GNU bug report logs - #14772
24.3; defvar and lexical-binding in interpreted elisp code

Previous Next

Package: emacs;

Reported by: Jisang Yoo <jisang.yoo.ac+org <at> gmail.com>

Date: Tue, 2 Jul 2013 21:09:02 UTC

Severity: normal

Tags: wontfix

Found in version 24.3

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 14772 in the body.
You can then email your comments to 14772 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#14772; Package emacs. (Tue, 02 Jul 2013 21:09:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Jisang Yoo <jisang.yoo.ac+org <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 02 Jul 2013 21:09:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jisang Yoo <jisang.yoo.ac+org <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 24.3; defvar and lexical-binding in interpreted elisp code
Date: Wed, 3 Jul 2013 05:52:02 +0900
Short description:

Declaring a special variable affects lexical local variables of the
same name (in interpreted code) in a half measure way, thereby
deviating from both the newbies expectation and the common lisp
expectation.



Long description:

contents of alice.el:

;; -*- lexical-binding: t; -*-
;; two functions that are supposed to do the same thing
(defun alice-multiplier-1 (foo)
  (lambda (n) (* n foo)))
(defun alice-multiplier-2 (num)
  (let ((foo num))
    (lambda (n) (* n foo))))
;; breaking bad
(defvar foo 1000)
;; time to see its effects
(print
 (list
  :R3 (mapcar (alice-multiplier-1 10) (list 1 2 3))
  :R4 (mapcar (alice-multiplier-2 10) (list 1 2 3))))

Output from emacs -q --load alice.el:

(:R3 (10 20 30) :R4 (1000 2000 3000))

What I expected:

Either (:R3 (10 20 30) :R4 (10 20 30))  or (:R3 (1000 2000 3000) :R4
(1000 2000 3000))

One answer in
http://stackoverflow.com/questions/17400556/strange-interaction-between-lexical-binding-and-defvar-in-emacs-lisp
suggests that (:R3 (1000 2000 3000) :R4 (1000 2000 3000)) should be
the right output, which is the same as the CLIST output according to
my test.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#14772; Package emacs. (Wed, 03 Jul 2013 09:31:02 GMT) Full text and rfc822 format available.

Message #8 received at 14772 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
To: Jisang Yoo <jisang.yoo.ac+org <at> gmail.com>
Cc: 14772 <at> debbugs.gnu.org
Subject: Re: bug#14772: 24.3;
 defvar and lexical-binding in interpreted elisp code
Date: Wed, 03 Jul 2013 05:30:02 -0400
tags 14772 wontfix
thanks

> ;; two functions that are supposed to do the same thing
> (defun alice-multiplier-1 (foo)
>   (lambda (n) (* n foo)))
> (defun alice-multiplier-2 (num)
>   (let ((foo num))
>     (lambda (n) (* n foo))))

They're not supposed to be equivalent, because function arguments in
lexical-binding mode are documented as always being lexical, regardless
of any defvar.

> Output from emacs -q --load alice.el:

> (:R3 (10 20 30) :R4 (1000 2000 3000))


That's arguably a bug in the interpreter, indeed.   The byte-compiler
returns (:R3 (10 20 30) :R4 (10 20 30)) AFAIK.  The byte-compiler should
also point out the fact that there's a problem in the code: we let-bind
`foo' first and later on declare foo with defvar.

> suggests that (:R3 (1000 2000 3000) :R4 (1000 2000 3000)) should be
> the right output, which is the same as the CLIST output according to
> my test.

All three answers can be considered correct depending on what semantics
we want to give to the language (I happen to prefer the semantics we
currently get from the compiler).  The fact that we get different
results with the interpreter and with the compiler is a bug, but making
the interpreter follow the compiler's behavior would be difficult/costly
and making the compiler follow the interpreter's behavior is also
difficult/costly.

So I prefer to say that such code is "unsupported": you should always
place the defvar before let-binding the corresponding variable.


        Stefan




Added tag(s) wontfix. Request was from Stefan Monnier <monnier <at> IRO.UMontreal.CA> to control <at> debbugs.gnu.org. (Wed, 03 Jul 2013 09:31:02 GMT) Full text and rfc822 format available.

bug closed, send any further explanations to 14772 <at> debbugs.gnu.org and Jisang Yoo <jisang.yoo.ac+org <at> gmail.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Sun, 28 Jul 2019 18:26:03 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Mon, 26 Aug 2019 11:24:07 GMT) Full text and rfc822 format available.

This bug report was last modified 5 years and 302 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.