Attila's experience matches mine: anaphoric macros are useful because they enhance readability. (I mean, of course, when they're used properly, but that's such a tiresome caveat to have to add and I'm hoping one benefit of this list is that we don't have to jump through *all* the usual hoops.) Given this experience I find it hard to fathom the critique of anaphoric macros that they are bad for readability.
Plausible reasons for disagreement are (a) we've had different experiences; (b) we have different tastes; or (c) we're talking about different things. Perhaps the best approach in every case is to make our terms explicit, so at risk of overspecifying I'm going to be as explicit as I can.
"Anaphoric macros" for me nearly always means AWHEN or AIF, very occasionally ACOND and that's about it. When I say these "improve readability" I mean that they make code shorter in an easily grokkable way. "Used properly" means "used in a small snippet": when their scope grows beyond the nearly trivial, their benefit -- concision -- tends to get diluted to the point of why bother. Worse, the meaning of IT gets exponentially harder to grok the further IT strays from ITs anaphoric introduction.
Here are two simple examples chosen nearly at random from the Skysheet code (Skysheet is the web-based spreadsheet startup I'm working at):
(awhen (search "Version/" str) (after-slash it))
(awhen (getf sh :col-deltas) (alist->hash it))
AWHEN makes these forms slightly more trivial than they would be without it. I like that: trivial is second only to non-existent as a good thing for code to be.
Here are two more. These are about as complex as I'd ever like an anaphoric macro to get:
(awhen (next-as-binary-op) (when (>= (precedence it) level) (consume) it))
(aif (implicit arg) (cond ((eq it :column) +abs-row+) ((eq it :row) +abs-col+) (t +abs-abs+)) (aim-rank (getf arg :aim)))
(That COND would be better as a CASE, but it has to run in both CL and JS via Parenscript, and CASE doesn't map to an expression in the latter.)
In all four examples I prefer AWHEN/AIF to an explicit binding because it makes the code shorter and more idiomatic. I guess you'll have to take my word for it that the concept temporarily denoted IT is in each case obvious from context and would not get any obviouser with an explicit name.
A couple of general reflections.
Readability is hard to talk about because it's so in the eye of the beholder. My own views on what's readable have changed a lot. They even vary per-program. In the end I find the definition is a cultural thing that has to get hammered out on a per-project basis by people who are working together (and needs a certain amount of re-hammering with each new person).
Finally, I hesitate to post the above because anaphoric macros are kind of a bike-shedding topic: not that interesting but easy to have an opinion about, so they get argued about more than they deserve. But I think it's a useful exercise occasionally to get right down to the threading on the screws. Too often in abstract discussions about programming I find myself wondering what people really mean; this experience gets worse as the subject matter gets more meta. Perhaps anaphoric macros are worth talking about *because* they are so simple. They're a chance to practice talking concretely about abstraction.
Dan Gackle
On Mon, Sep 27, 2010 at 3:56 AM, Attila Lendvai attila.lendvai@gmail.comwrote:
macros that are useful and should be allowed. It is just that anaphoric macros, despite all their cuteness, tax code readers unnecessarily hard and thus have not been adopted as acceptable practice in multi-programmer environments.
well, it's one opinion.
there's at least one counter example in our team of 4. and i personally do like reasonable usage of anaphoric macros, even when done by my colleagues. and the reason is exactly that it *rises* code readability for us.
our practice includes special coloring for "it" and avoids any usage which is not blatantly trivial.
-- attila
PS: argh, i so much didn't want to join such a subjective discussion... i need to meditate on this a bit more to successfully resist next time. the first exercise will be to let go my opinion of with-nesting... :)
pro mailing list pro@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/pro