| I somehow got interested in anaphora today. I've scribbled some Arc-equivalents to the On Lisp anaphora macros before, but don't think I've ever seen 'em floating around here. So, here are some snippets, for pedagogy's sake. (mac anaph (op . args)
((afn (args call)
(if args
(w/uniq u
`(withs (,u ,(car args) it ,u)
,(self (cdr args)
(join call (list u)))))
call))
args (list op)))
(mac anaph1 (op . args)
`(let it ,(car args) (,op it ,@(cdr args))))
(mac afold (op id . args)
(if (no args)
id
`(let it ,(car args) (,op it (afold ,op ,id ,@(cdr args))))))
pg notes at the bottom of arc.arc: ; idea: anaph macro so instead of (aand x y) say (anaph and x y)
Hence the name and structure of these macros. As noted in On Lisp, there are a bunch of different anaphora cases. E.g., (aand a b c)
==
(let it a
(and it
(let it b
(and it c))))
whereas (awhen a b c)
==
(let it a
(when it b c))
These correspond respectively to the :all and :first keywords of defanaph in On Lisp (page 223). Lacking keywords in Arc, I just use anaph for the :all case and anaph1 for :first (1 actually serves a semantic purpose in the name, unlike anaphex1, anaphex2, and anaphex3 in On Lisp).For example, arc> (anaph list 1 (+ it 2) (* it 3))
(1 3 9)
arc> (anaph1 if 'foo (string it "bar") 'baz)
"foobar"
However, notice that anaph will expand into a form that evaluates all of the
arguments. arc> (ppr:macex1 '(anaph list 1 (+ it 2) (+ it 3)))
(withs (gs2041 1 it gs2041)
(withs (gs2042 (+ it 2) it gs2042)
(withs (gs2043 (+ it 3) it gs2043)
(list gs2041 gs2042 gs2043))))t
So, this will break for aand. arc> (anaph and nil (prn "this shouldn't print"))
this shouldn't print
nil
Hence, afold is modeled more closely to aand's definition in arc.arc, but generalizes it into a right fold (http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29). This makes (afold and t ...) slightly different from aand, since we need to supply the identity element, lest afold make assumptions about op having a zero- or one-argument case. arc> (afold and t nil (prn "this shouldn't print"))
nil
arc> (aand nil (prn "this shouldn't print"))
nil
arc> (afold and t 'a 'b)
t
arc> (aand 'a 'b)
b
But, you could certainly define all sorts of other afold variants based on how to handle zero/one-argument cases alone.I didn't bother with the :place keyword from On Lisp because I didn't find it very interesting. |