Hans,

Wow!  That is beautifully explained!  I would go so far
as to say that even Peter Siebel's work could be enhanced
by this explanation.  This is the best description, with
reasoning, of when to use macros and when not,
that I have ever heard (read).

-- Dan

Hans Hübner wrote:
On Wed, Sep 8, 2010 at 09:59, Julian Squires <julian@cipht.net> wrote:
  
I don't understand why anaphoric macros are so frowned upon.  Like any
powerful tool, it's easy to construct pathological situations where
they make code more difficult to understand.  However, I feel that
when tastefully used, they enhance the expressiveness of the language,
readibility of code, and they can help to reduce the verbosity of CL
of which many outsiders complain.  Of course, the prior two sentences
apply just as well to macros in general as they do to anaphora.
    

The power of macros gives Lisp programmers the freedom to create the
language that they need, but every single modification of the language
makes it derive from what another programmer would expect.  Thus, in a
setting where the written code serves not only as instructions to a
computer, but also as prose communicating intent to another
programmer, it is vital to establish borders to the amount of language
modification permitted.

There are certain idiomatic macro styles that are commonly understood
amongs Lisp programmers, but the number of these styles is low.  One
of them is the WITH-family used for implicit (and guaranteed) resource
release, another is the DO-family for iteration.  These idiomatic
styles are easy to recognize and well-established, so they are rather
common.

Another family of macros that is everywhere, idiomatic and
well-established is top-level definers.  That family certainly is much
broader, and often a simple top-level definition form expands into
loads of code.  They are often part of a larger framework, and as
top-level forms they are easy to recognize.

Anaphoric macros usually are much harder to recognize visually, and
they do "unexpected" things to source code on a micro-level.  This is
what I object to.  Within the body of the anaphoric construct, a
simple variable "it" suddenly becomes dependent on the local context.
I find code with anaphoric macros harder to read than code that uses
explicit variable names, because, in a linear reading flow, I am not
told what a certain symbol is bound to.  Rather, I need to imagine the
"it" myself when reading "awhen". [*]

What I do support is the use of combined test-and-bind macros
(WHEN-BIND, WHEN-LET or similar).  They serve the same purpose as
anaphoric macros (reduce repetetive words in local contexts), but they
are much more scalable and require giving things names.

Anaphoric macros are a good example of things that one can do with
Common Lisp and that one can also like about Common Lisp, but that are
not useful in industrial software development practice.  When working
together, making things as easy to read as possible is not only a
question of style, but also of politeness and responsibility.  I am
certainly not claiming that the macro types listed above are the only
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.

-Hans

[*] I never really dug Forth for anything but  small programs because,
like anaphoric macros in CL, Forth requires me to keep more state in
my head when reading code.

_______________________________________________
pro mailing list
pro@common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/pro