The Power of Common Lisp Macros (was Re: Why is tcl broken?)

Pierre R. Mai pmai at
Tue Jun 29 20:07:31 EDT 1999

Marco Antoniotti <marcoxa at> writes:

> When "proc" is used within some code, its code is executed at
> runtime.  This is not what happens in Lisp, Scheme and Dylan, where
> macros are evaluated at read-time.  This is pure code transformation,

Only reader-macros are evaluated at read-time.  Normal macros are
evaluated at compile time.  (I know Marco knows this, just to make
sure those without CL knowledge aren't confused.).

> which when fed in the Common Lisp *compiler* produces inlined code.

What I find more interesting than the fact that you get inlined code,
is the possibility that compile-time evaluation affords you: In effect
macros (and compiler-macros) let you extend and use the normal CL
compiler to do most of the dirty work for you in many situations.
IMHO CL's macros are _the_ most important reason that makes CL so good 
at embedding domain-specific languages.

Take for example Harlequin's Common SQL, which embeds SQL in CL
(without any ugly pre-processors, or other evil stuff, such as C

(do-query ((name) [select [ename] :from [emp]])
  (print name))

This maps name over the tuples returned by the query and prints them.
The important wrinkle:  The query expression gets optimized and
compiled as part of the normal CL compilation process.  Here do-query
is implemented as a macro, the special SQL-syntax using [] is
implemented as reader-macros on [ (and ]).

Or take this silly macro definition (yes, this would need to pass
around a tcl environment object and probably do a number of other
things, but for simplicity):

(defun compile-tcl-to-lisp (exp)
  "Compiles a TCL expression in Lisp syntax into optimized Common Lisp 
code for run-time execution."

(defmacro in-tcl (&body expressions)
  (let ((compiled-code (mapcar #'compile-tcl-to-lisp expressions)))
    `(progn , at compiled-code)))

Given this (and a suitably lispified TCL syntax, i.e. one which used sexps
as basic units), I could now write embedded TCL in my CL programs, which
would get compiled to optimized native code along with my normal code.
And this works for any language for which you can dream up an apropriate
sexp syntax.  If done correctly, I can let the embedded language access
and modify the normal CL environment.

And all of this is done at the level of CL itself, that is all of this
can be written as portable ANSI Common Lisp code, without ever having
to open up the implementation, or resort to things like C...

Regs, Pierre.

PS:  Since I still think that this thread should never have been
started, especially as a cross-posted one, I've changed the subject
line and set a follow-up to comp.lang.lisp, where the possibilities of 
Common Lisp in this area can be suitably discussed.  Anyone who
disagrees with this judgement may of course ignore the F'up header...

Pierre Mai <pmai at>         PGP and GPG keys at your nearest Keyserver
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see]

More information about the Python-list mailing list