1

Suppose one of the customizable variables in a package is var, and its default value is a list, list. I understand I can change the value of var to mylist using

(setq var mylist)

in my init.el.

Suppose though that I have a function fun and I want the value of var to be the result of applying fun to list. Can I simply do this?

(setq var (fun var))

I've done it and it seems to work as intended, but I want to make sure this is a good idea.


EDIT: My question was not very clear, so let me clarify the sort of thing I was worried about (this may be redundant in light of my comment to this answer by Drew. Suppose I add

(setq var (fun var))

to my init.el. How do I ensure that the default value of var has already been set when that line gets evaluated? Should I put this inside a with-eval-after-load? And how do I ensure that M-x load-file ~/.emacs.d/init.el won't result in var being set to the value of (fun (fun var))? Should I instead add the above line to something like emacs-startup-hook or after-init-hook?

I'm currently using a line in my init.el like the above for setting a variable to a value as a function of its default value. I'm relying on use-package, and in order to ensure that the default value of the variable had been set I had to put that line in the :config section of the relevant package, rather than in the :custom section (without setq). Also, the function I am currently using has the nice feature that (fun (fun var)) yields the same output as (fun var). So I have managed to get around both of my concerns.

Still, this seemed like an opportunity to try to understand how to do what I'm trying to do even if I'm not using use-package and if I have a function that's not idempotent.

  • 1
    You might find the Programming in Emacs Lisp manual a useful introduction to Lisp in general and Emacs Lisp in particular. – NickD Sep 17 at 21:59
  • 1
    with-eval-after-load is the right approach for ensuring that var has been defined before you try to use it. Ensuring that you're only ever manipulating its default value is harder. If it's a defcustom then you do have access to its standard value, but this is not the case for defvar, so you would need to capture and store that value yourself before you changed it (notwithstanding that something else might already have gotten in ahead of you). – phils Sep 19 at 2:42
  • @phils That's exactly what I needed! Thanks very much. So, I could just do (setq var (fun (eval (car (get 'var 'standard-value))))) to accomplish what I want, as long as var is introduced with a defcustom. I will accept this if you want to put it as an answer. – apc Sep 20 at 1:45
1

Yes. setq sets a variable to whatever value is returned by the second argument.

(setq VAR VALUE) sets variable VAR to whatever VALUE is, and the second argument, VALUE is always evaluated.

(The first argument, VAR, is never evaluated. For a function that evaluates both args, see set.)

| improve this answer | |
  • Thanks (again!) for your helpful answer. One thing I was worried about was the fact that var may not yet have been assigned a value by the package. Another was that I didn't know whether e.g. reloading my init.el file would result in var being changed in a non-desirable way, since it might result in var having its value now be the result of applying fun to the result of applying fun to the default value of var. Does that make sense? Should I not worry about any of this? – apc Sep 18 at 1:58
  • C-h f defvar. Use defvar to set a global variable once. Subsequent evaluation of defvars for that variable have no effect. setq always updates an existing variable or initializes one that's never had a value. – Drew Sep 18 at 2:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.