;; encapsulates idiom: (w/uniq o `(let ,o ,obj ...)) (mac once-only (names exp) (withs (names (if atom.names (list names) names) names-temps (map [list (uniq) _] names)) `(with ,(apply join names-temps) (w/uniq ,names (list 'with (list ,@(mappend (fn ((name tmp)) (list tmp name)) names-temps)) ,exp)))))
Siebel's version then becomes:
(mac once-only (names . body) (let gensyms (map1 [uniq] names) `(w/uniq ,gensyms (list 'with (list ,@(mappend list gensyms names)) (with ,(mappend list names gensyms) ,@body)))))
(mac for (v init max . body) (once-only (init max) `(with (,v nil ,max (+ ,max 1)) (loop (assign ,v ,init) (< ,v ,max) (assign ,v (+ ,v 1)) ,@body)))) *** redefining for #3(tagged mac #<procedure: for>) arc> (for x 1 5 (prn x)) 1 2 3 4 5 nil arc> (for init 1 5 (prn init)) 1 2 3 4 5 nil arc> (let max 2 (for init 1 5 (when (> init max) (prn init)))) 3 4 5 nil arc> (for x 1 5 (prn init)) Error: "reference to undefined identifier: _init"
-----
(mac once-only (names . body) (let gensyms (map1 [uniq] names) `(w/uniq ,gensyms `(with ,(list ,@(mappend list gensyms names)) ,(with ,(mappend list names gensyms) ,@body)))))