3

Very simple question but confuse me for some time:

(setq visible-bell t)

and

(visible-bell t)

both seem work.

But

(desktop-save-mode 1)

works, while

(setq desktop-save-mode 1)

not.

May I ask why is this?

X.Arthur
  • 61
  • 5

4 Answers4

5

They're different because they're different :)

(setq visible-bell t)

is assigning the value t to a variable named visible-bell.

(visible-bell t)

is calling a function1 named visible-bell (and passing the value t as a parameter).

(Although FYI there is no visible-bell function by default in current versions of Emacs, so it's not obvious to me that this is actually working the way you think? However, assuming for the moment that you do indeed have such a function...)

Emacs Lisp is a 'Lisp-2' meaning it has separate name spaces for variables and functions, and therefore you can -- and commonly do -- have a variable and a function with the same name. Which one is being referred to is always implicit in the context of the code (e.g. setq always refers to a variable).

In short, the two pieces of code are doing very different things. This doesn't mean they couldn't have an equivalent effect (e.g. the function might simply set the value of the variable); but whether or not that's actually the case is entirely up to the definition of the function.


1 In fact the first line of code is also calling a function2: it's calling setq and passing it two parameters visible-bell and t, and setq then sets the value in accordance with its parameters. Hopefully you're now starting to see how lisp syntax works?

2 Strictly speaking, setq is actually a "special form" rather than a function, and special forms are closer to macros than to functions; but these distinctions are not important for this Q&A.

phils
  • 71,335
  • 11
  • 153
  • 198
3

Others have told you the basic points about what setq does and about variables versus functions.

Wrt visible-bell itself:

  1. There is no function visible-bell delivered with Emacs, in any Emacs version I know of, and there never has been. (I've checked back through Emacs 20, and by memory I believe the same was true from the beginning. There is only the variable visible-bell.

    So as @phils suggested, is not clear that what you said is true: "both seem to work". Unless some extra code you are loading defines a function of that name (and then there is no way for us to comment on it, not having it to see), evaluating (visible-bell t) raises an undefined (void) function error.

  2. Variable visible-bell is not just a variable. It is a user option, and it has been, again, since at least Emacs 20.

  3. You should not, in general, just use setq to change the value of a user option. In many cases you won't get into trouble if you do that, but sometimes you will, and it is not a good habit to get into.

    setq does not perform any special initialization or updating actions that might be appropriate for a given user option. It is not intended for user options. Or rather, user options are not intended for setq - they can be more complex than what setq can offer.

  4. What you should use instead of setq is Customize. Either interactively (M-x customize-option RET visible-bell RET, or C-h v RET visible-bell RET followed by clicking the customize link) or using Lisp code in your init file.

  5. If you use Lisp code then use one of these functions (not setq):

    • customize-set-variable
    • customize-set-value
    • custom-set-variables

    Use C-h f followed by each of those function names, to see what (minor) differences there are.

Drew
  • 29,895
  • 7
  • 74
  • 104
2

There are 3 issues here.

  1. In Emacs Lisp, the same symbol can be both variable and function.

in the case of desktop-save-mode, it's a function but also a variable.

Because it's a function, so you can call

(desktop-save-mode 1)

Because it's a variable, so you set value to it

(setq desktop-save-mode t)

You can define your own function and also a variable of the same name to test it.

Note: exactly what a function's arguments should be or what the value of a variable makes sense depends on the function or variable.

  1. Now, a second issue. In general, for function (commands) to activate a minor mode, the convention is that a positive integer should mean to turn it on, and otherwise turn off.

Also, for command to activate a minor mode, typically there's a variable of the same name, with value of t or nil, to indicate if the mode is on.

  1. Now, there's third issue. For command to activate the mode, before emacs 24 or so, by convention, if no arg is given, the command toggle current state.

Because all of the above, the issue is confusing. You might see in init things like this:

(desktop-save-mode 1) ; correct. To turn on.
(desktop-save-mode) ; Confusing. Should take value 1 to turn on. Usually works because by default it's off.
(desktop-save-mode t) ; wrong. Take value of positive integer to turn on.
(desktop-save-mode nil) ; Confusing. Value should be integer
(setq desktop-save-mode t) ; wrong. Shoud call function instead
(setq desktop-save-mode nil) ; wrong. Shoud call function instead
(setq desktop-save-mode 1) ; wrong. Shoud call function instead. Besides, only t and nil make sense

So, there's a lot confusion. In emacs 24 (or 23.x), the convention changed so that, if it receives no value, it will turn on, if called in elisp code. (when called interactively as command, it toggles.)

In the end, always call describe-function or describe-variable to read the doc.

Xah Lee
  • 16,755
  • 9
  • 37
  • 43
0

Well setq (which is "set" with an auto-quoting feature) is used in assigning a value to a variable. In this example, it's obviously not required because as you mentioned, omitting it works for the first set of examples.

Basically, visible-bell is a variable, and you assign it the value "t" to enable visible bells.

However, desktop-save-mode is an interactive function, so you don't use setq to assign it a value, you call it with parameters.

One good thing to do when you're not sure what something is, is to use the built-in help function:

C-h v visible-bell RET

This will return the information for visible bell -- notice the "v" in the command is because it's a variable. If you wanted to search for information on a function, you would do this:

C-h f desktop-save-mode RET

Incidentally in this case, desktop-save-mode is also a variable, but it's a read-only variable to determine whether or not desktop-save-mode is enabled, so trying to alter it will not work.

Drew
  • 29,895
  • 7
  • 74
  • 104
Tim S.
  • 2,187
  • 1
  • 25
  • 40