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

Re: Issue: LET-TOP-LEVEL (version 1)



    Date: Thu, 3 Mar 88 10:44:43 PST
    From: Pavel.pa@Xerox.COM

    The real difference between DEFMACRO and MACROLET is that the expansion
    functions produced  by the former have indefinite extent, while those produced
    by the latter have only dynamic extent, if that.

That can't be quite right, since

(defun foo (x) (macrolet ((baz (x y)
			    (print `(baz ,x ,y expanded))
			    `(list ,x ,y)))
		 (lambda (z) (baz x z))))
(setq bar (foo 1))
(funcall bar 3) => (1 3)

and in an implementation that has an interpreter that doesn't preprocess
[not ours], the expander function for baz would not be called until
after foo had returned.  Thus the expander function must have indefinite
extent.

The real difference between DEFMACRO and MACROLET, I think, is that in
DEFMACRO there is a clear separation between the lexical environment of
definition and the lexical environment of use, but in MACROLET the
use environment is always nested inside the definition environment.
However, that's not too relevant.

In a compiler or an interpreter that preprocesses, the definition
environment has not even been created at the time the expander has to be
called.  This is quite clear for MACROLET.  For DEFMACRO, it depends
on what the granularity for preprocessing is, but with the usual model
of file compilation, I think DEFMACRO has the same issue.  Think about
this nonsensical program:

  (let ((x (big-computation-that-returns-22/7)))
    (defmacro foo (y) `(list ,x ,y))
    (defun bar (z) (foo (1+ z))))

(bar 2) => (22/7 3) if it evaluates to anything, but how could the
compiler know that?