Subject: bug#21695: [External] : Re: bug#21695: 25.0.50; Change most occurrences of `setq' in Emacs manual to `customize-set-variable'? Really?

From: Drew Adams <[email-masked]>
Date: Tue, 31 Aug 2021 16:15:31 +0000

> There are a few customization options that are not really variables
> and need to be set with `customize-set-variable'.

Please specify what you mean by not really being
variables, and give examples (which options?).

Are you maybe just defining not-really-variable-p
as being an option that has a :set or :initialize?

To my mind (unless I see a persuasive argument),
user options are variables.  They're variables
defined with defcustom; variables whose values
typically have a :type restriction; variables
that are really designed to be set using
Customize.

If I had to come up with a class of options that
are kinda something else, I'd say it's the
minor-mode options (those that correspond to a
minor-mode command).  Those we already (and
rightfully) tell users not to use directly, i.e.,
as variables (`setq').  We tell users to set them
indirectly, by using the mode function instead.

(We do tell them that some mode vars _can_ be set
using `setq' or Customize, but we give them the
general guideline to use the minor-mode function
instead.)

Sure, an option with a :set or :initialize is not
a _simple_ variable, if simple means that you can
just set it with `setq'.  But with that we've
just turned in a circle.

> However, the rest of them are variables and
> normally set with `setq' and friends.

Circular, I think.  I'm guessing you're really
just defining options that can, without problem,
be set with `setq' to be "variables".

> Telling users to set them all with `customize-set-variable' will be a
> significant hassle.  What's more, users will disregard this instruction.
> `setq' is easy to remember and we all know it.
> 
> Having a recommendation in the manual which users will generally
> reject is in itself a problem.

Why would they reject it?  Only because `setq' is
easy to remember?  It's a question of habit.  If
you've never been told to set options differently,
then sure, `setq' is your hammer.

I do agree that a short name would be better.
But that's easily solved by adding an alias for
`customize-set-variable' such as `setq-opt' or
`setqo' or `setopt' .  What's missing is the
guideline to use that instead of `setq'.

Here's my (different) take, FWIW -

1. Yes, for most user options `setq' is sufficient.

   But that makes setting options seem to be
   nothing special - so it's a gotcha when it
   "doesn't work".

2. Yes, if an option's defcustom uses :set then its
   doc string is _supposed_ to tell users how to set
   it properly.

   (Similarly, for :initialize, IMO - même combat.
   But that one's _not_ stated in the manual.)

3. Yes, IF such an option's doc does that (does what
   it's supposed to do), and IF a user reads the doc
   string, and IF s?he understands it, and IF s?he
   does what the doc string says to do (or uses
   `setq' if the doc says nothing particular), THEN
   no problem - the problem is avoided.

OR if a user generally applies the heuristic to not
use `setq' with user options, then no problem.
(Only one "if".  Only one thing to learn, once and
for all - no case-by-case hunt needed.)

In the Emacs manual we use `customize-set-variable'
with options `display-buffer-alist' and
`display-buffer-base-action' (see nodes `Window
Choice' and `Temporary Displays').  Why?  Neither
of those even has a :set or :initialize.

And of course `custom-set-variables' is used in
init files, even if that's done by Customize.
(And there's no attempt there to use `setq' for
those options that are "really variables".)

Users who pay attention thus can see `setq' not
being used with options in some cases - but with
no explanation.

The problem/gotcha of users using `setq' when an
option is defined with :set is real, regardless
of how few options are so defined.

How best to help users avoid this gotcha?  I
think that's the question.

Relying on 3rd-party code that uses :set to also
correctly specify what's advised for doc strings
is problematic.

Relying on users, especially non-lisper or new
users, to hunt for whether an option uses :set,
and if so to DTRT for it, is problematic.

That few options actually do use :set makes it
all the more problematic when some do, because
the behavior is too often unexpected and not
known to be happening.

Better to get users in the good habit of setting
options without `setq'.  And yes, better for the
doc (the Emacs manual, not just the Elisp manual)
to give them a heads-up about the existence of
options that depend on a :set function.

Even better is to get users to use Customize,
and to use a `custom-file'.  But if they don't,
they should at least use a customize function,
which we provide precisely for that purpose: to
DTRT when it comes to setting an option value.

> I think we should address this some other way.
> Here are some ideas.
> 
> * indicate the few customization options
>    which are not really variables.

1. See above - how so "not really variables"?
2. It's not just about the options that Emacs
   delivers predefined.  It's also about the
   many options defined by 3rd-party code.

> * tell people how to check whether
>    a customization options is really a variable.

See above.  A rely-on-users-to-check approach
is problematic, IMO.  Far better to just tell
users, as a general rule, not to use `setq'
with options.

Options are _not_ your ordinary vars (what you
call "really variables", I guess).  That should
be our main (first approximation) message to
users.  Options - not some options - are not
ordinary variables.

The fact that `setq' does in fact "work" for
most user options is a problem, not a solution.
It fosters a bad habit and false idea of what's
involved.

> * warn about setq for a customization option
>   that isn't really a variable.

That's the problem: which option is that?  You
can put this check-carefully burden on users,
but that's not the best approach.

That's like teaching kids to check the chemical
composition of any candy offered them by any
person, instead of teaching them a general
(first approximation) rule of thumb to just not
accept candy from strangers.

IOW, reverse it: if you _don't_ know that some
option needs _no_ special handling then don't
use `setq'.

That's a sane general rule; it'll never get you
in trouble.  And it means you don't have to go
looking into each option definition (or rely on
a DTRT doc string), to see if you can use `setq'
on it.

Easier on users - no gotcha, no careful paying
attention.  If it's an option, don't use `setq'.

Just one opinion.
___

[I also think more defcustoms could benefit
from better (tighter) :type specs, and I suspect
that more options than now might benefit from
:set or :initialize functions.]