Arc Forumnew | comments | leaders | submitlogin
2 points by Jesin 5928 days ago | link | parent

Basically, as long as it has a termination condition that is always reached, it works. For example (this may not match arc.arc as I'm making this up on the spot):

  (mac aif (test . body)
    (if body
        `(let it ,test
           (if it
               ,(car body)
               (aif ,@(cdr body))))
        test))
Now, let's expand this (I won't bother expanding let, just aif):

  (aif a b c d e)

  ; expand aif

  (let it a
    (if it
        b
        (aif c d e)))

  ; expand aif

  (let it a
    (if it
        b
        (let it c
          (if it
              d
              (aif e)))))

  ; expand aif

  (let it a
    (if it
        b
        (let it c
          (if it
              d
              e))))
If you feed in an even number of terms, this happens:

  (aif a b)

  ; expand aif

  (let it a
    (if it
        b
        (aif nil)))

  ; expand aif

  (let it a
    (if it
        b
        nil))
That works because (car nil) is nil. Convenient!

Also, I'm something of a perfectionist, and sometimes when I get bored I've been cleaning up some of the macros in arc.arc. I've been able to work out cleaner implementations that produce cleaner expansions for some of them. For example, I don't know why while is implemented as:

  (mac while (test . body)
    (w/uniq (gf gp)
      `((rfn ,gf (,gp)
          (when ,gp ,@body (,gf ,test)))
        ,test)))
when this should also work:

  (mac while (test . body)
    (w/uniq g
      `((rfn ,g ()
          (when ,test ,@body (,g))))))