Subject: bug#11106: 24.0.94; enhancement request: have autoload treat faces like it does options

From: "Drew Adams" <[email-masked]>
Date: Wed, 28 Mar 2012 10:08:26 -0700

> > For #1: Make an autoload cookie before a defface do something
> > analogous to what it does before a defcustom.  I'm no expert on the
> > latter, so yes, this is vague.  IIUC, an autoload cookie handles an
> > option definition by setting the option value at autoload 
> > time, but it does not simply copy the defcustom to the autoloads file.
> 
> ;;;###autoload on a defcustom pretty much copies the defcustom, tho it
> addmittedly tries to strip away things that won't be needed until the
> file is actually loaded.
> 
> But I don't know what that would mean for defface.  IOW what is the
> concrete problem you see with ;;;###autoload on a defface that you'd
> like to see fixed?

No special problem for #1.  It's not completely clear to me how an option is
handled, but clearly the defcustom is not simply copied to the autoloads file.
I took a look at autoload.el and custom.el, as well as the C code for
`autoload', but the entire purpose behind the treatment of defcustom is not
clear to me.  If you think the cookie-handling code does nothing special for
options then you can ignore request #1.

It is request #2 that I am particularly interested in, as I said.

> > Assume you want to provide autoloading for the faces,
> 
> I can't assume it, since you're trying to explain to me why that would
> be useful.

No, I was not trying to explain why autoloading faces can be useful in general.
Yes, I do assume that it can be.

What I explained was a use case for having function `autoload' handle options
and faces - the scenario you asked for.  If you look at that use case perhaps
you will understand more specifically why (real) autoloading can be helpful, and
how different it would be from simply predefining faces completely at autoload
file generation time.

As to the assumption of usefulness in general, since that is apparently a
stumbling block for you: Why, in your opinion, can (real) autoloading be useful
for a command but not for an option or a face?  The same utility you see for a
command I see also for an option or face.

IOW, why do we have function `autoload' for functions?  Why not just use
autoload cookies and have them simply copy a function's defun to the autoloads
file (i.e., not handle functions specially)?

The same reason applies to options and functions: real autoloading has a use,
independent of the use of predefinition.  Imagine handicapping autoload cookies
by removing their special handling of defuns - have them just copy the defun to
the autoloads file, and you will see how their handling of options and faces is
handicapped.

> > to let users get to their doc.
> 
> That's it?  So you only want it for describe-face's purpose?

No, not only the doc.  I want it for the same reasons that any (real)
autoloading is wanted.  I want function `autoload' to do for options and faces
the same kind of thing it does for functions.

Think in terms of function autoloading as the model.  Why provide autoloading of
functions (e.g. commands, keymaps)?  Those same reasons apply to options and
faces, IMO.  It is about doc, sure, but not only doc.

When you do `M-x foo TAB', you see `foobar' as a candidate, if it is autoloaded.
Similarly, if you do `M-x customize-face RET foo TAB' you would see `fooface' as
a candidate, if it were autoloaded.

And just as in the case of a command, the face would not be predefined, just in
order to be autoloadable.  The point of this request is to provide real
autoloading for options and faces, as opposed to simply
predefinition/pre-evaluation (which is what autoload cookies do for an arbitrary
sexp).

The face would be undefined until you tried to access it, and then its defining
file would be loaded and its defface would kick in (at load time) to provide the
definition and hence the "value": either the default value or an already
customized value.  In this example, that definition would be provided to
`customize-face' as a completion candidate.

There is a big difference between defining a face at autoload file generation
time and defining it when the library containing its defface is loaded.  For one
thing, if the user has customized the face then the library's defface will have
no effect, whereas a defface in an autoloads file might be eval'ed before the
user's `custom-file' is loaded.

I gave a specific example (scenario) for this, as you requested.

Think how users interact with autoloaded commands and keymaps.  I would like the
same possibility for faces and options.  For the same reasons.  And yes, one of
those reasons - for commands too - is access to the doc.

> Then autoloading is not the right answer.  We're back at the issue of
> finding documentation for vars, functions, and now faces in not-yet
> loaded code.  We don't need to autoload the whole world for that.

And you're no doubt thinking of only the current handling of autoload cookies
for faces and options.  That handling is indeed heavy-handed, perhaps even
misguided.  It is a sledgehammer substitute for real, lightweight autoloading
(such as is provided for functions by function `autoload').

Autoload cookies simply predefine/pre-evaluate stuff.  They do not really
provide an autoload feature, as does function `autoload'.  Except that for
functions they DTRT: call `autoload'.

Simply predefining in an autoloads file is not what we do for autoloading
function definitions.  This request (#2) is about extending function `autoload'
to handle user options and faces, just as it handles functions (including
commands and keymaps).

For functions, we essentially preload only the doc, and we put in place a
trigger to load the file that actually defines the function.  That's what my
request #2 is about: have function `autoload' treat options and faces
analogously to its treatment of functions.  And an autoload cookie would then
handle defface and defcustom, like it handles defun, by handing things off to
function `autoload'.

I want to be able to actually autoload an option or face, having it become
defined by loading its defining file, and not just having it be predefined in
some autoloads file.

Just like commands, users interact with things that can be customized: options
and faces.  I want to make it possible to let them interact with options and
faces whose definitions have not yet been loaded.

And I do not want to predefine those customizable things just in order to be
able to autoload them.  Just as for autoloaded commands, I want all of the
defining logic to take effect in the library's load environment, not at some
package-install time when a file of autoloads is generated.

Letting user customizations be taken into account when loading is one example of
that.  Library file dependencies is another example.  I want to separate such
logic from the autoloads file - later, load-time binding, if you will.

> [ Sorry, didn't read the rest, assuming that it is not relevant since
>   I rejected the main assumption. ]

A copout.  Try reading before rejecting out of hand.  Especially since you asked
for a scenario and I provided one - I described a specific use case.  And I can
point you to the code that inspired it if my description of it is not clear.
But at least read the description, please.