[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Why is Elisp's defvar weird? And is eval_sub broken?
From: |
Stefan Monnier |
Subject: |
Re: Why is Elisp's defvar weird? And is eval_sub broken? |
Date: |
Fri, 13 Feb 2015 14:03:53 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) |
> But that's wrong. If INITVALUE is missing, and lexical-binding is
> t (as is the case in desktop.el), then not only is the value not set,
> but also the variable is _not_ declared special, even if the defvar
> is at top level.
The declaration of the var as being dynamically-scoped (aka "special")
is *local* to the (rest of the) current scope (typically the current file).
This is indispensable so that one package can use a dynamically-bound
variable `foo' without breaking some other package that expects `foo' to
be lexically-bound. Normally, such conflicts should never happen
because all special vars should be named with a "package prefix", but
sadly, reality is different, so it was indispensable to make this
effect local, to allow lexical-binding code to work reliably.
> That means that even after loading desktop.el, if you let-bind the
> three variables above in a function defined in a file other than
> desktop.el, and lexical-binding is t in that other file, then those
> variables will be bound lexically, not dynamically.
That's right.
If you're lucky (more specifically, if you only let-bind those vars but
you don't use them locally), the byte-compiler will emit a warning that
those let-bindings aren't used (which is usually a sign that you need
to add a (defvar <foo>) earlier in the file).
> That's because eval_sub in eval.c looks up the variable in the lexical
> environment using only Fassq, without first using Fmemq to check for
> a local dynamic binding. Is that behavior actually correct?
I wouldn't argue it's correct, but I'd rather not pay the price of an
additional memq check to cater to such brain-dead misuse of defvar.
Arguably, the byte-compiler should flag such misuse, tho currently it
misses it (tho it does catch the case of:
(let ((my-foo 0))
(let ((my-foo 1))
my-foo))
(defvar my-foo)
-- Stefan
- Why is Elisp's defvar weird? And is eval_sub broken?, Kelly Dean, 2015/02/12
- Re: Why is Elisp's defvar weird? And is eval_sub broken?,
Stefan Monnier <=
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Kelly Dean, 2015/02/14
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Stefan Monnier, 2015/02/14
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Daniel Colascione, 2015/02/15
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Kelly Dean, 2015/02/16
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Stefan Monnier, 2015/02/16
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Kelly Dean, 2015/02/17
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Stefan Monnier, 2015/02/18
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Kelly Dean, 2015/02/19
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Stefan Monnier, 2015/02/19
- Re: Why is Elisp's defvar weird? And is eval_sub broken?, Kelly Dean, 2015/02/19