[pro] The Best Examples of "Code is Data"

Daniel Gackle danielgackle at gmail.com
Tue Sep 28 05:17:40 UTC 2010


Vladimir touches on two important things.

A lot of the value in Lisp macros is how simple they make certain
things. People sometimes ask for an example of macros that "can't be
done without them" - but that's a contradiction. By definition,
anything that can be done by a macro can be done by its expansion.  It
can't, however, necessarily be done as easily. But this is a harder
debate to have because "easy" gets so subjective so quickly.

Second, SETF is really apropos. One of the places I often find macros
making things easier is in eliminating boilerplate code that involves
assigning values to things. You can't do this with functions; or if
you can, the cure is usually worse (more verbose) than the disease
(the original repetition). It's usually very simple to write a macro
to generates the block of code that does the assignments and whatever
else goes with them. Yet I never seem to hear this brought up in
discussions about macros - maybe because it's so obvious it doesn't
seem to matter.

Dan Gackle

On Mon, Sep 27, 2010 at 3:04 PM, Vladimir Sedach <vsedach at gmail.com> wrote:

> Kazimir Majorinc:
>
> > formulas. So far so good. However, some essential operations on formulas
> > (substitution, unification, rules or inference ...) require analysis of
> > the formula.
> >
> > Similar analysis of the function could be done only by transforming it
> > back into formula with (caddr (function-lambda-expression Si)), and it
> > is not simpler, even if it work, what is not guaranteed according to
> > Hyperspec.
>
> This example is confusion about phase separation
> (
> http://axisofeval.blogspot.com/2010/07/whats-phase-separation-and-when-do-you.html
> ),
> but more relevantly it presents a false dichotomy for the solution
> space and perfectly demonstrates the power of macros.
>
> There is no need to choose between EVAL and lambdas - make the formula
> operators be macros and the formulas will know how to analyze
> (macro-expansion time) *and* evaluate (result of macro-expansion)
> themselves - the formula interpreter falls out "for free" from doing a
> COMPILE on a lambda that binds the formula free variables. As a bonus,
> now the code is factored such that all the analysis code is grouped
> with the definition of the relevant operators, instead of being
> scattered around inside an interpreter.
>
> A similar example came up in an ll1 mailing list discussion on macros
> vs closures (
> http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg02060.html
> - recommended reading as there is also discussion of good macros), but
> using SQL query languages as the domain. CLSQL, for example, does it
> with macros, which enable all kinds of compile[macro-expansion]-time
> analysis and optimization. Smalltalkers do the same thing with
> closures and using #doesNotUnderstand: (which is sort of like
> re-binding APPLY):
>
> http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg02096.html
>
> I wrote about how this technique might be used in Common Lisp:
>
>
> http://carcaddar.blogspot.com/2009/04/closure-oriented-metaprogramming-via.html
>
> I think the macro approach to queries is more succinct and powerful
> (you are no longer limited to function calling syntax for your query
> DSL). The query DSL is something that a lot of people seem to like -
> LINQ in .NET attempts to do the same thing, but a much higher price
> (an new syntax for expressing queries, a new protocol for query
> consumers (database interfaces), and a horribly complicated
> implementation).
>
> The other really powerful example pointed out in the ll1 discussion
> was SETF. I think SETF is one of the best examples of macros around.
> It takes the idea of accessors, and turns them into a generic idea of
> "places" that can be modified in the same way they are read.
>
> This extends the language with an entirely new domain concept that
> works transparently everywhere, with absolutely no changes needed to
> any of its other parts. There are ways to fake "places" with closures
> (ex: Oleg Kiselyov's "pointers as closures" trick, or the way dynamic
> variables work in SRFI 39), but they work by completely changing the
> accessor protocol, introducing a second protocol for updating places
> (funcall the closure with new value), and because the "directions" to
> the place are not reified they are not composable (ie - you can't do
> (setf (gethash foo (aref bar)) baz) with closures), and cannot be
> implemented efficiently.
>
> Now think about what it would take to do this in Java - you'd need a
> whole new DSL implemented on top of the Interpreter pattern, a Factory
> to help you produce the grammar of that DSL, all with a Strategy
> component so you can define new places. I bet it would be really
> pleasant to use as well.
>
> Vladimir
>
> _______________________________________________
> 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/c76a7040/attachment.html>


More information about the pro mailing list