(map eval
     (tree-subst 'loop 'loopform
       (keep [and (caris _ 'mac) (in (cadr _) 'loop 'for 'down)]
             (readfile "arc.arc"))))

(mac loop (withses . body)
  (let w (pair withses)
    `((rfn next ,(map car w) ,@body) ,@(map cadr w))))

I notice that I use afn often like this:

((afn (x y) ...) init-x init-y)

conanite made a macro named afnwith to encapsulate this pattern that I’m quite fond of:

(mac afnwith (withses . body)
  (let w (pair withses)
    `((afn ,(map car w) ,@body) ,@(map cadr w))))

I imagine I’ll use this often enough that I’d like to call it “loop”, and use “next” to repeat the loop with new values:

arc> (loop (x 0)
       (pr x " ")
       (if (< x 10)
            (next (+ x 1))))
0 1 2 3 4 5 6 7 8 9 10 nil

Arc of course already has a macro called “loop”. How to avoid conflicting with Arc’s loop? The Arc macros for and down use loop, so even if I never use Arc’s loop myself, I can’t redefine it without breaking for and down.

The map eval tree-subst code at the top reloads Arc’s definitions of loop, for, and down, renaming “loop” to “loopform”. I suppose a module system really would be more sensible, but rewriting Arc’s source code does feel pleasantly hackerish :-)

See also

xloop for a version which doesn’t conflict with Arc’s loop.

Get this hack

Using the hackinator:

$ hack \ \

Contact me

Twitter: awwx
Email: andrew.wilcox [at]