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

Re: macros vs. blocks

   Date: Fri, 22 Nov 2002 13:51:29 -0800 (PST)
   From: Avi Bryant <avi@beta4.com>
   To: Guy Steele - Sun Microsystems Labs <Guy.Steele@sun.com>
   cc: tlb@anybots.com, <ll1-discuss@ai.mit.edu>
   Subject: Re: macros vs. blocks
   On Fri, 22 Nov 2002, Guy Steele - Sun Microsystems Labs wrote:
   >    Ok, but you're moving away from the advantage of having it be a macro:
   >    "there is no reason that a runtime system cannot allow you to write
   >    functions that refer to the source file and line from which the function
   >    was called".  ...
   > Sure there is: as a matter of efficiency, it might well
   > be undesirable or infeasible to keep all that information
   > around at run time on the off chance that someone might
   > need part of it.
   > Maybe you think that's a stupid or insufficient reason,
   > but it is a reason, which suffices to rebut the claim
   > that there is no reason.
   True.  But then the argument becomes "macros are more efficient (by virtue
   of being a compile time construct) than closures", which is a much less
   interesting argument, in my opinion, than "macros are more expressive (by
   virtue of being a metalevel construct) than closures".  Pursuing that
   argument also brings to mind all of the problems (in a mostly
   late-bound language like Lisp) that come of using compile time constructs
   for abstraction: I can change a function on the fly, but if I change a
   macro I have to recompile everything that uses it (are there any systems
   smart enough to do that automatically, btw?)
Um... would you believe that macros are so expressive ...


They're so expressive, they let me express the idea that I need
only a few relevant line numbers kept around at run time, rather
than all of them!
--Guy Steele

P.S.  How about: macros are so expressive, that Lisp doesn't
need primitive conditional AND and OR operators the way C has
&& and ||.  Instead they can be macros:

	(OR x y)  => ((lambda (p q) (if p p (q))) x (lambda () y))
	(AND x y) => ((lambda (p q) (if p (q) p)) x (lambda () y))

And good compilers will produce good target code from these definitions.

Similarly WHEN and UNLESS are macros.  Yeah, that may seem trivial
to someone who hasn't worked with them, but in good Lisp code I sense
subtle differences of intention between

	(AND x y)
	(IF x y)
	(WHEN x y)

While these examples all do the same thing, they invite extension
in different directions, because

	(AND x y z)
	(IF x y z)
	(WHEN x y z)

have rather different (and useful) behaviors.