<div>Vladimir touches on two important things.</div><div><br></div><div>A lot of the value in Lisp macros is how simple they make certain</div><div>things. People sometimes ask for an example of macros that "can't be</div>
<div>done without them" - but that's a contradiction. By definition,</div><div>anything that can be done by a macro can be done by its expansion. It</div><div>can't, however, necessarily be done as easily. But this is a harder</div>
<div>debate to have because "easy" gets so subjective so quickly.</div><div><br></div><div>Second, SETF is really apropos. One of the places I often find macros</div><div>making things easier is in eliminating boilerplate code that involves</div>
<div>assigning values to things. You can't do this with functions; or if</div><div>you can, the cure is usually worse (more verbose) than the disease</div><div>(the original repetition). It's usually very simple to write a macro</div>
<div>to generates the block of code that does the assignments and whatever</div><div>else goes with them. Yet I never seem to hear this brought up in</div><div>discussions about macros - maybe because it's so obvious it doesn't</div>
<div>seem to matter.</div><div><br></div><div>Dan Gackle</div><br><div class="gmail_quote">On Mon, Sep 27, 2010 at 3:04 PM, Vladimir Sedach <span dir="ltr"><<a href="mailto:vsedach@gmail.com">vsedach@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Kazimir Majorinc:<br>
<div class="im"><br>
> formulas. So far so good. However, some essential operations on formulas<br>
> (substitution, unification, rules or inference ...) require analysis of<br>
> the formula.<br>
><br>
> Similar analysis of the function could be done only by transforming it<br>
> back into formula with (caddr (function-lambda-expression Si)), and it<br>
> is not simpler, even if it work, what is not guaranteed according to<br>
> Hyperspec.<br>
<br>
</div>This example is confusion about phase separation<br>
(<a href="http://axisofeval.blogspot.com/2010/07/whats-phase-separation-and-when-do-you.html" target="_blank">http://axisofeval.blogspot.com/2010/07/whats-phase-separation-and-when-do-you.html</a>),<br>
but more relevantly it presents a false dichotomy for the solution<br>
space and perfectly demonstrates the power of macros.<br>
<br>
There is no need to choose between EVAL and lambdas - make the formula<br>
operators be macros and the formulas will know how to analyze<br>
(macro-expansion time) *and* evaluate (result of macro-expansion)<br>
themselves - the formula interpreter falls out "for free" from doing a<br>
COMPILE on a lambda that binds the formula free variables. As a bonus,<br>
now the code is factored such that all the analysis code is grouped<br>
with the definition of the relevant operators, instead of being<br>
scattered around inside an interpreter.<br>
<br>
A similar example came up in an ll1 mailing list discussion on macros<br>
vs closures (<a href="http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg02060.html" target="_blank">http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg02060.html</a><br>
- recommended reading as there is also discussion of good macros), but<br>
using SQL query languages as the domain. CLSQL, for example, does it<br>
with macros, which enable all kinds of compile[macro-expansion]-time<br>
analysis and optimization. Smalltalkers do the same thing with<br>
closures and using #doesNotUnderstand: (which is sort of like<br>
re-binding APPLY):<br>
<br>
<a href="http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg02096.html" target="_blank">http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg02096.html</a><br>
<br>
I wrote about how this technique might be used in Common Lisp:<br>
<br>
<a href="http://carcaddar.blogspot.com/2009/04/closure-oriented-metaprogramming-via.html" target="_blank">http://carcaddar.blogspot.com/2009/04/closure-oriented-metaprogramming-via.html</a><br>
<br>
I think the macro approach to queries is more succinct and powerful<br>
(you are no longer limited to function calling syntax for your query<br>
DSL). The query DSL is something that a lot of people seem to like -<br>
LINQ in .NET attempts to do the same thing, but a much higher price<br>
(an new syntax for expressing queries, a new protocol for query<br>
consumers (database interfaces), and a horribly complicated<br>
implementation).<br>
<br>
The other really powerful example pointed out in the ll1 discussion<br>
was SETF. I think SETF is one of the best examples of macros around.<br>
It takes the idea of accessors, and turns them into a generic idea of<br>
"places" that can be modified in the same way they are read.<br>
<br>
This extends the language with an entirely new domain concept that<br>
works transparently everywhere, with absolutely no changes needed to<br>
any of its other parts. There are ways to fake "places" with closures<br>
(ex: Oleg Kiselyov's "pointers as closures" trick, or the way dynamic<br>
variables work in SRFI 39), but they work by completely changing the<br>
accessor protocol, introducing a second protocol for updating places<br>
(funcall the closure with new value), and because the "directions" to<br>
the place are not reified they are not composable (ie - you can't do<br>
(setf (gethash foo (aref bar)) baz) with closures), and cannot be<br>
implemented efficiently.<br>
<br>
Now think about what it would take to do this in Java - you'd need a<br>
whole new DSL implemented on top of the Interpreter pattern, a Factory<br>
to help you produce the grammar of that DSL, all with a Strategy<br>
component so you can define new places. I bet it would be really<br>
pleasant to use as well.<br>
<font color="#888888"><br>
Vladimir<br>
</font><div><div></div><div class="h5"><br>
_______________________________________________<br>
pro mailing list<br>
<a href="mailto:pro@common-lisp.net">pro@common-lisp.net</a><br>
<a href="http://common-lisp.net/cgi-bin/mailman/listinfo/pro" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/pro</a><br>
</div></div></blockquote></div><br>