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

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

Dave says:
``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

This is just the issue that I addressed in my first message on this topic.  When
you define a macro with a non-null closed-over environment, it is clear that the
compiler cannot know how to evaluate the expansion function.  It is therefore
reasonable to assume that the compiler cannot expand uses of that macro during
the same compilation that encounters the DEFMACRO form.  If you want a macro
like this, you must put the DEFMACRO in a separate file, compile and load that
file, and then compile any uses of the macro.  This may be very reasonable for
some applications.  In particular, it can be used in the same Scheme-style way
that uses a lexical variable to carry module-global state.  For example, it
might be reasonable for DEFSTRUCT to be defined in this way, with the DEFMACRO
for DEFSTRUCT and the DEFUN's for the other structure-handling subprimitives all
within the same non-global lexical environment:

(let ((destruct-database ...))
   (defmacro defstruct ...)
   (defun tell-me-about-this-structure-type ...)
   ...other code that doesn't use DEFSTRUCT...)

This style doesn't disgust me and I see no reason not to support it.