Code: Select all
(define-macro (do)
(letex ((iter-forms (args 0))
(break (args 1 0))
(result (args 1 1))
(body (cons begin (rest (rest (args))))))
(letex ((init-forms (map (fn (form) (0 2 form)) 'iter-forms))
(update-symbols (reverse (map first 'iter-forms)))
(update-values (reverse (map last 'iter-forms))))
(letn init-forms
(do-until break body
(map set 'update-symbols
(map eval 'update-values)))
result))))
Here is an example of factorial (from Ansi Common Lisp) using this do. It doesn't even have a body, because the update forms do all the work. I've included a comment where the body would be.
Code: Select all
(define (factorial n)
(do ((j n (- j 1))
(f 1 (* j f)))
((= j 0) f)
; (println j ", " f)
))
(println (factorial 10))