I like anaphoric macros like aif
and aand
, but that a
- is rather opaque. If you didn't know what it stood for, would you ever guess "anaphoric", or have a clue what the macros did?
Abstruse naming conventions are nothing new — how long have Lispers been using -p
for predicates? — but that's no reason to inflict more of them. Is there a less exotic affix for anaphoric macros? Probably not, because it has to be short to be useful, and anything that short will be pretty opaque.
In any case, I'm not sure separate anaphoric macros are the right idea. It's nice to be able to bind a variable by adding a single character to a name, but it's not general. It won't work with a newly defined macro until someone defines an anaphoric variant, which realistically won't happen very often. Maybe that doesn't matter, since you can always fall back on let
.
I wonder if it wouldn't be better to be like Perl, and make everything anaphoric. If the normal versions of if
and progn
bound a variable (perhaps with a more distinctive name than it
?), then new macros based on them would too. This sounds nightmarishly unpredictable, since a newly defined macro might use several anaphoric constructs, and the innermost is not necessarily the one you want. It works for and
but not for (the naive definition of) case
, for instance.
Rampant anaphora might also pose a maintenance hazard, since simple transformations of code may change their referents. However, I haven't heard that this is a big problem in Perl. I suspect this is because people normally base their changes on a mental model of local dataflow, and in Perl, this model includes $_
. Unfortunately I don't have enough Perl experience to check this on myself.
I would like to dismiss anaphora on the grounds that they don't compose well: while one aif
can make an expression much simpler, a second will often conflict with the first. But this isn't a very distinctive fault. Many useful constructs are hard to compose — even function composition, ironically — and anaphoric macros are too handy to ignore.
I prefer the more explicit approach, rather than anaphora — Clojure has if-let, when-let macros.
ReplyDelete(if-let [foo (some-pred)]
(println "Yes" foo)
(println "No" foo))
I use little macros like Richard mentioned too, in CL. Names like that are more descriptive. There really is no reason for less descriptive names. (So i think anaphora should just make alternative names.)
ReplyDeleteA little off topic, I used to think that let, flet, macrolet, symbol-macrolet were the right thing to do and promoted clarity. I strongly have doubts now. Maybe we should be using single macros that make multiple types of variables. umac and scope are two approaches. (I like the first one better.)