Arc Forumnew | comments | leaders | submitlogin
1 point by fallintothis 5631 days ago | link | parent

Ah, I hadn't thought to mangle around with explicit lists; probably because I find it uglier than quasiquotation.

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)))))
Could be worse. And it's usable, e.g.:

   (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"
Thanks for the help!


3 points by fallintothis 5630 days ago | link

Not that anyone cares about beating this dead horse, but after coming back to the code, I instantly realized how to mitigate the ,,@(...) snafu:

  (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)))))
Seems obvious in retrospect. (Also, I've been spelling Peter Seibel's name wrong in this thread; oops.)

-----