unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* defcustom: changing from defvar - order of execution
@ 2005-05-03 15:50 Drew Adams
  2005-05-03 16:13 ` Drew Adams
       [not found] ` <mailman.3227.1115174847.2819.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-03 15:50 UTC (permalink / raw)


I'm unclear on the recommended way to change Lisp code from using defvar for
user options to using defcustom. I guess I'm also unclear on just how
defcustom and Customize work. I couldn't find an explanation of this in Info
for Emacs or Emacs Lisp.

Initial setup - library foo.el has this:

 (defvar foovar nil)
 (defun foo-fn () foovar)

Initial setup - user has this in .emacs:

 (defvar foovar t)
 (load-library "foo")
 (foo-fn)

When .emacs is loaded, (foo-fn) is executed, foovar is `t', so (foo-fn)
returns `t'.


Second setup - library foo.el has this:

 (defcustom foovar nil)
 (defun foo-fn () foovar)

Second setup - user has this in .emacs, after customizing foovar to `t' with
Customize:

 (load-library "foo")
 (foo-fn)
 ...
 (custom-set-variables '(foovar t)...)

When .emacs is loaded, (foo-fn) is executed, foovar is (has default value)
`nil', so (foo-fn) returns `nil'.

That is, because (custom-set-variables...) is executed after (foo-fn), it
has no effect during foo-fn's execution.

What am I missing/confusing here? What is the proper way for library foo.el
to move from using defvar to using defcustom? Also, what difference does it
make, if any, whether a defcustom is executed at the top level or a lower
level of a file.

Thanks. - Drew

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

* RE: defcustom: changing from defvar - order of execution
  2005-05-03 15:50 Drew Adams
@ 2005-05-03 16:13 ` Drew Adams
       [not found] ` <mailman.3227.1115174847.2819.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-03 16:13 UTC (permalink / raw)


Oops - before someone gripes about users using defvar for variables that are
defined in libraries, let me change the initial user setup from this:

     (defvar foovar t)
     (load-library "foo")
     (foo-fn)

to this:

     (setq foovar t)
     (load-library "foo")
     (foo-fn)

I don't think it changes my overall question, in any case. Thanks. - Drew



    -----Original Message-----
    I'm unclear on the recommended way to change Lisp code from
    using defvar for user options to using defcustom. I guess I'm
    also unclear on just how defcustom and Customize work. I
    couldn't find an explanation of this in Info for Emacs or Emacs Lisp.

    Initial setup - library foo.el has this:

     (defvar foovar nil)
     (defun foo-fn () foovar)

    Initial setup - user has this in .emacs:

     (defvar foovar t)
     (load-library "foo")
     (foo-fn)

    When .emacs is loaded, (foo-fn) is executed, foovar is `t', so
    (foo-fn) returns `t'.


    Second setup - library foo.el has this:

     (defcustom foovar nil)
     (defun foo-fn () foovar)

    Second setup - user has this in .emacs, after customizing
    foovar to `t' with Customize:

     (load-library "foo")
     (foo-fn)
     ...
     (custom-set-variables '(foovar t)...)

    When .emacs is loaded, (foo-fn) is executed, foovar is (has
    default value) `nil', so (foo-fn) returns `nil'.

    That is, because (custom-set-variables...) is executed after
    (foo-fn), it has no effect during foo-fn's execution.

    What am I missing/confusing here? What is the proper way for
    library foo.el to move from using defvar to using defcustom?
    Also, what difference does it make, if any, whether a defcustom
    is executed at the top level or a lower level of a file.

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

* Re: defcustom: changing from defvar - order of execution
       [not found] ` <mailman.3227.1115174847.2819.help-gnu-emacs@gnu.org>
@ 2005-05-04 15:03   ` Stefan Monnier
  2005-05-04 22:49     ` Drew Adams
  2005-05-04 15:51   ` rgb
  1 sibling, 1 reply; 17+ messages in thread
From: Stefan Monnier @ 2005-05-04 15:03 UTC (permalink / raw)


>     Second setup - library foo.el has this:

>      (defcustom foovar nil)
>      (defun foo-fn () foovar)

>     Second setup - user has this in .emacs, after customizing
>     foovar to `t' with Customize:

>      (load-library "foo")
>      (foo-fn)
>      ...
>      (custom-set-variables '(foovar t)...)

>     When .emacs is loaded, (foo-fn) is executed, foovar is (has
>     default value) `nil', so (foo-fn) returns `nil'.

You're comparing two different elisp package code and two different .emacs
code.  Try to separate those two cases; it will help you understand
the problem.

E.g. changing the elisp package to use defcustom, but without the user
changing her .emacs will not result in any problem.

The problem comes when the user replaces her "setq at the beginning" with
a "custom-set-var at the end".

It's only weakly related to the use of custom since the same behavior
appears if you move the setq, or if you move the custom-set-var.


        Stefan

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

* Re: defcustom: changing from defvar - order of execution
       [not found] ` <mailman.3227.1115174847.2819.help-gnu-emacs@gnu.org>
  2005-05-04 15:03   ` Stefan Monnier
@ 2005-05-04 15:51   ` rgb
  2005-05-04 22:49     ` Drew Adams
  1 sibling, 1 reply; 17+ messages in thread
From: rgb @ 2005-05-04 15:51 UTC (permalink / raw)


> I'm unclear on the recommended way to change Lisp code from
> using defvar for user options to using defcustom. I guess I'm
> also unclear on just how defcustom and Customize work. I
> couldn't find an explanation of this in Info for Emacs or Emacs Lisp.
>
It appears that defcustom acts just like defvar and
custom-set-variables acts much like setq.
So the position of your load command, with respect to the
custom-set-variables section is unimportant.
Obviously the position of your call to foo-fn IS important.

In my .emacs nothing comes before custom-set-variables.
But I notice that if the section doesn't already exist
it gets added at the end rather than the beginning.
I question the logic behind that.  Especially considering
the existence of options like :require and :set-after which
make the need for anything before it unlikely.
At least it doesn't move if it's present so you can put it
where you want and it will stay.

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

* RE: defcustom: changing from defvar - order of execution
  2005-05-04 15:51   ` rgb
@ 2005-05-04 22:49     ` Drew Adams
  0 siblings, 0 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-04 22:49 UTC (permalink / raw)


    It appears that defcustom acts just like defvar and
    custom-set-variables acts much like setq.

Yes, wrt setting the value.

    So the position of your load command, with respect to the
    custom-set-variables section is unimportant.

Right, if the user uses setq. In my initial email the user used defvar,
which only takes effect if done before the load (with its own defvar or
defcustom).

    Obviously the position of your call to foo-fn IS important.

    In my .emacs nothing comes before custom-set-variables.
    But I notice that if the section doesn't already exist
    it gets added at the end rather than the beginning.
    I question the logic behind that.  Especially considering
    the existence of options like :require and :set-after which
    make the need for anything before it unlikely.
    At least it doesn't move if it's present so you can put it
    where you want and it will stay.

Yes, I am referring to the placement in .emacs, by Customize, of
custom-set-variables. Obviously, a user can reposition that at will, but, a
priori, a user will just let Customize place it, and it will be placed at
the end, after the load-library.

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

* RE: defcustom: changing from defvar - order of execution
  2005-05-04 15:03   ` Stefan Monnier
@ 2005-05-04 22:49     ` Drew Adams
  0 siblings, 0 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-04 22:49 UTC (permalink / raw)


    You're comparing two different elisp package code and two
    different .emacs code.  Try to separate those two cases;...

    E.g. changing the elisp package to use defcustom, but without the user
    changing her .emacs will not result in any problem.
    The problem comes when the user replaces her "setq at the
    beginning" with a "custom-set-var at the end".

    It's only weakly related to the use of custom since the same behavior
    appears if you move the setq, or if you move the custom-set-var.

Let me try to be clearer.

The only differences are these:

 - the library in setup #1 uses defvar;
   the library in setup #2 uses defcustom

 - the user in setup #1 uses setq at the beginning;
   the user in setup #2 customizes the variable using Customize,
   which adds (custom-set-variables...) at the end of .emacs

The user in setup #2 has never used the library, let's say (and so, does not
have the setq in .emacs). The user knows nothing about setq and Lisp; he
just copies the text "(load-library "foo")(foo-fn)", per the library
comments, to his .emacs. He fires up Emacs, and then uses Customize to set
and save foovar. This causes (custom-set-variables...) to be added to the
end of his .emacs - after the load-library and the call to foo-fn.

The user is then surprised to find that the customization had no effect: in
subsequent Emacs sessions, load-library does the defcustom, which sets
foovar to nil; and foo-fn then executes with foovar=nil, returning `t'.

What am I missing?

I'm not trying to suggest something is wrong with Emacs (e.g. Customization)
here, I'm just wondering how to use defcustom so that users can customize
things. Telling them that they need to either use setq or to move the
custom-set-variables form that Customize inserts at the end of .emacs seems
the wrong way to proceed. I assume that I must be doing something wrong wrt
the library definition, that if I do things correctly there should be no
such problem. So, what am I missing here?

Thanks,

  Drew

--- my original message ---

    I'm unclear on the recommended way to change Lisp code from
    using defvar for user options to using defcustom. I guess I'm
    also unclear on just how defcustom and Customize work. I
    couldn't find an explanation of this in Info for Emacs or Emacs Lisp.

    Initial setup - library foo.el has this:

     (defvar foovar nil)
     (defun foo-fn () foovar)

    Initial setup - user has this in .emacs:

     (defvar foovar t)
     (load-library "foo")
     (foo-fn)

    When .emacs is loaded, (foo-fn) is executed, foovar is `t', so
    (foo-fn) returns `t'.


    Second setup - library foo.el has this:

     (defcustom foovar nil)
     (defun foo-fn () foovar)

    Second setup - user has this in .emacs, after customizing
    foovar to `t' with Customize:

     (load-library "foo")
     (foo-fn)
     ...
     (custom-set-variables '(foovar t)...)

    When .emacs is loaded, (foo-fn) is executed, foovar is (has
    default value) `nil', so (foo-fn) returns `nil'.

    That is, because (custom-set-variables...) is executed after
    (foo-fn), it has no effect during foo-fn's execution.

    What am I missing/confusing here? What is the proper way for
    library foo.el to move from using defvar to using defcustom?
    Also, what difference does it make, if any, whether a defcustom
    is executed at the top level or a lower level of a file.

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

* Re: defcustom: changing from defvar - order of execution
       [not found] <mailman.3356.1115247555.2819.help-gnu-emacs@gnu.org>
@ 2005-05-06  3:20 ` Stefan Monnier
  2005-05-06 17:00   ` Drew Adams
  0 siblings, 1 reply; 17+ messages in thread
From: Stefan Monnier @ 2005-05-06  3:20 UTC (permalink / raw)


> The user in setup #2 has never used the library, let's say (and so, does not
> have the setq in .emacs). The user knows nothing about setq and Lisp; he
> just copies the text "(load-library "foo")(foo-fn)", per the library
> comments, to his .emacs. He fires up Emacs, and then uses Customize to set
> and save foovar. This causes (custom-set-variables...) to be added to the
> end of his .emacs - after the load-library and the call to foo-fn.

> The user is then surprised to find that the customization had no effect: in
> subsequent Emacs sessions, load-library does the defcustom, which sets
> foovar to nil; and foo-fn then executes with foovar=nil, returning `t'.

> What am I missing?

That this situation you describe is just a bug in the elisp library.
Most likely in the comment that suggests "(load-library "foo")(foo-fn)",
but it's hard to say without more info.
In any case the scenario you describe doesn't seem to be common.


        Stefan

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

* RE: defcustom: changing from defvar - order of execution
  2005-05-06  3:20 ` Stefan Monnier
@ 2005-05-06 17:00   ` Drew Adams
  0 siblings, 0 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-06 17:00 UTC (permalink / raw)


    > The user in setup #2 has never used the library, let's say
    (and so, does not
    > have the setq in .emacs). The user knows nothing about setq
    and Lisp; he
    > just copies the text "(load-library "foo")(foo-fn)", per the library
    > comments, to his .emacs. He fires up Emacs, and then uses
    Customize to set
    > and save foovar. This causes (custom-set-variables...) to be
    added to the
    > end of his .emacs - after the load-library and the call to foo-fn.

    > The user is then surprised to find that the customization had
    no effect: in
    > subsequent Emacs sessions, load-library does the defcustom, which sets
    > foovar to nil; and foo-fn then executes with foovar=nil,
    returning `t'.

    > What am I missing?

    That this situation you describe is just a bug in the elisp library.
    Most likely in the comment that suggests "(load-library "foo")(foo-fn)",
    but it's hard to say without more info.
    In any case the scenario you describe doesn't seem to be common.

Dunno if it's a bug, but it certainly does not seem that _uncommon_. In my
example scenario, the user puts "(load-library "foo")(foo-fn)" in his
.emacs, but the problem arises, in particular, when library foo itself calls
`foo-fn' (or otherwise references `foovar') at the _top level_. That may not
be good practice (?), but it is not uncommon, and I'm not sure what the
proper fix is.

I see things like this fairly commonly, at the top level of the standard
Emacs libraries:

  (defcustom align-load-hook nil
    "*Hook that gets run after the aligner has been loaded."
    :type 'hook
    :group 'align)

  (run-hooks 'align-load-hook)

That is, I see code that: 1) does a defcustom and then 2) uses the value of
that user variable at the _top level_ of the same library (not just inside a
defun). Loading the library uses the value of the variable defined in the
file (unless the variable is somehow set earlier).

In this case, it looks to me like `align-load-hook' will be nil when
`run-hooks' is evaluated, unless the user somehow sets `align-load-hook'
_before_ this library is loaded. Having custom-set-variables set the
variable at the end of the user's .emacs will be too late, if the user loads
this library before that.

Here's another example:

  (defcustom apropos-symbol-face 'bold
    "*Face for symbol name in Apropos output, or nil for none."
    :group 'apropos
    :type 'face)

  (define-button-type 'apropos-symbol
    'face apropos-symbol-face
    'help-echo "mouse-2, RET: Display more help on this symbol"
    'follow-link t
    'action #'apropos-symbol-button-display-help
    'skip t)

In this case, `apropos-symbol-face' will be `bold' when define-button-type
is run, unless the user somehow sets `apropos-symbol-face' _before_ this
library is loaded. (This code cannot just be an old throw-back, because
`define-button-type' is a new function.)

Here's another example:

  (defcustom mouse-avoidance-mode nil...)
  (if mouse-avoidance-mode
      (mouse-avoidance-mode mouse-avoidance-mode))

Here's another example:

  (defcustom calculator-use-menu t ...)
  (or calculator-mode-map
      ...
      (if (and calculator-use-menu ...

These examples are taken from just the first few standard Elisp libraries,
sorted alphabetically. I could go on, but you get the idea.

How is the user's customization (via Customize) taken into account in such
cases, if the custom-set-variables form is inserted at the _end_ of his
.emacs or custom-file? It looks to me like the _library_ (default) values of
such variables, not the user's customized values, will be used in the
library.

To me, it makes sense to generally avoid using user options at the top level
of the library that defines them, but I'm not sure such avoidance is always
feasible. In any case, as the above examples show, the standard libraries
are themselves full of counter examples.

No doubt I'm still missing something - please help me understand. I want to
fix the "bug in the elisp library" in question, but I don't know how to
proceed. I want a user to be able to just load the library and go - not have
to execute foo-fn interactively, but I want the library to take the user's
customized value of foovar into account.

Thanks,

  Drew

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

* Re: defcustom: changing from defvar - order of execution
       [not found] <mailman.3763.1115399076.2819.help-gnu-emacs@gnu.org>
@ 2005-05-06 17:38 ` Stefan Monnier
  2005-05-06 18:19   ` Drew Adams
  2005-05-10 16:14 ` Per Abrahamsen
  1 sibling, 1 reply; 17+ messages in thread
From: Stefan Monnier @ 2005-05-06 17:38 UTC (permalink / raw)


> I see things like this fairly commonly, at the top level of the standard
> Emacs libraries:

All these examples don't seem relevant since nowhere is it suggested to the
user to load the library in her .emacs.

> To me, it makes sense to generally avoid using user options at the top level
> of the library that defines them, but I'm not sure such avoidance is always
> feasible. In any case, as the above examples show, the standard libraries
> are themselves full of counter examples.

What makes more sense is to discourage loading of packages in .emacs.
Instead users should only set vars, setup autoloads, ...

> No doubt I'm still missing something - please help me understand. I want to
> fix the "bug in the elisp library" in question, but I don't know how to
> proceed. I want a user to be able to just load the library and go

Why would she need to load the library?


        Stefan

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

* RE: defcustom: changing from defvar - order of execution
  2005-05-06 17:38 ` Stefan Monnier
@ 2005-05-06 18:19   ` Drew Adams
  0 siblings, 0 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-06 18:19 UTC (permalink / raw)


    > I see things like this fairly commonly, at the top level of
    the standard
    > Emacs libraries:

    All these examples don't seem relevant since nowhere is it
    suggested to the user to load the library in her .emacs.

Fair enough. But if a user does end up loading such a library during startup
(i.e. via .emacs) - whether by autoload or explicit load, the problem
arises, no?

    > To me, it makes sense to generally avoid using user options
    at the top level
    > of the library that defines them, but I'm not sure such
    avoidance is always
    > feasible.

    What makes more sense is to discourage loading of packages in .emacs.
    Instead users should only set vars, setup autoloads, ...

Granted, but what if a user wants to systematically do something at startup
that is provided by a library? Autoload etc. are fine, but what if the user
wants to call a library-defined function at each startup? Whether it's a
command to show daily appointments or whatever...

Users do sometimes call functions at top level in their .emacs; those
functions are sometimes defined by libraries that are loaded by the .emacs
(whether via autoload, require, or load-library); and the called functions
sometimes depend on user options defined in those same libraries. Is this
just "bad practice" on the part of users?

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

* Re: defcustom: changing from defvar - order of execution
       [not found] <mailman.3782.1115404280.2819.help-gnu-emacs@gnu.org>
@ 2005-05-07 15:56 ` Stefan Monnier
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Monnier @ 2005-05-07 15:56 UTC (permalink / raw)


>> I see things like this fairly commonly, at the top level of the standard
>> Emacs libraries:

>     All these examples don't seem relevant since nowhere is it
>     suggested to the user to load the library in her .emacs.

> Fair enough. But if a user does end up loading such a library during startup
> (i.e. via .emacs) - whether by autoload or explicit load, the problem
> arises, no?

Could be, but I haven't seen it mentioned very often so it doesn't seem to
be a common problem.  Probably because it requires that people edit their
.emacs by hand.  I think there are 3 common safe scenarios:
1 - for everything relating to package FOO the user uses only Custom.
2 - for everything relating to package FOO the user doesn't use Custom and
    does all the configuration by hand in her .emacs.
3 - the user mixes up the two, but is aware that the relative position of
    the manual customizations and of the custom-set-variables is important.

The only dangerous case is when the user mixes Custom and manual .emacs
editing and doesn't pay attention to the relative position of the two styles
of customization.

> Granted, but what if a user wants to systematically do something at startup
> that is provided by a library? Autoload etc. are fine, but what if the user
> wants to call a library-defined function at each startup? Whether it's a
> command to show daily appointments or whatever...

Then she'll put it at the end of her .emacs because otherwise other
customizations will be missing.  Duh!

Every once in a while someone comes here with exactly this problem, where
she put her (desktop-load-default) at the beginning of her .emacs instead of
putting it at the end.

There's really not much we can do, and this problem is not directly related
to Custom since it occurs with other things as well.


        Stefan

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

* Re: defcustom: changing from defvar - order of execution
       [not found] <mailman.3763.1115399076.2819.help-gnu-emacs@gnu.org>
  2005-05-06 17:38 ` Stefan Monnier
@ 2005-05-10 16:14 ` Per Abrahamsen
  2005-05-10 18:32   ` Drew Adams
  1 sibling, 1 reply; 17+ messages in thread
From: Per Abrahamsen @ 2005-05-10 16:14 UTC (permalink / raw)


"Drew Adams" <drew.adams@oracle.com> writes:

>   (defcustom align-load-hook nil
>     "*Hook that gets run after the aligner has been loaded."
>     :type 'hook
>     :group 'align)
>
>   (run-hooks 'align-load-hook)

Load hooks are rather special, and shouldn't be declared with
defcustom.  Anyone using a load hook should be comfortable with Emacs
Lisp.

> Here's another example:
>
>   (defcustom apropos-symbol-face 'bold
>     "*Face for symbol name in Apropos output, or nil for none."
>     :group 'apropos
>     :type 'face)
>
>   (define-button-type 'apropos-symbol
>     'face apropos-symbol-face
>     'help-echo "mouse-2, RET: Display more help on this symbol"
>     'follow-link t
>     'action #'apropos-symbol-button-display-help
>     'skip t)

Problematic in any case, since changing apropos-symbol-face from
customize will have no immidiate effect.  It would be better to have
apropos-symbol-face being an actual face, inheriting from bold.  But
because face inheritance wasn't in Emacs 19.0, Emacs is very
incosistent about when to use faces, and when to use variables
containing faces.  Also in new code, since bad habbits don't die
easily. 

>   (defcustom mouse-avoidance-mode nil...)
>   (if mouse-avoidance-mode
>       (mouse-avoidance-mode mouse-avoidance-mode))

Is there a :set in the defcustom?  Global minor mode variables should
have one, so changing the variable from customize will turn the minor
mode on or off.  This will also solve the initialization order problem
(with the risk of doing some unnecessary work).

> Here's another example:
>
>   (defcustom calculator-use-menu t ...)
>   (or calculator-mode-map
>       ...
>       (if (and calculator-use-menu ...

calculator-use-menu should be a global minor mode, see above.

> These examples are taken from just the first few standard Elisp libraries,
> sorted alphabetically. I could go on, but you get the idea.

As you see, the answer depends on the example.  But a common answer is
that if you need to depend on a user variable in the initialization,
the user variable should have a :set that undo the effect if the user
change it.

> How is the user's customization (via Customize) taken into account in such
> cases, if the custom-set-variables form is inserted at the _end_ of his
> .emacs or custom-file? It looks to me like the _library_ (default) values of
> such variables, not the user's customized values, will be used in the
> library.

The location in the .emacs file is just exposing the problem to more,
in all cases the problem would show up if the library was loaded from
the site initialization file, or even dumped with Emacs.

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

* RE: defcustom: changing from defvar - order of execution
  2005-05-10 16:14 ` Per Abrahamsen
@ 2005-05-10 18:32   ` Drew Adams
  0 siblings, 0 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-10 18:32 UTC (permalink / raw)


Per Abrahamsen said:

    Load hooks ... shouldn't be declared with defcustom.
    ...
    Emacs is very incosistent about when to use faces [vs variables]
    ...
    calculator-use-menu should be a global minor mode

OK, I guess the standard libraries need a bit of cleanup in this regard.
These samples came from just the first few files. I know that Luc Teirlinck
already pointed out in emacs-devel that defcustoms for hooks were
problematic, and that there will perhaps be an effort to clean up such stuff
after release 23.

    As you see, the answer depends on the example.  But a common
    answer is that if you need to depend on a user variable in the
    initialization, the user variable should have a :set that undo
    the effect if the user change it.

Thanks; that guideline makes things a bit clearer. However, such use of :set
seems complex to me (perhaps just because I'm not yet used to it). I need to
look more at how it's used.

    The location in the .emacs file is just exposing the problem to
    more, in all cases the problem would show up if the library was
    loaded from the site initialization file, or even dumped

Yes. That's part of what I meant.

To come back to my original example, I guess the thing to do is this:

 - Ensure that libraries make no use of user options at the top level. IOW,
always encapsulate such use inside defun's (e.g. `foo-fn').

 - Tell the user (e.g. in library comments) that to use `foo-fn' at startup
it must be called *after* `custom-set-variables', not before:

     (load-library "foo")
     ...
     (custom-set-variables '(foovar t)...)
     ...
     (foo-fn)

-----------------------

The rest of this email is about the first of these guidelines, and it might
be somewhat off-topic for help-gnu-emacs.

I noticed that RMS said this recently in emacs-devel:

    Just loading appt.el probably should not activate the feature.
    In the 90s it was not unusual for packages to work that way,
    but when Custom was added it became common for a package to be
    loaded simply because someone wanted to customize a variable.
    So our convention, since then, is that just loading a package
    shouldn't really change anything.

Not only was this common in standard libraries before this century, but it
is still common for personal "libraries" - that is, .emacs and its
extensions. It is normal for the latter, IMO, as long as they don't contain
defcustom's.

I said this in emacs-devel on Feb 8:

    I hope and expect that (beyond the bugs) few
    libraries will ever need to change user options, at least
    not by simply being loaded. Most will a) define standard
    values for options or b) provide commands to set options
    or c) behave themselves properly by modifying only
    non-user-option variables.

    I should make a distinction here - there are libraries
    and libraries. There are libraries that are intended for
    use by multiple users, and there are libraries that are
    essentially custom files or personal extensions thereof.
    Multi-user libraries are the ones that should not step on
    user options. Personal libraries are made to set user options.

    Some libraries start out life as a personal library and
    end up being shared to some extent by others. In
    some cases, user-option settings in a library shared this
    way are not bothersome - if the person using the library has
    the same environment and wants to do the same thing, for
    instance. This is essentially just cutting and pasting code.

    In general, however, a library destined for multiple users
    should not contain user-option settings - that is bad form.

That is, some "libraries" are, in effect, .emacs settings (setq...) and
startup code that have been relegated to one or more separate files loaded
at startup. Lots of users do that, to help them organize their settings. (A
common use is to deal with different settings for different platforms.)

It might make sense to have a standard, recognizable (textual) way to
distinguish these two types of emacs-lisp files ("libraries"), so users (and
tools) could more easily apply the different kinds of guidelines to them.

A first step, I think, is recognizing the different kinds of file and
establishing clear guidelines for each. In particular, their treatment wrt
customize is likely to be quite different. For example:

 1) std library: defcustom, defun, etc. only - no top-level setq or function
calls etc.
 2) personal startup library: top-level function calls, setq etc. Executed
after custom-set-variables, usually.

Coming up with such guidelines would also help people migrate a personal
library to become a clean multi-user library. A complete set of such
guidelines would include heuristics, such as the :set rule Per mentioned,
for dealing with customize.

It is, I guess, thanks to the introduction of customize that the standard
libraries are being forced to become cleaner wrt initializing and activating
things. And customize considerations are driving the separation in form
between standard libraries and personal startup libraries. Things that were
commonly done in both a few years ago are now appropriate only for one or
the other.

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

* Re: defcustom: changing from defvar - order of execution
       [not found] <mailman.4474.1115750087.2819.help-gnu-emacs@gnu.org>
@ 2005-05-11 14:07 ` Stefan Monnier
  2005-05-11 16:36   ` Drew Adams
  2005-05-11 16:37   ` Drew Adams
  0 siblings, 2 replies; 17+ messages in thread
From: Stefan Monnier @ 2005-05-11 14:07 UTC (permalink / raw)


> Not only was this common in standard libraries before this century, but it
> is still common for personal "libraries" - that is, .emacs and its
> extensions. It is normal for the latter, IMO, as long as they don't contain

.emacs and its extensions are not libraries.  Extending the meaning of
libraries to things like .emacs makes the word useless.


        Stefan

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

* RE: defcustom: changing from defvar - order of execution
  2005-05-11 14:07 ` Stefan Monnier
@ 2005-05-11 16:36   ` Drew Adams
  2005-05-11 16:37   ` Drew Adams
  1 sibling, 0 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-11 16:36 UTC (permalink / raw)


    > Not only was this common in standard libraries before this
    > century, but it is still common for personal "libraries" -
    > that is, .emacs and its extensions.

    .emacs and its extensions are not libraries.  Extending the meaning of
    libraries to things like .emacs makes the word useless.

OK. What's a better term?

Use whatever term you like. I think I made clear what I was talking about. I
referred to them as "personal 'libraries'" (note quotes) and "libraries that
are essentially custom files or personal extensions".

Whatever term you use, I think it's important to recognize:

 - These different kinds of files have different properties and should be
associated with different guidelines.

 - It happens that personal startup files sometimes evolve into multi-user
libraries, and these sometimes evolve into standard Emacs libraries.

The guidelines for the different file types would help someone evolve a
personal file toward a multi-user library.

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

* RE: defcustom: changing from defvar - order of execution
  2005-05-11 14:07 ` Stefan Monnier
  2005-05-11 16:36   ` Drew Adams
@ 2005-05-11 16:37   ` Drew Adams
  1 sibling, 0 replies; 17+ messages in thread
From: Drew Adams @ 2005-05-11 16:37 UTC (permalink / raw)


    > Not only was this common in standard libraries before this
    > century, but it is still common for personal "libraries" -
    > that is, .emacs and its extensions.

    .emacs and its extensions are not libraries.  Extending the meaning of
    libraries to things like .emacs makes the word useless.

OK. What's a better term?

Use whatever term you like. I think I made clear what I was talking about. I
referred to them as "personal 'libraries'" (note quotes) and "libraries that
are essentially custom files or personal extensions".

Whatever term you use, I think it's important to recognize:

 - These different kinds of files have different properties and should be
associated with different guidelines.

 - It happens that personal startup files sometimes evolve into multi-user
libraries, and these sometimes evolve into standard Emacs libraries.

The guidelines for the different file types would help someone evolve a
personal file toward a multi-user library.

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

* Re: defcustom: changing from defvar - order of execution
       [not found] <mailman.4674.1115829901.2819.help-gnu-emacs@gnu.org>
@ 2005-05-11 18:32 ` Stefan Monnier
  0 siblings, 0 replies; 17+ messages in thread
From: Stefan Monnier @ 2005-05-11 18:32 UTC (permalink / raw)


>> Not only was this common in standard libraries before this
>> century, but it is still common for personal "libraries" -
>> that is, .emacs and its extensions.

>     .emacs and its extensions are not libraries.  Extending the meaning of
>     libraries to things like .emacs makes the word useless.

> OK. What's a better term?

Who needs a better term.  The point is that *libraries* should not do
anything (other than define new feature) when they're loaded and thus, since
.emacs is not a library, this rule of thumb doesn't apply to it.

>  - It happens that personal startup files sometimes evolve into multi-user
> libraries, and these sometimes evolve into standard Emacs libraries.

And they have to change between those stages.


        Stefan

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

end of thread, other threads:[~2005-05-11 18:32 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.3782.1115404280.2819.help-gnu-emacs@gnu.org>
2005-05-07 15:56 ` defcustom: changing from defvar - order of execution Stefan Monnier
     [not found] <mailman.4674.1115829901.2819.help-gnu-emacs@gnu.org>
2005-05-11 18:32 ` Stefan Monnier
     [not found] <mailman.4474.1115750087.2819.help-gnu-emacs@gnu.org>
2005-05-11 14:07 ` Stefan Monnier
2005-05-11 16:36   ` Drew Adams
2005-05-11 16:37   ` Drew Adams
     [not found] <mailman.3763.1115399076.2819.help-gnu-emacs@gnu.org>
2005-05-06 17:38 ` Stefan Monnier
2005-05-06 18:19   ` Drew Adams
2005-05-10 16:14 ` Per Abrahamsen
2005-05-10 18:32   ` Drew Adams
     [not found] <mailman.3356.1115247555.2819.help-gnu-emacs@gnu.org>
2005-05-06  3:20 ` Stefan Monnier
2005-05-06 17:00   ` Drew Adams
2005-05-03 15:50 Drew Adams
2005-05-03 16:13 ` Drew Adams
     [not found] ` <mailman.3227.1115174847.2819.help-gnu-emacs@gnu.org>
2005-05-04 15:03   ` Stefan Monnier
2005-05-04 22:49     ` Drew Adams
2005-05-04 15:51   ` rgb
2005-05-04 22:49     ` Drew Adams

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