8

I understand what autoload does for functions (register file to load when such function is called or its documentation string is retrieved). However, it's not clear how to use autoload facility in conjunction with variables and macros.

I have two questions:

  1. What happens when package has parameter, implemented as a variable that user can set, but it's not autoloaded? Should such variables be autoloaded? If not, it turns out that such variables do not exist, Lisp environment knows nothing about them, including their default values, until some autoloaded function from the package is used (typically after loading of configuration files), then if user sets them in his/her configuration file, it's like setting non-existing variable. If value of the variable is a non-empty list and user uses push or add-to-list to change its value, what exactly happens? Are default values lost?

  2. What happens when a macro is autoloaded? When should we autoload a macro?

Mark Karpov
  • 4,893
  • 1
  • 24
  • 53

1 Answers1

5

Autoloading only applies to the function value slot of a symbol. In particular, there is no such thing as autoloading a variable.

It is probably bad form for a package to contain variables for user customization whose default value is a nonempty list, precisely because it becomes difficult to customize the variable in that case. Worse, if the default value were to change, the customized value should probably change too, yet the user won't be aware of it. If some package does have such variables, it may be best to alter it after the package has loaded, using eval-after-load.

Most customization variables will have a default value of nil, in which case you just set them using setq in your init file (or use the customization interface). Assuming the package uses defvar or defcustom to set the variable, as it should, it will not override your setting.

Autoloading macros: Set the fifth argument of autoload to achieve this. Like functions, this should be done if it's likely that you wish to use the macro without loading the package first – either explicitly, or implicitly by first invoking other autoloaded symbols from the package.

Addendum: As the OP pointed out in the comments, a magical ;;;###autoload comment will also copy a defvar (indeed, any elisp form) to the autoload file. See the Autoload section in the elisp manual for details.

Harald Hanche-Olsen
  • 2,401
  • 12
  • 15
  • So, variables that can be just `setq`ed (i.e. it doesn't matter what values they had before) can have default specified in `defvar` or `defcustom` form, but in case of list that can be extended by user it's best to use `eval-after-load` right? Also, sometimes good defaults are good, even if they take form of a list ;-) – Mark Karpov Jul 13 '15 at 07:33
  • That's right. I would argue that if a common customization requires `eval-after-load`, it's a bug in the package implementation. Typically, `eval-after-load` should be used for bug fixes or highly unusual customizations. By the way, it may be better to use a hook if the package makes one available. – Harald Hanche-Olsen Jul 13 '15 at 08:12
  • The problem is that I wanted to have a variable that's bound to list of three elements (defaults). The defaults is what most users want, I'm sure. But if I go `eval-after-load` way, users still won't be able to remove elements from the list! This makes me wonder if I should abandon the defaults at all. – Mark Karpov Jul 13 '15 at 08:16
  • 1
    I don't agree that `eval-after-load` should be needed only for unusual situations. It's one of the standard tools in the deferred-loading toolkit. If people don't want to use such tools, they can `require` the library up front (which is indeed what newcomers are invariably recommended to do -- by the time they get around to thinking "I wish Emacs started a little faster", they've probably learned enough not to be scared off by the new syntax :) – phils Jul 13 '15 at 08:56
  • @phils Okay, maybe I worded that too strongly. But I think it is preferable if customizations can be done up front. At least the simple ones. – Harald Hanche-Olsen Jul 13 '15 at 09:32
  • @Mark It was not clear to me that you were writing as a package developer rather than a user. I find it difficult to offer advice without knowing a bit more about the nature of those defaults. If you are confident that the defaults will never change, then you might as well tell users who want different values to `setq` the relevant variable up front. – Harald Hanche-Olsen Jul 13 '15 at 09:36
  • It turns out that adding `;;;###autoload` cookie adds declaration of the variable to corresponding autoload file (when installed via package manager, at least) thus it can be used to "predeclare" variables and their values (I think it's also kinda cheap operation). Did you know that? Can you add the fact into your answer for future readers? – Mark Karpov Jul 13 '15 at 11:52
  • What @Mark just said. It is absolutely false that "*there is no such thing as autoloading a variable*". If you decide to autoload, say, a `defcustom` form, you should be careful about its initialization code (e.g., make sure that any functions and variables it uses are autoloaded first or are otherwise available without loading the library). And autoloading a long variable definition can contribute to autoload-file bloat. IOW, (1) it is entirely possible and (2) use it judiciously, if you use it. – Drew Feb 01 '16 at 02:03
  • This too is false: "*bad form for a package to contain variables for user customization whose default value is a nonempty list, precisely because it becomes difficult to customize the variable in that case.*" There is no problem using a non-nil default value for a `defcustom`. If a user sets the option value before the `defcustom` is evaluated, the `defcustom` default value is not used. "*If OPTION already has a default value, it is left unchanged. If the user has already saved a customization for OPTION, the user’s customized value is installed as the default value.*" – Drew Feb 01 '16 at 02:09
  • (That last quote is from the Elisp manual, node [Variable Definitions](http://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Definitions.html).) – Drew Feb 01 '16 at 02:10
  • This is fiction also: "*Most customization variables will have a default value of nil.*" And this is bad practice: "*just set them using setq in your init file.*" Do *not* use `setq` for user options. Use `customize-set-variable` or use the Customize UI. Why? Because `setq` knows nothing about `:set` and initialization triggers (functions). See [Advantages of setting variables with setq instead of custom.el?](http://emacs.stackexchange.com/a/106/105). – Drew Feb 01 '16 at 02:13
  • @Drew: About autoloading variables – as far as I read the elisp manual, autoloading is a term only used for functions, macros, and keymaps. It is far from clear to me that using the magic cookie method to add a form to the autoload file deserves the name autoloading. It's a question of when it gets evaluated. On the other hand, I see now that `custom-set-variables` does have some of the features I associate with autoloading, i.e., it's not evaluated until needed. – Harald Hanche-Olsen Feb 01 '16 at 12:46
  • @Drew: As for the “bad form” comment (please note that I softened it with “probably”), what I see as the problem her is when the default value is a long list, where the user wants to add a small bit or make some simple modification. The typical solution is to do the modification in a hook or with `eval-after-load`. If possible and meaningful, it might be better to provide a customizable variable containing additions to the given list. Perhaps this is better solved with some of the more advanced features of the customize feature; I haven't studied it in that much detail. – Harald Hanche-Olsen Feb 01 '16 at 12:52
  • 1
    @Drew: Your point on using `customize-set-variable` rather than `setq` may be a good one. But I don't have the time now for the careful study required to improve my answer in this regard. If you think this is important, why don't you write your own answer? It will be more visible than this long comment thread. – Harald Hanche-Olsen Feb 01 '16 at 12:55