[pro] Anaphoric macros (Was: The Best Examples of "Code is Data")

Daniel Gackle danielgackle at gmail.com
Tue Sep 28 04:57:34 UTC 2010


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 at gmail.com>wrote:

> > 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 at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/pro
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/pro/attachments/20100927/5b9e361d/attachment.html>


More information about the pro mailing list