GNU bug report logs -
#4845
23.1.50; Uninterned symbols in .elc files
Previous Next
Full log
View this message in rfc822 format
[Message part 1 (text/plain, inline)]
>>>>> Alan Mackenzie <acm <at> muc.de> 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
[signature.asc (application/pgp-signature, inline)]
This bug report was last modified 4 years and 186 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.