all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* defconst
@ 2004-11-14 18:33 Luc Teirlinck
  2004-11-15 14:00 ` defconst Richard Stallman
  0 siblings, 1 reply; 7+ messages in thread
From: Luc Teirlinck @ 2004-11-14 18:33 UTC (permalink / raw)
  Cc: Rob Riepel, Michael Kifer, Kyle Jones

I believe that `defconst' is a relatively widely misused function.  I
believe that it should only be used for something that is an absolute
constant.  Yet people seem to use it for such things as variables that
should only be changed by the user but not by Lisp code, or vice-versa,
or variables that have no effect when changed with setq (but only if a
function is called), and any other of a number of situations where
changing the value of a variable has to be done carefully, or only in
certain situations.

Using `defconst' instead of `defvar' is much more than just a
stylistic error.  If the file gets reloaded, then the defconst, unlike
defvar, will override any changes made thus far in the Elisp session,
behind the user's back.  This can be very confusing to the user.
Thus, it should only be used if _any_ change to the variable in any
way would be wrong.  If in doubt, I believe one should always use defvar.

Maybe `defconst' is OK for version numbers.  They are not necessarily
constants, but if a new version of a package is loaded, the old
version number should indeed be overridden.

I only will handle uses of defconst that produced compiler warnings.
I am afraid that the problem is more widespread.

Compiler warnings are produced by defconsts in the viper package,
cust-print.el, tpu-edt.el, life.el and lao.el.

It appears that the vast majority of the many defconsts in the viper
package should be defvar's.  I hope that the author of viper.el still
maintains the package and can take a look at this.

For the four other files, I will propose concrete changes.

I CC-ed the authors of the viper, tpu-edt and life packages. 


Sincerely,

Luc.

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

* Re: defconst
  2004-11-14 18:33 defconst Luc Teirlinck
@ 2004-11-15 14:00 ` Richard Stallman
  0 siblings, 0 replies; 7+ messages in thread
From: Richard Stallman @ 2004-11-15 14:00 UTC (permalink / raw)
  Cc: riepel, kifer, emacs-devel

Originally I intended defconst for variables that the program should
not change, but the user might.  However, later on we concluded it was
not right to use defconst for these, and that it should be used only
for things that should never change at all.

I am not surprised that it has been misused.

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

* defconst
@ 2004-11-18  0:21 Luc Teirlinck
  2004-11-18  0:36 ` defconst Drew Adams
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Luc Teirlinck @ 2004-11-18  0:21 UTC (permalink / raw)


I wonder what the exact usefulness of defconst, in its present form,
is.  It does two things, one very concrete, the other rather vague
(and therefore not very useful).

The concrete effect of `(defconst var value)' is that it is equivalent
with `(defvar var value)' followed by `(setq var value)', that is, its
concrete effect is that of the CL function `defparameter'.

Apart from that, quoted from `(elisp)Defining Variables':

     This special form defines SYMBOL as a value and initializes it.
     It informs a person reading your code that SYMBOL has a standard
     global value, established here, that should not be changed by the
     user or by other programs.

There are two problems with this.

Firstly, it does not inform everybody that needs to be informed.  It
informs the person reading the defconst directly, and the person
writing Elisp code, _who compiles and pays attention to compiler
warnings_, through a compiler warning.  It does not inform the user
who changes the value in his .emacs or interactively that he is doing
something that may have adverse consequences.  It does not inform the
`C-h v' user.

Secondly, one can not rely on what the information concretely means.
Many people use defconst just because they do not consider it _very
likely_ that somebody might want to change the value of the variable.

I believe it would be better if `defconst' behaved like `defconstant'
in CLISP: throw an error if the user or a program tries to change the
value through anything else but a second defconst.  If a second
defconst resets the "constant" to a different value, give a warning,
but change the constant's value anyway.  Do not warn about a defconst
that keeps the value the same.  (Note that this is CLISP specific
behavior.  CL leaves most of the `defconstant' behavior up to the
implementation.)

This way, everybody who tries to change the value gets informed of the
fact that it might cause trouble and still gets the chance to do it
anyway (but knowing the risk).  It would allow programmers seeing a
defconst to rely on the fact that the value they see in the defconst
is the value they will get if they evaluate the symbol.  Currently,
they can not do that.  `defconst' would produce something `read-only'
which it currently does not.

Maybe it might not be advisable to make such a change before the
release, but what about after it?  I bring it up now, because a
decision on this might affect what we do with current defconst's.

Sincerely,

Luc.








 LocalWords:  defconst's

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

* RE: defconst
  2004-11-18  0:21 defconst Luc Teirlinck
@ 2004-11-18  0:36 ` Drew Adams
  2004-11-18  1:17 ` defconst Stefan
  2004-11-19  2:25 ` defconst Richard Stallman
  2 siblings, 0 replies; 7+ messages in thread
From: Drew Adams @ 2004-11-18  0:36 UTC (permalink / raw)


    The concrete effect of `(defconst var value)' is that it is equivalent
    with `(defvar var value)' followed by `(setq var value)'

Just a nit-picking reminder:

The example you gave, without doc strings, is correct. However, in general,
defconst is not exactly the same as defvar followed by setq. Like defvar,
defconst lets you change the doc string, as well as the value.

  - Drew

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

* Re: defconst
  2004-11-18  0:21 defconst Luc Teirlinck
  2004-11-18  0:36 ` defconst Drew Adams
@ 2004-11-18  1:17 ` Stefan
  2004-11-19  2:25 ` defconst Richard Stallman
  2 siblings, 0 replies; 7+ messages in thread
From: Stefan @ 2004-11-18  1:17 UTC (permalink / raw)
  Cc: emacs-devel

> I believe it would be better if `defconst' behaved like `defconstant'
> in CLISP: throw an error if the user or a program tries to change the
> value through anything else but a second defconst.

I obviously agree since that's what my local Emacs does ;-)

> Maybe it might not be advisable to make such a change before the
> release, but what about after it?  I bring it up now, because a
> decision on this might affect what we do with current defconst's.

I haven't pushed for such a thing (other than by adding a byte-compiler
warning and by installing patches to fix the problems I encounter) because
it creates a backward incompatibility without much immediate benefit.


        Stefan

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

* Re: defconst
  2004-11-18  0:21 defconst Luc Teirlinck
  2004-11-18  0:36 ` defconst Drew Adams
  2004-11-18  1:17 ` defconst Stefan
@ 2004-11-19  2:25 ` Richard Stallman
  2004-11-20  1:25   ` defconst Luc Teirlinck
  2 siblings, 1 reply; 7+ messages in thread
From: Richard Stallman @ 2004-11-19  2:25 UTC (permalink / raw)
  Cc: emacs-devel

    I believe it would be better if `defconst' behaved like `defconstant'
    in CLISP: throw an error if the user or a program tries to change the
    value through anything else but a second defconst.

That is a drastic change, and I see no need for it.  Practically
speaking, nothing disastrous happens if you change it with setq.
There is no need to make it an error.  So I will not change this.

Please don't suggest such major changes now.  Our goal now is to aim
for a release.

Please let's direct effort at checking the documentation and fixing
the bugs listed in FOR-RELEASE, so we can have a release.

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

* Re: defconst
  2004-11-19  2:25 ` defconst Richard Stallman
@ 2004-11-20  1:25   ` Luc Teirlinck
  0 siblings, 0 replies; 7+ messages in thread
From: Luc Teirlinck @ 2004-11-20  1:25 UTC (permalink / raw)


(I forgot to include a CC to emacs-devel in a previous version of
this message.)

Richard Stallman wrote:
   
   Please don't suggest such major changes now.  Our goal now is to aim
   for a release.

In my message I very explicitly stated that I only suggested making
this change _after the release_.  I only wanted to know now whether
doing that was a possibility, in order to better know how to deal with
present defconst's.

       I believe it would be better if `defconst' behaved like `defconstant'
       in CLISP: throw an error if the user or a program tries to change the
       value through anything else but a second defconst.

   That is a drastic change, and I see no need for it.  Practically
   speaking, nothing disastrous happens if you change it with setq.

If the user changes a variable defined with defconst then the new
value can be overridden at any time without notice to the user.  That
is a dangerous situation and disastrous things _could_ happen,
depending on what variable is being played around with.

What about the following changes to lispref/variables.texi and the
docstring of `defconst' that add appropriate warnings about this
dangerous situation.

===File ~/variables.texi-diff===============================
*** variables.texi	19 Nov 2004 18:35:43 -0600	1.52
- --- variables.texi	19 Nov 2004 18:40:04 -0600	
***************
*** 415,423 ****
  a matter of intent, serving to inform human readers of whether the value
  should ever change.  Emacs Lisp does not restrict the ways in which a
  variable can be used based on @code{defconst} or @code{defvar}
! declarations.  However, it does make a difference for initialization:
! @code{defconst} unconditionally initializes the variable, while
! @code{defvar} initializes it only if it is void.
  
  @ignore
    One would expect user option variables to be defined with
- --- 415,431 ----
  a matter of intent, serving to inform human readers of whether the value
  should ever change.  Emacs Lisp does not restrict the ways in which a
  variable can be used based on @code{defconst} or @code{defvar}
! declarations (although it would be very inadvisable to change the
! value of a variable defined with @code{defconst}).  However, it does
! make a difference for initialization: @code{defconst} unconditionally
! initializes the variable, while @code{defvar} initializes it only if
! it is void.
! 
!   You should @strong{only} use @code{defconst} if you are absolutely
! sure that no user will ever want to change the value for any reason.
! If there is the slightest doubt about that, use @code{defvar}.
! Indeed, files can be loaded at unpredictable times and @code{defconst}
! would override the user's value behind his back.
  
  @ignore
    One would expect user option variables to be defined with
***************
*** 539,545 ****
  
  Here, @code{pi} is a constant that presumably ought not to be changed
  by anyone (attempts by the Indiana State Legislature notwithstanding).
! As the second form illustrates, however, this is only advisory.
  
  @example
  @group
- --- 547,555 ----
  
  Here, @code{pi} is a constant that presumably ought not to be changed
  by anyone (attempts by the Indiana State Legislature notwithstanding).
! As the second form illustrates, however, this is not enforced (but one
! should @emph{never} change the value of a variable defined by defconst
! regardless).
  
  @example
  @group
============================================================

===File ~/eval.c-diff=======================================
*** eval.c	06 Nov 2004 09:07:09 -0600	1.224
- --- eval.c	19 Nov 2004 19:12:17 -0600	
***************
*** 816,821 ****
- --- 816,828 ----
  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.
+ 
+ It is very important to *only* use this form if you are *absolutely*
+ sure that no user will ever want to change the value for any reason.
+ If there is the slightest doubt about that, use `defvar'.  Indeed,
+ files can be loaded at unpredictable times and this form would
+ override the user's value behind his back.
+ 
  usage: (defconst SYMBOL INITVALUE [DOCSTRING])  */)
       (args)
       Lisp_Object args;
============================================================
------- End of forwarded message -------

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

end of thread, other threads:[~2004-11-20  1:25 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-18  0:21 defconst Luc Teirlinck
2004-11-18  0:36 ` defconst Drew Adams
2004-11-18  1:17 ` defconst Stefan
2004-11-19  2:25 ` defconst Richard Stallman
2004-11-20  1:25   ` defconst Luc Teirlinck
  -- strict thread matches above, loose matches on Subject: below --
2004-11-14 18:33 defconst Luc Teirlinck
2004-11-15 14:00 ` defconst Richard Stallman

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.