emacs-devel
[Top][All Lists]
Advanced

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

RE: [Emacs-diffs] trunk r117002: Correctly treat progn contents as tople


From: Drew Adams
Subject: RE: [Emacs-diffs] trunk r117002: Correctly treat progn contents as toplevel forms when byte compiling
Date: Tue, 22 Apr 2014 13:41:44 -0700 (PDT)

> >> The SBCL and ECL behavior is what I'd expect from reading the spec, but
> >> maybe I misunderstood something.
> >
> > Hm.  What part of the spec do you think gives the impression that
> > `defmacro' behavior is defined only at top level?
> 
> defmacro is specced to "define[] name as a macro by associating a macro
> function with that name in the global environment". 

> Like any form, it's supposed to do that when it's evaluated,

Yes, anywhere and anywhen it's evaluated, including from a file at any
level.  And including when invoked from running code.  And including
`defmacro' forms that are generated and eval'd on the fly.

> and forms inside defuns aren't evaluated when they're loaded or
> compiled: they're evaluated when the defun is called. So you should
> expect a defmacro inside a defun to have no effect unti lthe defun is
> called.

Agreed, but when the defun is called and the `defmacro' is evaluated,
its behavior should be well-defined - it is not just up for grabs or
up to the implementation.

But I do see now that you allowed for `progn' contexts, at least.
I guess you meant any context, like progn, which evaluates the
`defmacro' at load or compile time.

> Likewise, if a defmacro appears at top level, it should ordinarily be
> evaluated only when the file that contains it is loaded, just like any
> other toplevel form. So, without special provisions, defmacro should not
> be expanded inside forms that happen to be in the same file.
> 
> But this behavior isn't very useful, so as a special case, CL specifies
> that "if a defmacro form appears as a top level form, the compiler must
> store the macro definition at compile time, so that occurrences of the
> macro later on in the file can be expanded correctly. Users must ensure
> that the body of the macro can be evaluated at compile time if it is
> referenced within the file being compiled."

That was precisely the passage I was thinking of, BTW.

It does not say anything about `defmacro' inside a defun signaling a
compile-time error, as opposed to doing what you write above: "have no
effect until the defun is called".  A priori, when the defun is called
the `defmacro' inside it should be evaluated, defining the macro
normally, no?

It says clearly that IF you expect the macro to be available to code
in the same file at compile time for that file, THEN you must ensure
that it gets evaluated at compile time.  If not, then not.

> It's because of this special case that a normal defmacro, not wrapped in
> an eval-when, has any effect on compilation of forms in the same file. A
> defmacro inside a defun isn't covered by this special case, so its
> behavior should revert to the normal behavior for forms.

Which is what?  Why isn't it that the embedded `defmacro' would, as you
said "have no effect until the defun is called"?

> SBCL and ECL implement this model of evaluation. CLISP's behavior
> appears to be incorrect here.

I don't see that either of those behaviors realizes the exclusive truth
here.  All I see that passage saying is that you must not expect a
`defvar' embedded in a defun to have an effect, at compile time, on
subsequent code located in the same file.  I don't see that as a call
to raise a compile-time error.

> The behavior I'm proposing for Emacs is identical to what SBCL and ECL
> do. Stefan is proposing that we adopt CLISP behavior.

I see.  Anyway, I misunderstood your original comment about `defmacro'
behavior being undefined if not at top level - sorry.

(And I have no special opinion about the question you are deciding.
A priori, I prefer that Emacs Lisp be closer to CL, but I have no
opinion about this particular issue.)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]