[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Using Macros in Lisp



>A popular misconception is that macros are used `for efficiency.' As
>has been pointed out both here and in comp.lang.lisp, macros are not
>functions and can not be used as functional arguments.  (E.g., you can't
>apply a macro or use it as a :test argument to a sequence function.)
>
>So, if you are worried about efficiency, don't write:
>
>  (defmacro frame-name (x)
>    `(car ,x))
>
>instead write this:
>
>  (proclaim (inline frame-name))
>  (defun frame-name (x)
>    (car x))
>
Well...the latter ALLOWS a smart compiler to "replace" frame-name with car,
but it is no guarantee that it will.  Thus, for a dumb compiler (i.e. lots
of them) there will be some additional run-time overhead.  However, the
former WILL replace all calls to frame-name with car at compile time, which
guarantees that the run-time code will just be car.  So with SOME compilers
the former WILL BE more efficient at run-time.
I've always found it useful to think of macros as glorified #define (is
that it?) in /c or as a glorified <blank>.

where <blank> is an assembly language thing on the Vax I forgot the name
of, but it works like defmacro.  :-)

Of course, in the above example, you SHOULDN'T be writing a macro.  The
overhead is very small and not worth quibbling about.  I only quibbled to
point out that in SOME cases one can significantly reduce run-time overhead
by using macros to compute some things at compile time that won't/can't be
handled by (proclaim (inline ...)).  The "To macro or not to macro" rules I
use are:

Don't write a macro UNLESS:
A:  You have to. (e.g. a class assignment)

B:  It will be used in LOTS of places in your code and will save you LOTS
of typing and make the code a LOT clearer.  (e.g. (with-open-file..))

C:  You NEED the arguments to be unevaluated so you can process them BEFORE
you do the function.
(e.g.  (defmacro frame (name) `(find-frame ',name)))

D:  You are going to save a LOT of run-time cycles by computing something.
(e.g.  (defmacro slot-value (type object slot-name)
           ;...hairy computation of integer result deleted...
          `(svref (node-vector ,object) ,result))
)

E:  You need to be able to setf some portion of a structure.
(e.g. (setf (slot-value person *fred* name) "Fred"))


>Unfortunately, I don't know of any text that describes writing anything
>other than trivial macros.  Probably, the best thing to do is to look at
Too true.  Which is why macros are often misunderstood or understood but
not used.  Many students end up never seeing (and certainly not writing) a
useful macro that deserves to exist--only silly little examples.  Any REAL
macro experts out there want to make a quick buck, a mini-text on macros
with honest-to-goodness exercises would definitely be the way to go.  Hell,
I'd buy it, and I like to think of myself as half-decent at writing macros.

Disclaimer:  I'm never too sure I know *anything* when it comes to macros.

"TANSTAAFL" Rich lynch@aristotle.ils.nwu.edu