>>>>> Alan Mackenzie writes: >>> (defmacro foo () >>> (let ((sym (make-symbol "bar"))) >>> `(progn >>> (defun ,sym () (message "function %s called" ',sym)) >>> (,sym)))) >>> >>> (foo) >>> However loading the corresponding compiled file signals an error: shell> emacs -Q -batch -eval '(byte-compile-file "x.el")' -load x.elc >>> Wrote /tmp/x.elc >>> Symbol's function definition is void: bar This example becomes clearer if we use `gensym' instead of `make-symbol "bar"`. Here is a macro expansion: Byte-compiled: (progn (defun bar68503 nil (message "function %s called" '#:bar68503)) (#:bar68503)) Interpreted: (progn (defun bar68503 nil (message "function %s called" 'bar68503)) (bar68503)) What's happening here is this: 1. At compile-time, we're creating a new, uninterned symbol, and we are both passing that symbol to defun, and calling it. 2. `defun', at compilation time, is using the _name_ of that symbol to define a function definition for an interned symbol of the same name. 3. We then try to print and call the uninterned symbol directly. So what we are calling, and what defun defined, are not the same symbol. This works when non-byte-compiled because we don't inline the symbol reference, making it a reference by name instead of by value. You can trigger the same error behavior at interpretation time with: (defmacro foo () (let ((sym (gensym))) `(progn (defun ,sym () (message "function %s called" ',sym)) (funcall (symbol-function (quote ,sym)))))) (foo) I don't think this is a bug, rather macro expansion doing exactly what it was told to do. If anything, it's odd that when interpreting, we expand to a reference by name; but I suppose that makes sense too, given the more dynamic nature of interpreted code. The general rule to follow is: Don't leak internal symbols. If you use `gensym' or `make-symbol', ensure that all dependencies on that symbol occur entirely within the macro body. `defun' is used to establish global definitions, so it effectively "exports" the internal symbol, breaking the abstraction. That it has inconsistent behavior here is due to differences in the way that byte-compilation inlines references. I recommend closure of this bug as expected behavior, unless there are further concerns. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2