all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Surrounding Lexical Variable Reference in the Body of defun
@ 2012-08-21  6:07 Deokhwan Kim
  2012-08-22  6:42 ` Andreas Röhler
  2012-08-22 15:11 ` Stefan Monnier
  0 siblings, 2 replies; 5+ messages in thread
From: Deokhwan Kim @ 2012-08-21  6:07 UTC (permalink / raw)
  To: help-gnu-emacs

Hi there,

I'm having trouble understanding lexical binding in Emacs 24. I came across the following sentence in the Emacs Lisp manual <http://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html>:

> the code in the body of a defun or defmacro cannot refer to surrounding lexical variables.

It was a great shock to me because it sounded quite awkward and Common Lisp does not have such restriction AFAIK. Rather, I suspected that I might misunderstand what the sentence really meant. So I decided to make some experiments with the following code stored in foo.el:

  ;;; -*- lexical-binding: t -*-
  (let ((x 0))
    (defun counter ()
      (setq x (1+ x))))

  (message "%d" (counter))
  (message "%d" (counter))

Surprisingly, when I ran it in the form of source code, it worked:

  $ emacs -Q -batch -l foo.el
  1
  2

On the other hand, when I tried to byte-compile it, I got the following warning messages:

  $ emacs -Q -batch -f batch-byte-compile foo.el
  In toplevel form:
  foo.el:2:1:Warning: Function counter will ignore its context (x)
  foo.el:2:1:Warning: Unused lexical variable `x'
  foo.el:4:11:Warning: reference to free variable `x'
  foo.el:4:17:Warning: assignment to free variable `x'

  In end of data:
  foo.el:8:1:Warning: the function `counter' is not known to be defined.
  Wrote foo.elc

When I ran the resulting byte-compiled code, I got an error as the manual claims:

  $ emacs -Q -batch -l foo.elc
  Symbol's value as variable is void: x

Now I'm so confused. Here are my two questions:

  1. Why does this restriction exists? Is it inevitable because of some design decision of Emacs? Or is it temporary and removed in a (near) future release?
  2. Why does the original source code behave differently from its compiled code?

Best regards,
Deokhwan Kim


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

* Re: Surrounding Lexical Variable Reference in the Body of defun
  2012-08-21  6:07 Surrounding Lexical Variable Reference in the Body of defun Deokhwan Kim
@ 2012-08-22  6:42 ` Andreas Röhler
  2012-08-22 15:11 ` Stefan Monnier
  1 sibling, 0 replies; 5+ messages in thread
From: Andreas Röhler @ 2012-08-22  6:42 UTC (permalink / raw)
  To: help-gnu-emacs

Am 21.08.2012 08:07, schrieb Deokhwan Kim:
> Hi there,
>
> I'm having trouble understanding lexical binding in Emacs 24. I came across the following sentence in the Emacs Lisp manual <http://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html>:
>
>> the code in the body of a defun or defmacro cannot refer to surrounding lexical variables.
>
> It was a great shock to me because it sounded quite awkward and Common Lisp does not have such restriction AFAIK. Rather, I suspected that I might misunderstand what the sentence really meant. So I decided to make some experiments with the following code stored in foo.el:
>
>    ;;; -*- lexical-binding: t -*-
>    (let ((x 0))
>      (defun counter ()
>        (setq x (1+ x))))
>
>    (message "%d" (counter))
>    (message "%d" (counter))
>
> Surprisingly, when I ran it in the form of source code, it worked:
>
>    $ emacs -Q -batch -l foo.el
>    1
>    2
>
> On the other hand, when I tried to byte-compile it, I got the following warning messages:
>
>    $ emacs -Q -batch -f batch-byte-compile foo.el
>    In toplevel form:
>    foo.el:2:1:Warning: Function counter will ignore its context (x)
>    foo.el:2:1:Warning: Unused lexical variable `x'
>    foo.el:4:11:Warning: reference to free variable `x'
>    foo.el:4:17:Warning: assignment to free variable `x'
>
>    In end of data:
>    foo.el:8:1:Warning: the function `counter' is not known to be defined.
>    Wrote foo.elc
>
> When I ran the resulting byte-compiled code, I got an error as the manual claims:
>
>    $ emacs -Q -batch -l foo.elc
>    Symbol's value as variable is void: x
>
> Now I'm so confused. Here are my two questions:
>
>    1. Why does this restriction exists? Is it inevitable because of some design decision of Emacs? Or is it temporary and removed in a (near) future release?
>    2. Why does the original source code behave differently from its compiled code?
>
> Best regards,
> Deokhwan Kim
>

as this question isn't raised first time, maybe Emacs developers consider to revert that change?




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

* Re: Surrounding Lexical Variable Reference in the Body of defun
  2012-08-21  6:07 Surrounding Lexical Variable Reference in the Body of defun Deokhwan Kim
  2012-08-22  6:42 ` Andreas Röhler
@ 2012-08-22 15:11 ` Stefan Monnier
  2012-08-23  2:56   ` justinhj
  2012-08-23 12:52   ` Deokhwan Kim
  1 sibling, 2 replies; 5+ messages in thread
From: Stefan Monnier @ 2012-08-22 15:11 UTC (permalink / raw)
  To: help-gnu-emacs

>   1. Why does this restriction exists? Is it inevitable because of
>      some design decision of Emacs? Or is it temporary and removed in
>      a (near) future release?

It is because of a technical limitation in the byte-compiler's handling
of dynamically loaded docstrings.

You can work around this by replacing your defun
with (defalias counter (lambda () (setq x (1+ x)))).

I believe this is fixed in the Emacs trunk (where defun is just a macro
that expands to a defalias+lambda and where the docstrings handling was
improved accordingly).


        Stefan


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

* Re: Surrounding Lexical Variable Reference in the Body of defun
  2012-08-22 15:11 ` Stefan Monnier
@ 2012-08-23  2:56   ` justinhj
  2012-08-23 12:52   ` Deokhwan Kim
  1 sibling, 0 replies; 5+ messages in thread
From: justinhj @ 2012-08-23  2:56 UTC (permalink / raw)
  To: help-gnu-emacs

Does this mean that if you build from emacs trunk then the code above should compile and run just fine? In which case is the manual wrong (or at least out of date) about warning you not to refer to the surrounding lexical environment from inside a defun?

Justin

> I believe this is fixed in the Emacs trunk (where defun is just a macro
> 
> that expands to a defalias+lambda and where the docstrings handling was
> 
> improved accordingly).
> 
> 
> 
> 
> 
>         Stefan



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

* Re: Surrounding Lexical Variable Reference in the Body of defun
  2012-08-22 15:11 ` Stefan Monnier
  2012-08-23  2:56   ` justinhj
@ 2012-08-23 12:52   ` Deokhwan Kim
  1 sibling, 0 replies; 5+ messages in thread
From: Deokhwan Kim @ 2012-08-23 12:52 UTC (permalink / raw)
  To: help-gnu-emacs

For reference, Revision 108427 (especially, lisp/emacs-lisp/byte-run.el) looks like bringing that change:

  http://bzr.savannah.gnu.org/lh/emacs/trunk/revision/108427

- Deokhwan Kim


On Wednesday, August 22, 2012 11:11:06 AM UTC-4, Stefan Monnier wrote:
> I believe this is fixed in the Emacs trunk (where defun is just a macro
> 
> that expands to a defalias+lambda and where the docstrings handling was
> 
> improved accordingly).


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

end of thread, other threads:[~2012-08-23 12:52 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-21  6:07 Surrounding Lexical Variable Reference in the Body of defun Deokhwan Kim
2012-08-22  6:42 ` Andreas Röhler
2012-08-22 15:11 ` Stefan Monnier
2012-08-23  2:56   ` justinhj
2012-08-23 12:52   ` Deokhwan Kim

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.