unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* void variable
@ 2004-07-25  6:32 Lars Hansen
  2004-07-25  7:56 ` Adrian Aichner
                   ` (2 more replies)
  0 siblings, 3 replies; 46+ messages in thread
From: Lars Hansen @ 2004-07-25  6:32 UTC (permalink / raw)


Assume that you on the load path have a file foo.el containing the line

  (defvar foo 'x)

If you evaluate

  (let ((foo 'y)) (load "foo.el"))
  foo

you get

  Symbol's value as variable is void: foo

Observe that the loading may very well be implicit like in

  (let ((foo 'y)) (bar))

where bar could be an autoloaded function in foo.el or even in another 
module requiring foo.el.
This behavior is not new. It works like that in Emacs 21.2 and Emacs 20.7.

Is the behavior a bug that should be fixed, or is it OK but should be 
documented? Or is it documented already?

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

* Re: void variable
  2004-07-25  6:32 void variable Lars Hansen
@ 2004-07-25  7:56 ` Adrian Aichner
  2004-07-25 19:25 ` Lars Hansen
  2004-07-26  1:29 ` Richard Stallman
  2 siblings, 0 replies; 46+ messages in thread
From: Adrian Aichner @ 2004-07-25  7:56 UTC (permalink / raw)


Lars Hansen <larsh@math.ku.dk> writes:

> Assume that you on the load path have a file foo.el containing the line
>
>   (defvar foo 'x)
>
> If you evaluate
>
>   (let ((foo 'y)) (load "foo.el"))
>   foo
>
> you get
>
>   Symbol's value as variable is void: foo
>
> Observe that the loading may very well be implicit like in
>
>   (let ((foo 'y)) (bar))
>
> where bar could be an autoloaded function in foo.el or even in another
> module requiring foo.el.
> This behavior is not new. It works like that in Emacs 21.2 and Emacs 20.7.
>
> Is the behavior a bug that should be fixed, or is it OK but should be
> documented? Or is it documented already?

Hi Lars, the local binding of foo established by the let form is
causing this behavior.

This is pretty well documented in
(info "(lispref)Local Variables")
and
(info "(lispref)Variable Scoping")

Hope this helps,

Adrian

-- 
Adrian Aichner
 mailto:adrian@xemacs.org
 http://www.xemacs.org/

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

* Re: void variable
  2004-07-25  6:32 void variable Lars Hansen
  2004-07-25  7:56 ` Adrian Aichner
@ 2004-07-25 19:25 ` Lars Hansen
  2004-07-25 20:46   ` Luc Teirlinck
  2004-07-26  1:29 ` Richard Stallman
  2 siblings, 1 reply; 46+ messages in thread
From: Lars Hansen @ 2004-07-25 19:25 UTC (permalink / raw)


I now see that the docstring of defvar clearly says that the variable is 
  set only if it is void. So

   (let ((foo 'y)) (defvar foo 'x))

should leave foo void as it does.

So there is no problem :-)

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

* Re: void variable
  2004-07-25 19:25 ` Lars Hansen
@ 2004-07-25 20:46   ` Luc Teirlinck
  2004-07-25 21:54     ` Lars Hansen
                       ` (2 more replies)
  0 siblings, 3 replies; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-25 20:46 UTC (permalink / raw)
  Cc: emacs-devel

Lars Hansen wrote:

   I now see that the docstring of defvar clearly says that the variable is 
     set only if it is void. So

      (let ((foo 'y)) (defvar foo 'x))

   should leave foo void as it does.

It has nothing to do with the fact that defvar only sets the variable
if void.  You get the same result with:
(let ((foo 'y)) (makunbound 'foo) (defvar foo 'x))
See the ielm run at the end of this posting.

What it has to do with is the following quote from
`(elisp)Defining Variables':

       *Warning:* If the `defconst' and `defvar' special forms are
    used while the variable has a local binding (made with `let', or a
    function argument), they set the local-binding's value; the
    top-level binding is not changed.  This is not what you usually
    want.  To prevent it, use these special forms at top level in a
    file, where normally no local binding is in effect, and make sure
    to load the file before making a local binding for the variable.

This also applies to defcustom.

   So there is no problem :-)

Unless other people might be confused by this too.  Maybe it might be
good to add the above warning to the involved docstrings.

What about the following patches?

===File ~/eval.c-diff=======================================
*** eval.c	19 Jul 2004 07:02:32 -0500	1.220
--- eval.c	25 Jul 2004 15:19:42 -0500	
***************
*** 742,747 ****
--- 742,754 ----
   This means that M-x set-variable recognizes it.
   See also `user-variable-p'.
  If INITVALUE is missing, SYMBOL's value is not set.
+ 
+ If SYMBOL has a local binding, then this form affects the local
+ binding.  This is usually not what you want.  Thus, if you need to
+ load a file defining variables, with this form or with `defconst' or
+ `defcustom', you should always load that file _outside_ any bindings
+ for these variables.  \(`defconst' and `defcustom' behave similarly in
+ this respect.)
  usage: (defvar SYMBOL &optional INITVALUE DOCSTRING)  */)
       (args)
       Lisp_Object args;
***************
*** 784,789 ****
--- 791,800 ----
  If SYMBOL is buffer-local, its default value is what is set;
   buffer-local values are not affected.
  DOCSTRING is optional.
+ 
+ If SYMBOL has a local binding, then this form sets the local binding's
+ value.  However, you should normally not make local bindings for
+ variables defined with this form.
  usage: (defconst SYMBOL INITVALUE [DOCSTRING])  */)
       (args)
       Lisp_Object args;
============================================================

===File ~/custom.el-diff====================================
*** custom.el	05 Jun 2004 22:41:36 -0500	1.75
--- custom.el	25 Jul 2004 15:19:30 -0500	
***************
*** 246,251 ****
--- 246,258 ----
  	Specifies that SYMBOL should be set after the list of variables
          VARIABLES when both have been customized.
  
+ If SYMBOL has a local binding, then this form affects the local
+ binding.  This is normally not what you want.  Thus, if you need
+ to load a file defining variables with this form, or with
+ `defvar' or `defconst', you should always load that file
+ _outside_ any bindings for these variables.  \(`defvar' and
+ `defconst' behave similarly in this respect.)
+ 
  Read the section about customization in the Emacs Lisp manual for more
  information."
    ;; It is better not to use backquote in this file,
============================================================

Just to illustrate:

===File ~/foo-ielm==========================================
*** Welcome to IELM ***  Type (describe-mode) for help.
ELISP> (let ((foo 1)) (defvar foo 2) foo)
1
ELISP> (boundp 'foo)
nil
ELISP> (let ((foo 1)) (makunbound 'foo) (defvar foo 2) foo)
2
ELISP> (boundp 'foo)
nil
ELISP> (let ((foo 1)) (defconst foo 2) foo)
2
ELISP> (boundp 'foo)
nil
ELISP> (defvar foo 3)
foo
ELISP> (let ((foo 1)) (makunbound 'foo) (defvar foo 2) foo)
2
ELISP> foo
3
ELISP> (makunbound 'foo)
foo
ELISP> (let ((foo 1)) (makunbound 'foo) (defcustom foo 2 "blabla") foo)
2
ELISP> (boundp 'foo)
nil
ELISP> (defcustom foo 3 "blabla")
foo
ELISP> (let ((foo 1)) (makunbound 'foo) (defcustom foo 2 "blabla") foo)
2
ELISP> foo
3
ELISP> 
============================================================

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

* Re: void variable
  2004-07-25 20:46   ` Luc Teirlinck
@ 2004-07-25 21:54     ` Lars Hansen
  2004-07-25 23:39       ` Luc Teirlinck
  2004-07-26  1:52       ` Luc Teirlinck
  2004-07-26  3:13     ` Richard Stallman
  2004-07-26 19:23     ` Stefan Monnier
  2 siblings, 2 replies; 46+ messages in thread
From: Lars Hansen @ 2004-07-25 21:54 UTC (permalink / raw)
  Cc: emacs-devel

Luc Teirlinck wrote:

>Unless other people might be confused by this too.  Maybe it might be
>good to add the above warning to the involved docstrings.
>  
>
I think that is a good idea. And thanks for your information.

Maybe there should also be a warning somewhere that one must ensure that 
a module is loaded before making local bindings of variables defined in 
that module. I just fixed a bug in wdired where the following happened: 
A custom variable in dired-aux was bound locally just before the call of 
an autoloading  function from dired-aux. The result was that the custom 
variable was left void if dired-aux was loaded at that point. That 
caused dired renaming to malfunction afterwards.

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

* Re: void variable
  2004-07-25 21:54     ` Lars Hansen
@ 2004-07-25 23:39       ` Luc Teirlinck
  2004-07-25 23:54         ` Luc Teirlinck
  2004-07-26  1:52       ` Luc Teirlinck
  1 sibling, 1 reply; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-25 23:39 UTC (permalink / raw)
  Cc: emacs-devel

Lars Hansen wrote:

   Maybe there should also be a warning somewhere that one must ensure that 
   a module is loaded before making local bindings of variables defined in 
   that module. I just fixed a bug in wdired where the following happened: 
   A custom variable in dired-aux was bound locally just before the call of 
   an autoloading  function from dired-aux. The result was that the custom 
   variable was left void if dired-aux was loaded at that point. That 
   caused dired renaming to malfunction afterwards.

Would the following patches be more useful than my original ones?

===File ~/eval.c-diff-2=====================================
*** eval.c	19 Jul 2004 07:02:32 -0500	1.220
--- eval.c	25 Jul 2004 18:20:38 -0500	
***************
*** 742,747 ****
--- 742,756 ----
   This means that M-x set-variable recognizes it.
   See also `user-variable-p'.
  If INITVALUE is missing, SYMBOL's value is not set.
+ 
+ WARNING: If SYMBOL has a local binding when this form is called, then
+ the call affects the local binding.  This is usually not what you want.
+ Thus, if you make a local binding for a variable that is defined in
+ some file FILE with this form \(or with `defconst' or `defcustom',
+ which behave similarly in this respect), you should carefully check
+ whether something in the scope of the binding can load FILE.  If so,
+ you should execute \(require FILE) before making the binding, unless
+ for some reason you know that the file is already loaded.
  usage: (defvar SYMBOL &optional INITVALUE DOCSTRING)  */)
       (args)
       Lisp_Object args;
***************
*** 784,789 ****
--- 793,802 ----
  If SYMBOL is buffer-local, its default value is what is set;
   buffer-local values are not affected.
  DOCSTRING is optional.
+ 
+ If SYMBOL has a local binding, then this form sets the local binding's
+ value.  However, you should normally not make local bindings for
+ variables defined with this form.
  usage: (defconst SYMBOL INITVALUE [DOCSTRING])  */)
       (args)
       Lisp_Object args;
============================================================

===File ~/custom.el-diff-2==================================
*** custom.el	05 Jun 2004 22:41:36 -0500	1.75
--- custom.el	25 Jul 2004 18:30:52 -0500	
***************
*** 247,253 ****
          VARIABLES when both have been customized.
  
  Read the section about customization in the Emacs Lisp manual for more
! information."
    ;; It is better not to use backquote in this file,
    ;; because that makes a bootstrapping problem
    ;; if you need to recompile all the Lisp files using interpreted code.
--- 247,263 ----
          VARIABLES when both have been customized.
  
  Read the section about customization in the Emacs Lisp manual for more
! information.
! 
! WARNING: If SYMBOL has a local binding when this form is called,
! then the call affects the local binding.  This is usually not
! what you want.  Thus, if you make a local binding for a variable
! that is defined in some file FILE with this form \(or with
! `defvar' or `defconst', which behave similarly in this respect),
! you should carefully check whether something in the scope of the
! binding can load FILE.  If so, you should execute \(require FILE)
! before making the binding, unless for some reason you know that
! the file is already loaded."
    ;; It is better not to use backquote in this file,
    ;; because that makes a bootstrapping problem
    ;; if you need to recompile all the Lisp files using interpreted code.
============================================================

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

* Re: void variable
  2004-07-25 23:39       ` Luc Teirlinck
@ 2004-07-25 23:54         ` Luc Teirlinck
  0 siblings, 0 replies; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-25 23:54 UTC (permalink / raw)
  Cc: larsh, emacs-devel

I now believe that I should replace:

   + some file FILE with this form \(or with `defconst' or `defcustom',
   + which behave similarly in this respect), you should carefully check

with:

   some file FILE with this form \(or with `defcustom', which behaves
   similarly in this respect), you should carefully check

and:

   ! that is defined in some file FILE with this form \(or with
   ! `defvar' or `defconst', which behave similarly in this respect),

with:

   that is defined in some file FILE with this form \(or with
   `defvar', which behave similarly in this respect),

We do not want to encourage people to make local bindings for variables
defined with `defconst'.

Sincerely,

Luc.

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

* Re: void variable
  2004-07-25  6:32 void variable Lars Hansen
  2004-07-25  7:56 ` Adrian Aichner
  2004-07-25 19:25 ` Lars Hansen
@ 2004-07-26  1:29 ` Richard Stallman
  2 siblings, 0 replies; 46+ messages in thread
From: Richard Stallman @ 2004-07-26  1:29 UTC (permalink / raw)
  Cc: emacs-devel

    Is the behavior a bug that should be fixed, or is it OK but should be 
    documented? Or is it documented already?

It is hard to do anything about this--this is a special case of how
variables work.  I tend to think it is not worth documenting in the
manual.  Important variables typically get autoloaded, which means
they are defined before the relevant file actually gets loaded, so
loading the file doesn't set them anyway.

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

* Re: void variable
  2004-07-25 21:54     ` Lars Hansen
  2004-07-25 23:39       ` Luc Teirlinck
@ 2004-07-26  1:52       ` Luc Teirlinck
  2004-07-26  2:13         ` Luc Teirlinck
  1 sibling, 1 reply; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-26  1:52 UTC (permalink / raw)
  Cc: emacs-devel

   Would the following patches be more useful than my original ones?

After reading Richard's reply, I realized that I forgot about
autoloaded variables in that second patch.  So I believe that my first
patch would be better.  If we would actually go for the second, then:

   + Thus, if you make a local binding for a variable that is defined in

should twice be replaced with:

      Thus, if you make a local binding for a non-autoloaded variable
      that is defined in ...

Sincerely,

Luc.

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

* Re: void variable
  2004-07-26  1:52       ` Luc Teirlinck
@ 2004-07-26  2:13         ` Luc Teirlinck
  2004-07-26 14:30           ` Richard Stallman
  0 siblings, 1 reply; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-26  2:13 UTC (permalink / raw)
  Cc: larsh, emacs-devel

>From my previous message:

   So I believe that my first patch would be better.

Actually, on second thought I am not that sure anymore.  Several
variables, that are important enough for people to want to bind them,
are not autoloaded.  The situation is potentially dangerous, as we
saw with wdired.  So we should warn about it _somewhere_.  Either the
manual or the docstrings or both.

Of course, one should make the change I mentioned.

Sincerely,

Luc.

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

* Re: void variable
  2004-07-25 20:46   ` Luc Teirlinck
  2004-07-25 21:54     ` Lars Hansen
@ 2004-07-26  3:13     ` Richard Stallman
  2004-07-26 19:23     ` Stefan Monnier
  2 siblings, 0 replies; 46+ messages in thread
From: Richard Stallman @ 2004-07-26  3:13 UTC (permalink / raw)
  Cc: larsh, emacs-devel

Those doc fixes are ok.

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

* Re: void variable
  2004-07-26  2:13         ` Luc Teirlinck
@ 2004-07-26 14:30           ` Richard Stallman
  2004-07-26 15:12             ` Lars Hansen
                               ` (2 more replies)
  0 siblings, 3 replies; 46+ messages in thread
From: Richard Stallman @ 2004-07-26 14:30 UTC (permalink / raw)
  Cc: larsh, teirllm, emacs-devel

    Actually, on second thought I am not that sure anymore.  Several
    variables, that are important enough for people to want to bind them,
    are not autoloaded.  The situation is potentially dangerous, as we
    saw with wdired.  So we should warn about it _somewhere_.  Either the
    manual or the docstrings or both.

The manual should direct people to autoload variables used by
autoloaded functions, if programs might want to bind them.

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

* Re: void variable
  2004-07-26 14:30           ` Richard Stallman
@ 2004-07-26 15:12             ` Lars Hansen
  2004-07-27 18:18               ` Richard Stallman
  2004-07-26 15:21             ` Luc Teirlinck
  2004-07-26 16:05             ` Kai Grossjohann
  2 siblings, 1 reply; 46+ messages in thread
From: Lars Hansen @ 2004-07-26 15:12 UTC (permalink / raw)
  Cc: Luc Teirlinck, emacs-devel


>    Actually, on second thought I am not that sure anymore.  Several
>    variables, that are important enough for people to want to bind them,
>    are not autoloaded.  The situation is potentially dangerous, as we
>    saw with wdired.  So we should warn about it _somewhere_.  Either the
>    manual or the docstrings or both.
>
>The manual should direct people to autoload variables used by
>autoloaded functions, if programs might want to bind them.
>  
>
I agree that the manual should direct people to autoload variables used 
by autoloaded functions if programs might want to bind them.
But I also think it should be carefully explained what can happen if a 
non-autoloaded variable is bound. We cannot be sure all relevant 
variables are autoloaded.

What about:
1. Docstrings of defvar, defcustom and let briefly explain what happens 
if a local binding exist when defvar or defcustom is evaluated _and_ 
mention the autoloading pitfall.
2. Manual explain the same a bit more elaborate and direct people to 
autoload relevant variables to avoid the pitfall.

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

* Re: void variable
  2004-07-26 14:30           ` Richard Stallman
  2004-07-26 15:12             ` Lars Hansen
@ 2004-07-26 15:21             ` Luc Teirlinck
  2004-07-27 18:18               ` Richard Stallman
  2004-07-26 16:05             ` Kai Grossjohann
  2 siblings, 1 reply; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-26 15:21 UTC (permalink / raw)
  Cc: larsh, emacs-devel

Richard Stallman wrote:

   The manual should direct people to autoload variables used by
   autoloaded functions, if programs might want to bind them.

It is not just the variables _used_ by the autoloaded function.  In
the concrete bug, `dired-rename-file' does not use
`dired-backup-overwrite', at least not directly.

So whenever a file contains any autoloaded function, one should
autoload _all_ variables in the file that any program might
conceivably ever want to bind.  Just about any file nowadays contains
some autoloaded function and just about any variable that is not
strictly internal or defined with `defconst' could conceivably be
bound by another program.

After taking a brief look at some sample files, it would seem that
`loaddefs' might get very big.

Sincerely,

Luc.

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

* Re: void variable
  2004-07-26 14:30           ` Richard Stallman
  2004-07-26 15:12             ` Lars Hansen
  2004-07-26 15:21             ` Luc Teirlinck
@ 2004-07-26 16:05             ` Kai Grossjohann
  2004-07-26 18:40               ` Lars Hansen
  2004-07-27 18:18               ` Richard Stallman
  2 siblings, 2 replies; 46+ messages in thread
From: Kai Grossjohann @ 2004-07-26 16:05 UTC (permalink / raw)


Richard Stallman <rms@gnu.org> writes:

>     Actually, on second thought I am not that sure anymore.  Several
>     variables, that are important enough for people to want to bind them,
>     are not autoloaded.  The situation is potentially dangerous, as we
>     saw with wdired.  So we should warn about it _somewhere_.  Either the
>     manual or the docstrings or both.
>
> The manual should direct people to autoload variables used by
> autoloaded functions, if programs might want to bind them.

If foo.el defines a variable foo-var, and bar.el wishes to let-bind
this variable, then perhaps the manual should suggest the *caller*
(ie, bar.el) to require foo:

(require 'foo)

(defun bar-func ()
  (let ((foo-var ...))
    ...))

WDYT?

Kai

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

* Re: void variable
  2004-07-26 16:05             ` Kai Grossjohann
@ 2004-07-26 18:40               ` Lars Hansen
  2004-07-27 18:18               ` Richard Stallman
  1 sibling, 0 replies; 46+ messages in thread
From: Lars Hansen @ 2004-07-26 18:40 UTC (permalink / raw)
  Cc: emacs-devel

Kai Grossjohann wrote:
> If foo.el defines a variable foo-var, and bar.el wishes to let-bind
> this variable, then perhaps the manual should suggest the *caller*
> (ie, bar.el) to require foo:
> 
> (require 'foo)
> 
> (defun bar-func ()
>   (let ((foo-var ...))
>     ...))

I guess one wants to avoid unnessary loading. So maybe it should be

(defun bar-func ()
   (require 'foo)
   (let ((foo-var ...))
     ...))

At least that was what I did in wdired.el.

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

* Re: void variable
  2004-07-25 20:46   ` Luc Teirlinck
  2004-07-25 21:54     ` Lars Hansen
  2004-07-26  3:13     ` Richard Stallman
@ 2004-07-26 19:23     ` Stefan Monnier
  2004-07-26 19:46       ` Lars Hansen
                         ` (2 more replies)
  2 siblings, 3 replies; 46+ messages in thread
From: Stefan Monnier @ 2004-07-26 19:23 UTC (permalink / raw)
  Cc: larsh, emacs-devel

> Unless other people might be confused by this too.  Maybe it might be
> good to add the above warning to the involved docstrings.

I think adding such warnings won't help much.  I know damn well how those
variable bindings work, but I get burned every once in a while anyway.

Maybe we could arrange for defvar to burp a warning if the var is currently
let-bound?


        Stefan

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

* Re: void variable
  2004-07-26 19:23     ` Stefan Monnier
@ 2004-07-26 19:46       ` Lars Hansen
  2004-07-26 19:46       ` David Kastrup
  2004-07-26 20:41       ` Luc Teirlinck
  2 siblings, 0 replies; 46+ messages in thread
From: Lars Hansen @ 2004-07-26 19:46 UTC (permalink / raw)
  Cc: Luc Teirlinck, emacs-devel

Stefan Monnier wrote:

>I think adding such warnings won't help much.  I know damn well how those
>variable bindings work, but I get burned every once in a while anyway.
>
I did not know it. And there is a fair chance that I might have read the 
docstring.
Maybe it won't *solve* the problem, but I am sure it will help.

>Maybe we could arrange for defvar to burp a warning if the var is currently
>let-bound?
>  
>
Yes, why not?

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

* Re: void variable
  2004-07-26 19:23     ` Stefan Monnier
  2004-07-26 19:46       ` Lars Hansen
@ 2004-07-26 19:46       ` David Kastrup
  2004-07-26 20:41       ` Luc Teirlinck
  2 siblings, 0 replies; 46+ messages in thread
From: David Kastrup @ 2004-07-26 19:46 UTC (permalink / raw)
  Cc: larsh, Luc Teirlinck, emacs-devel

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

> > Unless other people might be confused by this too.  Maybe it might be
> > good to add the above warning to the involved docstrings.
> 
> I think adding such warnings won't help much.  I know damn well how those
> variable bindings work, but I get burned every once in a while anyway.
> 
> Maybe we could arrange for defvar to burp a warning if the var is currently
> let-bound?

Sounds like a more effective solution to me.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

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

* Re: void variable
  2004-07-26 19:23     ` Stefan Monnier
  2004-07-26 19:46       ` Lars Hansen
  2004-07-26 19:46       ` David Kastrup
@ 2004-07-26 20:41       ` Luc Teirlinck
  2004-07-26 21:13         ` Stefan Monnier
  2004-07-28 16:00         ` Richard Stallman
  2 siblings, 2 replies; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-26 20:41 UTC (permalink / raw)
  Cc: larsh, emacs-devel

Stefan Monnier wrote:

   Maybe we could arrange for defvar to burp a warning if the var is currently
   let-bound?

Just to be sure, I assume you mean a compiler warning?  (As opposed to
the kind of thing that `define-minor-mode' does.)  defvar-ing
let-bound variables is OK for autoloaded variables.  It is also OK for
`(defvar foo)''s that are just there to pacify the compiler.

Sincerely,

Luc.

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

* Re: void variable
  2004-07-26 20:41       ` Luc Teirlinck
@ 2004-07-26 21:13         ` Stefan Monnier
  2004-07-27  2:59           ` Luc Teirlinck
                             ` (2 more replies)
  2004-07-28 16:00         ` Richard Stallman
  1 sibling, 3 replies; 46+ messages in thread
From: Stefan Monnier @ 2004-07-26 21:13 UTC (permalink / raw)
  Cc: larsh, emacs-devel

>    Maybe we could arrange for defvar to burp a warning if the var is
>    currently let-bound?

> Just to be sure, I assume you mean a compiler warning?  (As opposed to
> the kind of thing that `define-minor-mode' does.)  defvar-ing
> let-bound variables is OK for autoloaded variables.  It is also OK for
> `(defvar foo)''s that are just there to pacify the compiler.

I don't think it can be done half-reliably by the byte-compiler.
I was suggesting a runtime check in Fdefvar.


        Stefan

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

* Re: void variable
  2004-07-26 21:13         ` Stefan Monnier
@ 2004-07-27  2:59           ` Luc Teirlinck
  2004-07-27  3:07           ` Luc Teirlinck
  2004-07-27  3:09           ` Luc Teirlinck
  2 siblings, 0 replies; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-27  2:59 UTC (permalink / raw)
  Cc: larsh, emacs-devel

Stefan Monnier wrote:

   I don't think it can be done half-reliably by the byte-compiler.
   I was suggesting a runtime check in Fdefvar.

In that case I definitely believe that it would be important not to
throw an error if the defvar is autoloaded, because that is definitely
an acceptable way to get around the problem (regardless of whether or
not it should be considered the only acceptable way).  Also, it would
be very important not to throw errors for compiler pacifiers like
`(defvar foo)'.  Otherwise, we would get tons of irrelevant error
messages and that would be very annoying for the user.

Would there be a way for the user to turn off these messages?

Sincerely,

Luc.

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

* Re: void variable
  2004-07-26 21:13         ` Stefan Monnier
  2004-07-27  2:59           ` Luc Teirlinck
@ 2004-07-27  3:07           ` Luc Teirlinck
  2004-07-27  3:09           ` Luc Teirlinck
  2 siblings, 0 replies; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-27  3:07 UTC (permalink / raw)
  Cc: larsh, emacs-devel

   Otherwise, we would get tons of irrelevant error
   messages and that would be very annoying for the user.

I meant "warnings" not "error messages", but still, irrelevant
warnings can be very annoying and confusing to the user.

Sincerely,

Luc.

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

* Re: void variable
  2004-07-26 21:13         ` Stefan Monnier
  2004-07-27  2:59           ` Luc Teirlinck
  2004-07-27  3:07           ` Luc Teirlinck
@ 2004-07-27  3:09           ` Luc Teirlinck
  2 siblings, 0 replies; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-27  3:09 UTC (permalink / raw)
  Cc: larsh, emacs-devel

Actually "error" should be replaced with "warning" throughout my
message.

Sincerely,

Luc.

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

* Re: void variable
  2004-07-26 15:12             ` Lars Hansen
@ 2004-07-27 18:18               ` Richard Stallman
  2004-07-29  2:31                 ` Luc Teirlinck
  0 siblings, 1 reply; 46+ messages in thread
From: Richard Stallman @ 2004-07-27 18:18 UTC (permalink / raw)
  Cc: teirllm, emacs-devel

    What about:
    1. Docstrings of defvar, defcustom and let briefly explain what happens 
    if a local binding exist when defvar or defcustom is evaluated _and_ 
    mention the autoloading pitfall.

I think that is going overboard.  It would be tiresome to mention
this in every doc string that relates to variables.  It should be
enough to say this in the section on autoloading.

    2. Manual explain the same a bit more elaborate and direct people to 
    autoload relevant variables to avoid the pitfall.

That could mean too many things, so I have no opinion.

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

* Re: void variable
  2004-07-26 15:21             ` Luc Teirlinck
@ 2004-07-27 18:18               ` Richard Stallman
  0 siblings, 0 replies; 46+ messages in thread
From: Richard Stallman @ 2004-07-27 18:18 UTC (permalink / raw)
  Cc: larsh, emacs-devel

       The manual should direct people to autoload variables used by
       autoloaded functions, if programs might want to bind them.

    It is not just the variables _used_ by the autoloaded function.  In
    the concrete bug, `dired-rename-file' does not use
    `dired-backup-overwrite', at least not directly.

Point noted.  However, it surely uses that variable indirectly, or
people would not have written code to bind that variable around that
call.

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

* Re: void variable
  2004-07-26 16:05             ` Kai Grossjohann
  2004-07-26 18:40               ` Lars Hansen
@ 2004-07-27 18:18               ` Richard Stallman
  1 sibling, 0 replies; 46+ messages in thread
From: Richard Stallman @ 2004-07-27 18:18 UTC (permalink / raw)
  Cc: emacs-devel

    > The manual should direct people to autoload variables used by
    > autoloaded functions, if programs might want to bind them.

    If foo.el defines a variable foo-var, and bar.el wishes to let-bind
    this variable, then perhaps the manual should suggest the *caller*
    (ie, bar.el) to require foo:

Either solution could work, but the former requires changes in
fewer places, so it might be more reliable as an approach.

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

* Re: void variable
  2004-07-26 20:41       ` Luc Teirlinck
  2004-07-26 21:13         ` Stefan Monnier
@ 2004-07-28 16:00         ` Richard Stallman
  2004-07-29  2:00           ` Luc Teirlinck
  2004-08-19 19:33           ` Stefan Monnier
  1 sibling, 2 replies; 46+ messages in thread
From: Richard Stallman @ 2004-07-28 16:00 UTC (permalink / raw)
  Cc: larsh, monnier, emacs-devel

    Maybe we could arrange for defvar to burp a warning if the var is currently
    let-bound?

That sounds like a good idea.  It should be possible to do this
by searching the specpdl.

       Maybe we could arrange for defvar to burp a warning if the var is currently
       let-bound?

    Just to be sure, I assume you mean a compiler warning?

This is a load-time occurrence; the compiler cannot detect it.
It would have to be detected at run time.  The warning could
use display-warning.

      defvar-ing
    let-bound variables is OK for autoloaded variables.

The warning could be issued only when the global binding that was
shadowed by the let-binding was unbound.  That will never be the case
for autoloaded variables.

      It is also OK for
    `(defvar foo)''s that are just there to pacify the compiler.

Yes, that case should not warn.

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

* Re: void variable
  2004-07-28 16:00         ` Richard Stallman
@ 2004-07-29  2:00           ` Luc Teirlinck
  2004-08-19 19:33           ` Stefan Monnier
  1 sibling, 0 replies; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-29  2:00 UTC (permalink / raw)
  Cc: larsh, monnier, emacs-devel

Clearly, if we make `defvar' warn, then we should do exactly the
same for `defcustom' and `defconst'.  Of course, one normally should
not bind variables defined with `defconst' to begin with.

Sincerely,

Luc.

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

* Re: void variable
  2004-07-27 18:18               ` Richard Stallman
@ 2004-07-29  2:31                 ` Luc Teirlinck
  2004-07-29  7:19                   ` Lars Hansen
  2004-07-30  4:55                   ` Richard Stallman
  0 siblings, 2 replies; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-29  2:31 UTC (permalink / raw)
  Cc: larsh, emacs-devel

Richard Stallman wrote:

       2. Manual explain the same a bit more elaborate and direct people to 
       autoload relevant variables to avoid the pitfall.

   That could mean too many things, so I have no opinion.

I have committed my _original_ patches for def{var,const,custom}.
In as far as the Elisp manual is concerned, what about the following patch?

===File ~/variables-diff====================================
*** variables.texi	23 Jun 2004 10:23:55 -0500	1.52
--- variables.texi	28 Jul 2004 21:15:39 -0500	
***************
*** 1,6 ****
  @c -*-texinfo-*-
  @c This is part of the GNU Emacs Lisp Reference Manual.
! @c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999,
  @c 2000, 2003, 2004
  @c   Free Software Foundation, Inc.
  @c See the file elisp.texi for copying conditions.
--- 1,6 ----
  @c -*-texinfo-*-
  @c This is part of the GNU Emacs Lisp Reference Manual.
! @c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2004,
  @c 2000, 2003, 2004
  @c   Free Software Foundation, Inc.
  @c See the file elisp.texi for copying conditions.
***************
*** 588,593 ****
--- 588,606 ----
  a file, where normally no local binding is in effect, and make sure to
  load the file before making a local binding for the variable.
  
+ If you make a local binding for a variable defined with @code{defvar}
+ or @code{defcustom} in another non-preloaded file, and if anything in
+ the scope of the binding loads that file, for instance through
+ autoloading, then this may fail to properly initialize the variable.
+ If the @code{defvar} or @code{defcustom} itself is autoloaded through
+ a magic comment (@pxref{Autoload}), then there is nothing to worry
+ about: it is already initialized.  Otherwise, there are two ways to
+ prevent trouble.  You can precede the @code{defvar} or
+ @code{defcustom} with a magic comment, or you can @code{require} the
+ file before making the binding (@pxref{Named Features}).  The same
+ applies to variables defined with @code{defconst}, but you should
+ normally not bind such variables anyway.
+ 
  @node Tips for Defining
  @section Tips for Defining Variables Robustly
  
============================================================

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

* Re: void variable
  2004-07-29  2:31                 ` Luc Teirlinck
@ 2004-07-29  7:19                   ` Lars Hansen
  2004-07-30  3:21                     ` Luc Teirlinck
  2004-07-30  4:55                   ` Richard Stallman
  1 sibling, 1 reply; 46+ messages in thread
From: Lars Hansen @ 2004-07-29  7:19 UTC (permalink / raw)
  Cc: rms, emacs-devel

Luc Teirlinck wrote:

>In as far as the Elisp manual is concerned, what about the following patch?
>
Looks good to me.
However, it confuses me that autoloading of variables is mentioned twice.
So what about changing

+ If the @code{defvar} or @code{defcustom} itself is autoloaded through
+ a magic comment (@pxref{Autoload}), then there is nothing to worry
+ about: it is already initialized.  Otherwise, there are two ways to
+ prevent trouble.  You can precede the @code{defvar} or
+ @code{defcustom} with a magic comment, or you can @code{require} the
+ file before making the binding (@pxref{Named Features}).

to

+ If the @code{defvar} or @code{defcustom} itself is autoloaded through
+ a magic comment (@pxref{Autoload}), then there is nothing to worry
+ about: it is already initialized.  Otherwise, you can @code{require} the
+ file before making the binding (@pxref{Named Features}).

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

* Re: void variable
  2004-07-29  7:19                   ` Lars Hansen
@ 2004-07-30  3:21                     ` Luc Teirlinck
  2004-07-30  6:56                       ` Lars Hansen
  0 siblings, 1 reply; 46+ messages in thread
From: Luc Teirlinck @ 2004-07-30  3:21 UTC (permalink / raw)
  Cc: rms, emacs-devel

Lars Hansen wrote:

   However, it confuses me that autoloading of variables is mentioned twice.
   So what about changing

   + If the @code{defvar} or @code{defcustom} itself is autoloaded through
   + a magic comment (@pxref{Autoload}), then there is nothing to worry
   + about: it is already initialized.  Otherwise, there are two ways to
   + prevent trouble.  You can precede the @code{defvar} or
   + @code{defcustom} with a magic comment, or you can @code{require} the
   + file before making the binding (@pxref{Named Features}).

   to

   + If the @code{defvar} or @code{defcustom} itself is autoloaded through
   + a magic comment (@pxref{Autoload}), then there is nothing to worry
   + about: it is already initialized.  Otherwise, you can @code{require} the
   + file before making the binding (@pxref{Named Features}).

I wanted to emphasize that adding an autoload, if it is not already
present, is an acceptable way to deal with the problem.  (Some people
are very reluctant to add autoloads, because they do not like to
increase the size of loaddefs.el)

What about:

    If the @code{defvar} or @code{defcustom} itself is autoloaded through
    a magic comment (@pxref{Autoload}), then there is nothing to worry
    about: it is already initialized.  Thus, adding such a magic comment is
    one way to prevent trouble.  Alternatively, you can @code{require}
    the file before making the binding (@pxref{Named Features}).

Sincerely,

Luc.

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

* Re: void variable
  2004-07-29  2:31                 ` Luc Teirlinck
  2004-07-29  7:19                   ` Lars Hansen
@ 2004-07-30  4:55                   ` Richard Stallman
  1 sibling, 0 replies; 46+ messages in thread
From: Richard Stallman @ 2004-07-30  4:55 UTC (permalink / raw)
  Cc: larsh, emacs-devel

    + If you make a local binding for a variable defined with @code{defvar}
    + or @code{defcustom} in another non-preloaded file, and if anything in
    + the scope of the binding loads that file, for instance through
    + autoloading, then this may fail to properly initialize the variable.

This tries to describe two different problem situations which in
practice occur in different code and when doing different things.

1. Making a variable binding in certain cases.

2. Failing to add an autoload for certain variable definitions.

That they are two ways of looking at the same underlying situation is
beside the point.  Each needs to be treated in the place that relates
to the situation in which it occurs.

Case #2 belongs in the section that describes autoload cookies.  Case
#1 belongs in the section which describes `let'.  This section, about
defvar, is not the right place for either of them.  Although it has a
relation to the issue, and to both cases, this is not the best place
for either of them.

Adding a shorter note to the existing warning at the end of the node
is appropriate, but don't try to do here the jobs that should be done
in other places.

Meanwhile, let's leave this until after the new warning is
implemented.  That will change what we need to say about these cases.
There is no point writing text we will have to change very soon.

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

* Re: void variable
  2004-07-30  3:21                     ` Luc Teirlinck
@ 2004-07-30  6:56                       ` Lars Hansen
  0 siblings, 0 replies; 46+ messages in thread
From: Lars Hansen @ 2004-07-30  6:56 UTC (permalink / raw)
  Cc: rms, emacs-devel

Luc Teirlinck wrote:

>What about:
>
>    If the @code{defvar} or @code{defcustom} itself is autoloaded through
>    a magic comment (@pxref{Autoload}), then there is nothing to worry
>    about: it is already initialized.  Thus, adding such a magic comment is
>    one way to prevent trouble.  Alternatively, you can @code{require}
>    the file before making the binding (@pxref{Named Features}).
>  
>
Yes, that's much more clear!

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

* Re: void variable
  2004-07-28 16:00         ` Richard Stallman
  2004-07-29  2:00           ` Luc Teirlinck
@ 2004-08-19 19:33           ` Stefan Monnier
  2004-08-19 20:12             ` Adrian Aichner
                               ` (4 more replies)
  1 sibling, 5 replies; 46+ messages in thread
From: Stefan Monnier @ 2004-08-19 19:33 UTC (permalink / raw)
  Cc: larsh, Luc Teirlinck, emacs-devel

>     Maybe we could arrange for defvar to burp a warning if the var is
>     currently let-bound?
> That sounds like a good idea.  It should be possible to do this
> by searching the specpdl.

The patch below seems to work well.  Any objection (or suggestion of
a better message)?


        Stefan


--- orig/src/eval.c
+++ mod/src/eval.c
@@ -747,6 +747,20 @@
 	XSYMBOL (sym)->constant = 0;
       if (NILP (tem))
 	Fset_default (sym, Feval (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.  */
+	  struct specbinding *pdl = specpdl_ptr;
+	  while (--pdl >= specpdl)
+	    {
+	      if (!pdl->func && EQ (pdl->symbol, sym) && EQ (pdl->old_value, Qunbound))
+		{
+		  message_with_string ("%s is still globally unbound",
+				       SYMBOL_NAME (sym), 1);
+		  pdl = specpdl; /* Don'tlook further.  */
+		}
+	    }
+	}
       tail = Fcdr (tail);
       tem = Fcar (tail);
       if (!NILP (tem))

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

* Re: void variable
  2004-08-19 19:33           ` Stefan Monnier
@ 2004-08-19 20:12             ` Adrian Aichner
  2004-08-19 20:45             ` Davis Herring
                               ` (3 subsequent siblings)
  4 siblings, 0 replies; 46+ messages in thread
From: Adrian Aichner @ 2004-08-19 20:12 UTC (permalink / raw)


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

> +		  pdl = specpdl; /* Don'tlook further.  */

I just noticed that little typo in "Don'tlook" above.

-- 
Adrian Aichner
 mailto:adrian@xemacs.org
 http://www.xemacs.org/

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

* Re: void variable
  2004-08-19 19:33           ` Stefan Monnier
  2004-08-19 20:12             ` Adrian Aichner
@ 2004-08-19 20:45             ` Davis Herring
  2004-08-20 21:08               ` Richard Stallman
  2004-08-19 21:54             ` Andreas Schwab
                               ` (2 subsequent siblings)
  4 siblings, 1 reply; 46+ messages in thread
From: Davis Herring @ 2004-08-19 20:45 UTC (permalink / raw)


> The patch below seems to work well.  Any objection (or suggestion of
> a better message)?
>         Stefan

It seems to me that it would make even more sense to actually bind the
variable's global value despite any dynamic bindings; this certainly would
be unusual, but even warning about it violates the the usual `let' binding
semantics.

(If this were judged to be a good idea, one could even have
`set[q]-global' that would provide the capacity in general.  Of course, on
that note one could have `makunbound-global' and even `makunbound-default'
to complete the possibilities...)

Of course, there would then be no way to fool a `defvar' if you wanted 
the global variable left unbound, but that seems like an unlikely desire 
(and there's always `makunbound' if you're desperate).

This is all admittedly somewhat insane, so if it's rubbish, here's a 
message idea:

"Can't bind `foo-bar' globally: `let' around `defvar'"

Davis Herring

-- 
This product is sold by volume, not by mass.  If it seems too dense or too 
sparse, it means mass-energy conversion has occurred during shipping.

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

* Re: void variable
  2004-08-19 19:33           ` Stefan Monnier
  2004-08-19 20:12             ` Adrian Aichner
  2004-08-19 20:45             ` Davis Herring
@ 2004-08-19 21:54             ` Andreas Schwab
  2004-08-19 22:20               ` Stefan Monnier
  2004-08-20  1:27             ` Luc Teirlinck
  2004-08-20 21:08             ` Richard Stallman
  4 siblings, 1 reply; 46+ messages in thread
From: Andreas Schwab @ 2004-08-19 21:54 UTC (permalink / raw)
  Cc: larsh, Luc Teirlinck, rms, emacs-devel

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

> --- orig/src/eval.c
> +++ mod/src/eval.c
> @@ -747,6 +747,20 @@
>  	XSYMBOL (sym)->constant = 0;
>        if (NILP (tem))
>  	Fset_default (sym, Feval (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.  */
> +	  struct specbinding *pdl = specpdl_ptr;
> +	  while (--pdl >= specpdl)
> +	    {
> +	      if (!pdl->func && EQ (pdl->symbol, sym) && EQ (pdl->old_value, Qunbound))
> +		{
> +		  message_with_string ("%s is still globally unbound",
> +				       SYMBOL_NAME (sym), 1);
> +		  pdl = specpdl; /* Don'tlook further.  */

What's wrong with break here?

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: void variable
  2004-08-19 21:54             ` Andreas Schwab
@ 2004-08-19 22:20               ` Stefan Monnier
  2004-08-19 22:25                 ` David Kastrup
  0 siblings, 1 reply; 46+ messages in thread
From: Stefan Monnier @ 2004-08-19 22:20 UTC (permalink / raw)
  Cc: larsh, Luc Teirlinck, rms, emacs-devel

>> +		  pdl = specpdl; /* Don'tlook further.  */

> What's wrong with break here?

My head, probably,


        Stefan

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

* Re: void variable
  2004-08-19 22:20               ` Stefan Monnier
@ 2004-08-19 22:25                 ` David Kastrup
  0 siblings, 0 replies; 46+ messages in thread
From: David Kastrup @ 2004-08-19 22:25 UTC (permalink / raw)
  Cc: Andreas Schwab, emacs-devel, Luc Teirlinck, rms, larsh

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

> >> +		  pdl = specpdl; /* Don'tlook further.  */
> 
> > What's wrong with break here?
> 
> My head, probably,

You need a break.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

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

* Re: void variable
  2004-08-19 19:33           ` Stefan Monnier
                               ` (2 preceding siblings ...)
  2004-08-19 21:54             ` Andreas Schwab
@ 2004-08-20  1:27             ` Luc Teirlinck
  2004-08-20 14:54               ` Stefan Monnier
  2004-08-20 21:08             ` Richard Stallman
  4 siblings, 1 reply; 46+ messages in thread
From: Luc Teirlinck @ 2004-08-20  1:27 UTC (permalink / raw)
  Cc: larsh, rms, emacs-devel

Stefan Monnier wrote:

   The patch below seems to work well.  Any objection (or suggestion of
   a better message)?

Of course, `defcustom' has exactly the same problem as `defvar'.  So
doing this for defvar and not defcustom seems inconsistent.  Strictly
speaking, `defconst' also has the same problem, but let-binding a
variable defined with defconst seems very iffy in any circumstances.

The message:  VAR is still globally unbound

looks cryptic.  It makes it seem that there is something wrong with
let-binding a variable that is globally unbound whereas, of course,
that happens all the time.

Davis Herring wrote:

"Can't bind `foo-bar' globally: `let' around `defvar'"

I would prefer:

"Warning: defvar for locally bound `%s' failed to globally define it."

and:

"Warning: defcustom for locally bound `%s' failed to globally define it."

For one thing, local bindings are not always made with `let'.

Anyway, somebody with a reasonably fast machine may only see this when
studying the *Messages* buffer.  It easily can be overwritten by
messages like:

Loading ~/foo.el ...done

Sincerely,

Luc.

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

* Re: void variable
  2004-08-20  1:27             ` Luc Teirlinck
@ 2004-08-20 14:54               ` Stefan Monnier
  2004-08-21 16:49                 ` Richard Stallman
  0 siblings, 1 reply; 46+ messages in thread
From: Stefan Monnier @ 2004-08-20 14:54 UTC (permalink / raw)
  Cc: larsh, rms, emacs-devel

> Of course, `defcustom' has exactly the same problem as `defvar'.  So
> doing this for defvar and not defcustom seems inconsistent.  Strictly

Indeed.  We had already mentioned defcustom, but I'd forgotten about it.
But now that I looked at it, I also see that it's a bit ugly to do
(ideally, defcustom would use defvar internally, but given the way
custom is supposed to work, it's not easy to do).  We'd probably need to
create a new function like `outer-default-boundp' just for that.

> speaking, `defconst' also has the same problem, but let-binding a
> variable defined with defconst seems very iffy in any circumstances.

The situation for defconst is a bit different indeed.
The byte-compiler already warns when we do

   (defconst toto 1)
   (let ((toto 2)) (balbla))

It doesn't do that if the defconst was in another file, tho (because after
the defconst is executed Emacs does not remember whether it was a defconst
or a defvar or a setq).  We could easily add a bit in the symbol to keep
track of which vars are "const" to work around this (my own local Emacs
branch has had that for a while, even making all `defconst'd variables
read-only).

> The message:  VAR is still globally unbound
> looks cryptic.

:-)

> "Can't bind `foo-bar' globally: `let' around `defvar'"
> I would prefer:
> "Warning: defvar for locally bound `%s' failed to globally define it."
[...]
> For one thing, local bindings are not always made with `let'.

I like having `defvar' and `let' in the message.  How about:

   "Warning: defvar ignored because %s is let-bound"

Or maybe "skipped" or "failed" is better than "ignored".

> Anyway, somebody with a reasonably fast machine may only see this when
> studying the *Messages* buffer.  It easily can be overwritten by
> messages like:

Actually I think the problem can show up on a slow machine just as well.
But it's nothing new and is not specific to this particular case.


        Stefan

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

* Re: void variable
  2004-08-19 19:33           ` Stefan Monnier
                               ` (3 preceding siblings ...)
  2004-08-20  1:27             ` Luc Teirlinck
@ 2004-08-20 21:08             ` Richard Stallman
  4 siblings, 0 replies; 46+ messages in thread
From: Richard Stallman @ 2004-08-20 21:08 UTC (permalink / raw)
  Cc: larsh, teirllm, emacs-devel

    The patch below seems to work well.  Any objection (or suggestion of
    a better message)?

It has to say what operation is reporting this message.
Otherwise nobody will understand why they would have expected
it to be otherwise.

So it could be:

   "defvar for %s did not work properly because it was locally bound"

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

* Re: void variable
  2004-08-19 20:45             ` Davis Herring
@ 2004-08-20 21:08               ` Richard Stallman
  2004-08-20 22:08                 ` Stefan Monnier
  0 siblings, 1 reply; 46+ messages in thread
From: Richard Stallman @ 2004-08-20 21:08 UTC (permalink / raw)
  Cc: emacs-devel

    It seems to me that it would make even more sense to actually bind the
    variable's global value despite any dynamic bindings; this certainly would
    be unusual, but even warning about it violates the the usual `let' binding
    semantics.

This might be a good idea.

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

* Re: void variable
  2004-08-20 21:08               ` Richard Stallman
@ 2004-08-20 22:08                 ` Stefan Monnier
  0 siblings, 0 replies; 46+ messages in thread
From: Stefan Monnier @ 2004-08-20 22:08 UTC (permalink / raw)
  Cc: emacs-devel

>     It seems to me that it would make even more sense to actually bind the
>     variable's global value despite any dynamic bindings; this certainly
>     would be unusual, but even warning about it violates the the usual
>     `let' binding semantics.

> This might be a good idea.

I'd rather not try to guess a fixup that way.  Too dangerous.
It's much safer to just report the situation so someone can figure out which
is the right way to fix it.

Or at least if we want to make it set the outer global binding, I suggest we
wait for post-21.4 to do that.


        Stefan

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

* Re: void variable
  2004-08-20 14:54               ` Stefan Monnier
@ 2004-08-21 16:49                 ` Richard Stallman
  0 siblings, 0 replies; 46+ messages in thread
From: Richard Stallman @ 2004-08-21 16:49 UTC (permalink / raw)
  Cc: larsh, teirllm, emacs-devel

      We could easily add a bit in the symbol to keep
    track of which vars are "const" to work around this (my own local Emacs
    branch has had that for a while, even making all `defconst'd variables
    read-only).

That would be reasonable, although what we really should be doing now
is moving towards a release.

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

end of thread, other threads:[~2004-08-21 16:49 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-25  6:32 void variable Lars Hansen
2004-07-25  7:56 ` Adrian Aichner
2004-07-25 19:25 ` Lars Hansen
2004-07-25 20:46   ` Luc Teirlinck
2004-07-25 21:54     ` Lars Hansen
2004-07-25 23:39       ` Luc Teirlinck
2004-07-25 23:54         ` Luc Teirlinck
2004-07-26  1:52       ` Luc Teirlinck
2004-07-26  2:13         ` Luc Teirlinck
2004-07-26 14:30           ` Richard Stallman
2004-07-26 15:12             ` Lars Hansen
2004-07-27 18:18               ` Richard Stallman
2004-07-29  2:31                 ` Luc Teirlinck
2004-07-29  7:19                   ` Lars Hansen
2004-07-30  3:21                     ` Luc Teirlinck
2004-07-30  6:56                       ` Lars Hansen
2004-07-30  4:55                   ` Richard Stallman
2004-07-26 15:21             ` Luc Teirlinck
2004-07-27 18:18               ` Richard Stallman
2004-07-26 16:05             ` Kai Grossjohann
2004-07-26 18:40               ` Lars Hansen
2004-07-27 18:18               ` Richard Stallman
2004-07-26  3:13     ` Richard Stallman
2004-07-26 19:23     ` Stefan Monnier
2004-07-26 19:46       ` Lars Hansen
2004-07-26 19:46       ` David Kastrup
2004-07-26 20:41       ` Luc Teirlinck
2004-07-26 21:13         ` Stefan Monnier
2004-07-27  2:59           ` Luc Teirlinck
2004-07-27  3:07           ` Luc Teirlinck
2004-07-27  3:09           ` Luc Teirlinck
2004-07-28 16:00         ` Richard Stallman
2004-07-29  2:00           ` Luc Teirlinck
2004-08-19 19:33           ` Stefan Monnier
2004-08-19 20:12             ` Adrian Aichner
2004-08-19 20:45             ` Davis Herring
2004-08-20 21:08               ` Richard Stallman
2004-08-20 22:08                 ` Stefan Monnier
2004-08-19 21:54             ` Andreas Schwab
2004-08-19 22:20               ` Stefan Monnier
2004-08-19 22:25                 ` David Kastrup
2004-08-20  1:27             ` Luc Teirlinck
2004-08-20 14:54               ` Stefan Monnier
2004-08-21 16:49                 ` Richard Stallman
2004-08-20 21:08             ` Richard Stallman
2004-07-26  1:29 ` Richard Stallman

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).