[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Bug in emacs
From: |
era |
Subject: |
Re: Bug in emacs |
Date: |
16 Oct 2003 10:59:30 +0300 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 |
On 14 Oct 2003 09:05:20 +0300, era@iki.fi posted to gmane.emacs.bugs:
> On Mon, 13 Oct 2003 10:28:06 -0600, Kevin Rodgers <ihs_4664@yahoo.com>
> posted to gmane.emacs.bugs:
>> era@iki.fi wrote:
>>> I'm not sure what the bug really is. Perhaps it would be useful to
>>> get a warning when compiling / evaling something when a macro +is+
>>> in effect and the file you are compiling is not pulling it in
>>> properly? Then at least you get a hint to fix it while you still
>>> can, while those who do it right will not experience any adverse
>>> effects.
>> When the compiler comes across a (function arg ...) form, either the
>> function is defined or it isn't. If it's defined, either as a function
>> or a macro, all is well. If it's not defined, the compiler can't know
>> whether it is a function or a macro and assumes it's a function. A
>> macro can't be "in effect" if it's file was not loaded "properly".
> What I'm saying is that macro expansion during compilation could
> trigger a warning if the macro is not loaded properly by the code
> which is being compiled.
Oog, I got this backwards. (Thanks to RMS for pointing out my error in
private mail.) The problem is that when a macro is +not+ defined when
code is byte-compiled, the compiler assumes it's a function call; then
when the compiled code is executed, and the macro +is+ defined, you
get an error.
The following example is hopefully representative, although I'm not
sure under what circumstances the dreaded "wrong number of arguments"
error is triggered -- couldn't quickly reproduce that here.
;;; trinket.el --- test case for macro error
;;
;; Steps to repeat:
;;
;; 0. Start fresh copy of Emacs
;; 1. Save this file as /tmp/trinket.el and byte-compile into /tmp/trinket.elc
;; 2. Save /tmp/macro.el (inlined below) and byte-compile into /tmp/macro.elc
;; 3. M-: (load-file "/tmp/trinket.elc")
;; 4. M-: (trinket)
;; => ERROR: Symbol's function definition is void: f (as expected)
;; 5. Visit macro.el and eval the macro definition
;; 6. M-: (trinket)
;; => ERROR: Invalid function: (macro lambda (x n) (\` (let ((m (make-list
(\, n) (quote y)))) (while m (message (\, x)) (setq m (cdr m))))))
;; 7. Restart Emacs
;; 8. M-: (load-file "/tmp/macro.elc")
;; 9. M-: (load-file "/tmp/trinket.elc")
;; 10. M-: (trinket)
;; => ERROR: Invalid function: (macro . #[(x n) "ÂÃÄÅBBDCÆÃÇ
DÈBBBE" [n x let m make-list ((quote y)) while message ((setq m (cdr m)))] 6])
(defun trinket ()
(f "This is neat, isn't it?" 4) )
;; Inlined copy of macro.el --- extract into /tmp/macro.el and byte-compile
;?;?; macro.el --- supplementary file for trinket.el
;?;
;?;(defmacro f (x n)
;?; `(let ((m (make-list ,n 'y)))
;?; (while m (message ,x) (setq m (cdr m))) ))
;?;
;?;?; macro.el ends here
;;; trinket.el ends here
The main problem I guess is that the error message with the porridge
of byte-compiled opcodes isn't exactly helpful, and that sometimes you
have no idea which macro is causing it, and thus what defined it and
when.
So the upgraded wishlist suggestion would be to check whether a
compiled opcode which is about to be executed is shadowed by a macro,
and in that case display a warning identifying the macro in question.
(As per the message I got from RMS, all macros are expanded at
compilation time, so byte-compiled code should never refer to any
macros, if I got this right.)
Still, I think my earlier suggestion would be useful for preventing
this sort of error, i.e. when performing macro expansion at byte
compilation time, warn if the code in question did not manage to
define the macro properly, either by including it directly, or
requiring / loading / whatever a file which contains the definition.
/* era */
--
The email address era the contact information Just for kicks, imagine
at iki dot fi is heavily link on my home page at what it's like to get
spam filtered. If you <http://www.iki.fi/era/> 500 pieces of spam for
want to reach me, see instead. each wanted message.