I'm not a CL user but I sometimes think CL's loop macro is really convenient if I want to write something really small. (I don't think I want to write big stuff with it. It's too complicated to me.) So why don't I write something looks like it?
Here is that something. It doesn't cover whole loop macro but some.
#!r6rs (import (except (rnrs) for-each map) (only (srfi :1) iota for-each map)) (define-syntax %loop (syntax-rules (:for :in :do :repeat :collect) ((_ (vars ...) (body ...) op :for var :in l rest ...) (%loop ((var l) vars ...) (body ...) op rest ...)) ((_ (vars ...) (body ...) op :repeat n rest ...) (%loop ((tmp (iota n)) vars ...) (body ...) op rest ...)) ((_ (vars ...) (body ...) op :do expr rest ...) (%loop (vars ...) (expr body ...) for-each rest ...)) ((_ (vars ...) (body ...) op :collect expr rest ...) (%loop (vars ...) (expr body ...) map rest ...)) ;; last ;; do trivial case first ((_ () (body ...) op) ;; infinite loop (do () (#f) body ...)) ((_ ((var init) ...) (body ...) op) (op (lambda (var ...) body ...) init ...)))) (define-syntax loop (syntax-rules () ((_ clause ...) (%loop () () #f clause ...)))) #| (loop :for i :in '(1 2 3 10) :for j :in '(4 5 6) :do (begin (display i) (display j) (newline))) (loop :repeat 10 :do (begin (display 'ok) (newline))) (display (loop :for i :in '(1 2 3 10) :for j :in '(4 5 6) :collect (+ i j))) (newline) ;; (loop :do (begin (display 'ok) (newline))) |#I'm not sure if this is useful or not and I don't want to go deep inside of the crucial loop macro specification either, though :-)
NOTE: I've tested above code Racket (plt-r6rs), Mosh, Ypsilon and Sagittarius but Ypsilon raises an exception when the given list length are not the same.
No comments:
Post a Comment