unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#14772: 24.3; defvar and lexical-binding in interpreted elisp code
@ 2013-07-02 20:52 Jisang Yoo
  2013-07-03  9:30 ` Stefan Monnier
  0 siblings, 1 reply; 2+ messages in thread
From: Jisang Yoo @ 2013-07-02 20:52 UTC (permalink / raw)
  To: 14772

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.





^ permalink raw reply	[flat|nested] 2+ messages in thread

* bug#14772: 24.3; defvar and lexical-binding in interpreted elisp code
  2013-07-02 20:52 bug#14772: 24.3; defvar and lexical-binding in interpreted elisp code Jisang Yoo
@ 2013-07-03  9:30 ` Stefan Monnier
  0 siblings, 0 replies; 2+ messages in thread
From: Stefan Monnier @ 2013-07-03  9:30 UTC (permalink / raw)
  To: Jisang Yoo; +Cc: 14772

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





^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-07-03  9:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-02 20:52 bug#14772: 24.3; defvar and lexical-binding in interpreted elisp code Jisang Yoo
2013-07-03  9:30 ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).