On 04/22/2014 11:37 AM, Stefan Monnier wrote: >> Nobody is going to write a defmacro at toplevel inside a cl-letf. > I'm OK with adding a bit of complexity if it removes special cases > (which my proposal might do, tho I have no experience with it, so maybe > it'll need horrendous hacks to implement and additionally it will > introduce new special cases), I think it will need horrendous hacks (but maybe I'm wrong). We'd have to expand macros step-by-step and check recursively for macro-defining macros, and probably introduce some kind of special alternative defmacro in the environment, since the normal `defmacro' is itself a macro and would be hidden by macroexpand. (Imagine a macro that just expands to a single defmacro --- we'd still want to add that macro to our temporary environment.) To address this problem, we could merge macroexpand-1 instead, but that's an even bigger change. You also have to worry about nested macroexpand-all calls, leakage between defuns, and so on. There are interesting corner cases too: what about (progn (and nil (defmacro foo () ...)) (foo))? The current code works, solves a real problem, matches many other lisp implementations, and has automated tests. It doesn't affect (and slow) every macro expansion everywhere. > but the CL semantics adds complexity > without really removing special cases: it just moves the "special case > boundary" elsewhere. And I don't like it for that reason. > It's a question of taste, to a large extent, hence the bikeshedding. Your proposal is equivalent to sucking all the forms "following" (in some sense) a defmacro into an implicit macrolet that defines the same macro that the defmacro does. Fine. But how do you decide how much code is included in this implicit macrolet? All the remaining forms in the current call to macroexpand-all? That's too broad: a macro defined in one defun shouldn't affect forms in a completely different defun. The forms following the defmacro in the same progn? That's too narrow --- there's still a "special case boundary". I think that no matter where we choose to put the implicit macrolet, it'll surprise someone. I'd rather not try. Instead, we should address the case that's come up in practice (and that came up 20 years ago in Common Lisp). > I prefer you adding `eval-and-compile' at a few places to work around > the "buggy Elisp semantics" over imposing the CL semantics. I'm not going to do that.