
Lisp Macro - pmoriarty
http://c2.com/cgi/wiki?LispMacro
======
Animats
Where that leads: the MIT Loop Macro.

[http://www.cs.cmu.edu/afs/cs/project/ai-
repository/ai/lang/l...](http://www.cs.cmu.edu/afs/cs/project/ai-
repository/ai/lang/lisp/code/iter/loop/mit/mit_loop.cl)

This essentially adds a FOR statement to LISP, using 1495 lines of LISP
macros. Here's its manual:
[http://www.ai.sri.com/pkarp/loop.html](http://www.ai.sri.com/pkarp/loop.html)

Because this is a macro, if you have to debug or step, you get to do so
through the expanded code. This is usually not fun. But at least it's a
memory-safe language, so it's not the hell of fixing C++ template bugs.

~~~
lispm
It does not _lead_ to the LOOP macro. The LOOP macro is a special approach for
an embedded language for iteration. It's coming from on an older idea from
Interlisp: Conversational LISP.

[http://www.softwarepreservation.org/projects/LISP/interlisp/...](http://www.softwarepreservation.org/projects/LISP/interlisp/Teitelman-3IJCAI.pdf)

> This essentially adds a FOR statement to LISP

LOOP provides quite a bit more than a `FOR` statement: various forms of
iteration and stepping, value accumulation, termination, flow control, ...

It's basically a special style of embedded DSL for it iteration. If one wants
to implement such a thing, there is only a way through macros in Lisp. There
are lots of iteration macros for Lisp - most have a slightly simplified
grammar, though not necessarily less features (see the ITERATE macro, which
has more features than LOOP plus more parentheses).

In other language this would have to be implemented in the language's internal
implementation.

> Because this is a macro, ...

Similar to DO, DO*, DOTIMES, DOLIST, ... which are all macros in Common Lisp.

> if you have to debug or step, you get to do so through the expanded code.

like so much in Common Lisp and like so much in Lisp in general. Source
translations are quite typical for this language family. It makes debugging
quite a bit more difficult.

For an alternative to this look at SERIES, which is also implemented with
macros, but looks and works completely different.

[http://lispm.de/docs/cltl2/clm/node347.html#SECTION003400000...](http://lispm.de/docs/cltl2/clm/node347.html#SECTION003400000000000000000)

Generally stepping is difficult in Lisp. If you would want to step through a
call to a MAP function, you will step through its implementation and repeated
calls to a closure argument, which might not be pretty.

~~~
nemoniac
SERIES is indeed quite a different approach.

A more Lisp-idiomatic approach to iteration, though not so far from LOOP, is
ITERATE.

[http://www.common-
lisp.net/project/iterate/doc/Don_0027t-Loo...](http://www.common-
lisp.net/project/iterate/doc/Don_0027t-Loop-Iterate.html)

~~~
lispm
The main thing which makes ITERATE more idiomatic in Lisp from a syntactic
point of view is this: ITERATE groups clauses as sublists.

Other than that the ITERATE approach is very similar to LOOP.

    
    
        (iterate (for el in num-list)
                 (when (> el 3)
                   (collect el)))
    

vs.

    
    
        (loop for el in num-list
              when (> el 3)
                collect el)
    
    

As you can see from the above example, ITERATE has more parentheses... which
from a Lisp point of view makes sense. But for this typical iteration example
it looks almost the same, otherwise.

ITERATE has also quite some more capabilities than LOOP, for example it
supports accumulation of results from nested loops.

------
mrottenkolber
The C2 wiki presents (as usually) a very uneducated view about Lisp. I am not
going to rip apart the details but whenever you read something about Lisp on
the C2 wiki please keep in mind that Lisp is not their usual cup of coffee
really.

So if you see something like "Lisp macros could be easily replaced with a
magic Ruby block lotion and are just lambdas + syntax", just because nobody on
C2 argues with it doesn't mean its not completely ignorant and wrong.

~~~
_yosefk
While you can't replace all macros with blocks, I think there's an interesting
argument in there about doing _some_ things done with macros using blocks, and
that it has the advantage that a function accepting a block can be passed
around in ways a macro can't be.

~~~
mrottenkolber
If we talk about blocks, do we mean something different than a LAMBDA, e.g. a
closure?

~~~
ScottBurson
No. Smalltalk called these blocks, and Ruby does too.

BTW a lambda expression and a closure are not the same thing. A lambda
expression _evaluates to_ a closure, just as an expression like "(make-
instance 'foo)" (or "new Foo()" for non-Lispers) _evaluates to_ an instance.
The former, in each case, is a syntactic entity, something you can write in
your program; the latter is an object inside the machine.

