Arc Forumnew | comments | leaders | submitlogin
2 points by waterhouse 5103 days ago | link | parent

Macro: (xloop var-vals . body) : Extremely useful macro to create and use a local recursive function named 'next. var-vals is a list of alternating variables and initial values (in the style of the built-in Arc 'with macro), and body is the body of the function (which probably contains calls to 'next). To illustrate, we shall calculate the factorial of n:

  (xloop (i 1 total 1)
    (if (> i n)
        total
        (next (+ i 1) (* total i)))))
This macroexpands to:

  ((rfn next (i total)
     (if (> i n)
         total
         (next (+ i 1) (* total i))))
   1 1)
This is my go-to when I want to write a function that needs looping or general recursion. I use this macro all the time:

  $ grep -c xloop a general-poly.arc
  a:38
  general-poly.arc:18
Credit for xloop's current form goes to aw: http://awwx.ws/xloop0 That link also contains an implementation, which I will reproduce here for convenience (though, for consistency, I have renamed the first argument to var-vals, which I hope doesn't irritate aw):

  (mac xloop (var-vals . body)
    (let w (pair var-vals)
      `((rfn next ,(map car w) ,@body) ,@(map cadr w))))


4 points by rocketnia 5103 days ago | link

My 'xloop at http://github.com/rocketnia/lathe has a more convenient interface at the expense of overall simplicity. It supports the usual syntax, but it also lets you leave off the parentheses as long as the things you're binding to are non-nil, non-ssyntax symbols, like most variable names are.

  (xloop i 1 total 1
    (if (> i n)
      total
      (next (+ i 1) (* total i))))
The restriction on the bindings makes it possible to figure out where the body starts.

-----

1 point by aw 5102 days ago | link

which I hope doesn't irritate aw

Gosh no! Most everything I write is based on code I've seen elsewhere; with either what I hope will be an incremental improvement or else with some minor change to make it fit a personal preference. For me to complain because other people then share their own improvements would be rather foolish... :)

-----