[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#46834: 28.0.50; byte-compiling the standard counter closure fails
From: |
Stefan Monnier |
Subject: |
bug#46834: 28.0.50; byte-compiling the standard counter closure fails |
Date: |
Mon, 01 Mar 2021 09:34:21 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
>>> (byte-compile (let ((l 0)) (lambda () (cl-incf l))))
> Huh, that's such a standard example of using closures that it's
> surprising that we haven't tripped on this before... but I guess we
> don't really write code like that much in Emacs. (I can confirm that
> the test case doesn't work in Emacs 28.)
The problem is not in the way the actual byte compiler handles such code
(e.g. when you compile a whole file, which works just fine), it's just
for the special case where we pass to `byte-compile` a function *value*
rather than an *expression* (in which case, `byte-compile` first needs
to turn this value back into a corresponding expression).
This is a very special situation, whose main use case is when you
do `(byte-compile 'SYMBOL)` and which we don't handle 100%
correctly, anyway.
E.g. (using lexical-binding, of course):
M-: (let ((x 1))
(defun counter1 () (cl-incf x))
(defun counter2 () (cl-incf x))) RET
then do
M-x byte-compile RET counter1 RET
and then try
M-: (list (counter1) (counter2) (counter1) (counter2))
and notice that the counter is not shared between the two functions :-(
> I've added Stefan M to the CCs; perhaps he has some comments.
Thanks,
Stefan