unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* defvar inside let-binding (was: bug#9090: 24.0.50; void-variable jka-compr-verbose)
       [not found]   ` <m3hb6nct3e.fsf@quimbies.gnus.org>
@ 2011-07-18 14:03     ` Stefan Monnier
  2011-07-18 14:20       ` defvar inside let-binding Lars Magne Ingebrigtsen
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2011-07-18 14:03 UTC (permalink / raw)
  To: emacs-devel

>>> When starting emacs, I'm getting a warning "Warning: defvar ignored
>>> because jka-compr-verbose is let-bound".
>> Fixed.
> Sorry; my fault.  The binding/later-loading thing is pretty annoying in
> general, though.

Yes.

> Has changing the way `defvar' works in the presence of let-bindings been
> discussed? 

No.  Personally I can't see how to make it work, because by the time we
get to defvar it's kind of too late.  Maybe we could try to change the
let-binding so that the "saved void state" (which will be restored at
the end of the outer let) gets changed as if the var had been defvarred
before the let-binding.  But it sounds terribly hackish.

Of course, another problem is that in the case of defcustom we don't
even detect the problem.


        Stefan



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

* Re: defvar inside let-binding
  2011-07-18 14:03     ` defvar inside let-binding (was: bug#9090: 24.0.50; void-variable jka-compr-verbose) Stefan Monnier
@ 2011-07-18 14:20       ` Lars Magne Ingebrigtsen
  2011-07-18 16:18         ` Stefan Monnier
  0 siblings, 1 reply; 9+ messages in thread
From: Lars Magne Ingebrigtsen @ 2011-07-18 14:20 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Has changing the way `defvar' works in the presence of let-bindings been
>> discussed? 
>
> No.  Personally I can't see how to make it work, because by the time we
> get to defvar it's kind of too late.  Maybe we could try to change the
> let-binding so that the "saved void state" (which will be restored at
> the end of the outer let) gets changed as if the var had been defvarred
> before the let-binding.  But it sounds terribly hackish.

That was exactly what I was thinking should happen.  :-)

I mean, if you say

(let ((foo-var nil))
  (foo-function))

and `foo-function' is autoloaded -- I can't think of a single use case
where you'd want `foo-var' to be unbound afterwards.

That `foo-function' is autoloaded or a real function is something that
should (in my opinion) have no effect on what you'd end up with after
calling it.

Leaving `foo-var' unbound is what is the hack, I think.  We should
strive to end up with the same result after calling `foo-function', no
matter whether it's autoloaded or not.

> Of course, another problem is that in the case of defcustom we don't
> even detect the problem.

I'm not sure I follow you there...

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/




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

* Re: defvar inside let-binding
  2011-07-18 14:20       ` defvar inside let-binding Lars Magne Ingebrigtsen
@ 2011-07-18 16:18         ` Stefan Monnier
  2011-07-19 16:14           ` Lars Magne Ingebrigtsen
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2011-07-18 16:18 UTC (permalink / raw)
  To: emacs-devel

>> Of course, another problem is that in the case of defcustom we don't
>> even detect the problem.
> I'm not sure I follow you there...

defcustom works differently from defvar and doesn't use defvar
(e.g. because it may not even define a real variable: the "var" may
simply only be available through accessor/setter functions) and since
the current code that detects a "defvar within let" is written in C code
in Fdefvar, it doesn't apply to defcustom.


        Stefan



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

* Re: defvar inside let-binding
  2011-07-18 16:18         ` Stefan Monnier
@ 2011-07-19 16:14           ` Lars Magne Ingebrigtsen
  2011-08-01 21:20             ` Stefan Monnier
  0 siblings, 1 reply; 9+ messages in thread
From: Lars Magne Ingebrigtsen @ 2011-07-19 16:14 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> defcustom works differently from defvar and doesn't use defvar
> (e.g. because it may not even define a real variable: the "var" may
> simply only be available through accessor/setter functions) and since
> the current code that detects a "defvar within let" is written in C code
> in Fdefvar, it doesn't apply to defcustom.

Right.

But does

(let ((foo nil))
  (foo-function))

leave `foo' unbound if `foo' is a defcustom?

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/




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

* Re: defvar inside let-binding
  2011-07-19 16:14           ` Lars Magne Ingebrigtsen
@ 2011-08-01 21:20             ` Stefan Monnier
  2011-08-02 13:42               ` Lars Magne Ingebrigtsen
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2011-08-01 21:20 UTC (permalink / raw)
  To: emacs-devel

> But does

> (let ((foo nil))
>   (foo-function))

> leave `foo' unbound if `foo' is a defcustom?

Yes, just like with defvar.  The difference is that defvar detects the
problem and outputs a warning.


        Stefan



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

* Re: defvar inside let-binding
  2011-08-01 21:20             ` Stefan Monnier
@ 2011-08-02 13:42               ` Lars Magne Ingebrigtsen
  2011-08-02 19:22                 ` Stefan Monnier
  0 siblings, 1 reply; 9+ messages in thread
From: Lars Magne Ingebrigtsen @ 2011-08-02 13:42 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> Yes, just like with defvar.  The difference is that defvar detects the
> problem and outputs a warning.

Ah, ok.  So if we decide to change the way let-bindings affect defvar
when we load files, then we have to basically implement the same
detection for defcustom.

Which we probably should do anyway.  :-)

It's this code, right?

      if (NILP (tem))
	Fset_default (sym, eval_sub (Fcar (tail)));
      else
	{ /* Check if there is really a global binding rather than just a let
	     binding that shadows the global unboundness of the var.  */
	  volatile struct specbinding *pdl = specpdl_ptr;
	  while (--pdl >= specpdl)
	    {
	      if (EQ (pdl->symbol, sym) && !pdl->func
		  && EQ (pdl->old_value, Qunbound))
		{
		  message_with_string ("Warning: defvar ignored because %s is let-bound",
				       SYMBOL_NAME (sym), 1);
		  break;
		}
	    }
	}

Since `defcustom' seems to be purely Emacs Lisp, and I don't think this
data is available on the Emacs Lisp level (am I wrong?), perhaps just
creating a C-level function `symbol-let-bound-p' (or something) would
allow us to issue the warning, as a first step?
        
-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/




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

* Re: defvar inside let-binding
  2011-08-02 13:42               ` Lars Magne Ingebrigtsen
@ 2011-08-02 19:22                 ` Stefan Monnier
  2011-08-02 19:56                   ` Lars Magne Ingebrigtsen
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2011-08-02 19:22 UTC (permalink / raw)
  To: emacs-devel

> Since `defcustom' seems to be purely Emacs Lisp, and I don't think this
> data is available on the Emacs Lisp level (am I wrong?), perhaps just
> creating a C-level function `symbol-let-bound-p' (or something) would
> allow us to issue the warning, as a first step?
        
Yes.  Tho the "next" step you suggested (to cause defvar to change the
outer let-binding) will require another such function and will make
symbol-let-bound-p unneeded.


        Stefan



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

* Re: defvar inside let-binding
  2011-08-02 19:22                 ` Stefan Monnier
@ 2011-08-02 19:56                   ` Lars Magne Ingebrigtsen
  2011-08-02 20:47                     ` Stefan Monnier
  0 siblings, 1 reply; 9+ messages in thread
From: Lars Magne Ingebrigtsen @ 2011-08-02 19:56 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> Yes.  Tho the "next" step you suggested (to cause defvar to change the
> outer let-binding) will require another such function and will make
> symbol-let-bound-p unneeded.

Let's see...

  ;; Use defvar to set the docstring as well as the special-variable-p flag.
  ;; FIXME: We should reproduce more of `defvar's behavior, such as the warning
  ;; when the var is currently let-bound.
  (if (not (default-boundp symbol))
      ;; Don't use defvar to avoid setting a default-value when undesired.
      (when doc (put symbol 'variable-documentation doc))
    (eval `(defvar ,symbol nil ,@(when doc (list doc)))))

So what I would do here now would be to add

(when (symbol-let-bound-p symbol)
  (message "Warning: let-bound etc"))

now, and in Emacs 24.2, I'd change that to

(when (symbol-let-bound-p symbol)
  (change-outer-let-binding symbol default))

Or something along those lines?  

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/



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

* Re: defvar inside let-binding
  2011-08-02 19:56                   ` Lars Magne Ingebrigtsen
@ 2011-08-02 20:47                     ` Stefan Monnier
  0 siblings, 0 replies; 9+ messages in thread
From: Stefan Monnier @ 2011-08-02 20:47 UTC (permalink / raw)
  To: Lars Magne Ingebrigtsen; +Cc: emacs-devel

>> Yes.  Tho the "next" step you suggested (to cause defvar to change the
>> outer let-binding) will require another such function and will make
>> symbol-let-bound-p unneeded.

> Let's see...

>   ;; Use defvar to set the docstring as well as the special-variable-p flag.
>   ;; FIXME: We should reproduce more of `defvar's behavior, such as the warning
>   ;; when the var is currently let-bound.
>   (if (not (default-boundp symbol))
>       ;; Don't use defvar to avoid setting a default-value when undesired.
>       (when doc (put symbol 'variable-documentation doc))
>     (eval `(defvar ,symbol nil ,@(when doc (list doc)))))

> So what I would do here now would be to add

> (when (symbol-let-bound-p symbol)
>   (message "Warning: let-bound etc"))

> now, and in Emacs 24.2, I'd change that to

> (when (symbol-let-bound-p symbol)
>   (change-outer-let-binding symbol default))

> Or something along those lines?  

Yes, although the above code is run after the var has been set,
i.e. too late.


        Stefan



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

end of thread, other threads:[~2011-08-02 20:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <87sjq7pq14.fsf@yun.yagibdah.de>
     [not found] ` <1ztyanqxv5.fsf@fencepost.gnu.org>
     [not found]   ` <m3hb6nct3e.fsf@quimbies.gnus.org>
2011-07-18 14:03     ` defvar inside let-binding (was: bug#9090: 24.0.50; void-variable jka-compr-verbose) Stefan Monnier
2011-07-18 14:20       ` defvar inside let-binding Lars Magne Ingebrigtsen
2011-07-18 16:18         ` Stefan Monnier
2011-07-19 16:14           ` Lars Magne Ingebrigtsen
2011-08-01 21:20             ` Stefan Monnier
2011-08-02 13:42               ` Lars Magne Ingebrigtsen
2011-08-02 19:22                 ` Stefan Monnier
2011-08-02 19:56                   ` Lars Magne Ingebrigtsen
2011-08-02 20:47                     ` 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).