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