1

I have to back up and restore a bunch of variables in Emacs and thought I'd be clever about it, put the variable names into a list, then create a function that defines for each item in the list a new variable whose name is that of the item in the list with a "-backup"-suffix and a function that takes the backup-versions and sets the corresponding variables to their value. So I wrote

(setq testlist (list '"test"))
(setq (intern (concat (car testlist) "-backup")) testlist)

But this doesn't work. As seen in the code I've already found out that the result of concat is a string and that I should make it into a symbol. But even as a symbol evaluating the above code returns an error. I suppose this is because the documentation of setq says "The symbols SYM are variables; they are literal (not evaluated).". So how do I set variables using code that evaluates to their symbol names?

4
  • Note that M-x elisp-index-search RET setq RET will take you to a node which also tells you about set.
    – phils
    Jan 24 at 22:41
  • I'm guessing this question might be a duplicate of another that misses set versus setq...
    – Drew
    Jan 25 at 0:33
  • 1
    You have an extraneous single-quote: '"test" should be just "test". Jan 31 at 12:01

2 Answers 2

4

EDIT

Here you can find the motivation for its removal. Apparently, it can not be used on lexically scoped variables.

END EDIT

This used to be explained in section 1.9 of An Introduction to Programming in Emacs Lisp, but seems to have been removed.

Therefore, I will paste the original contents here

1.9.1 Using ‘set’
-----------------

To set the value of the symbol ‘flowers’ to the list ‘'(rose violet
daisy buttercup)’, evaluate the following expression by positioning the
cursor after the expression and typing ‘C-x C-e’.

     (set 'flowers '(rose violet daisy buttercup))

The list ‘(rose violet daisy buttercup)’ will appear in the echo area.
This is what is _returned_ by the ‘set’ function.  As a side effect, the
symbol ‘flowers’ is bound to the list; that is, the symbol ‘flowers’,
which can be viewed as a variable, is given the list as its value.
(This process, by the way, illustrates how a side effect to the Lisp
interpreter, setting the value, can be the primary effect that we humans
are interested in.  This is because every Lisp function must return a
value if it does not get an error, but it will only have a side effect
if it is designed to have one.)

   After evaluating the ‘set’ expression, you can evaluate the symbol
‘flowers’ and it will return the value you just set.  Here is the
symbol.  Place your cursor after it and type ‘C-x C-e’.

     flowers

When you evaluate ‘flowers’, the list ‘(rose violet daisy buttercup)’
appears in the echo area.

   Incidentally, if you evaluate ‘'flowers’, the variable with a quote
in front of it, what you will see in the echo area is the symbol itself,
‘flowers’.  Here is the quoted symbol, so you can try this:

     'flowers

   Note also, that when you use ‘set’, you need to quote both arguments
to ‘set’, unless you want them evaluated.  Since we do not want either
argument evaluated, neither the variable ‘flowers’ nor the list ‘(rose
violet daisy buttercup)’, both are quoted.  (When you use ‘set’ without
quoting its first argument, the first argument is evaluated before
anything else is done.  If you did this and ‘flowers’ did not have a
value already, you would get an error message that the ‘Symbol's value
as variable is void’; on the other hand, if ‘flowers’ did return a value
after it was evaluated, the ‘set’ would attempt to set the value that
was returned.  There are situations where this is the right thing for
the function to do; but such situations are rare.)

This should be combined with the next section:

1.9.2 Using ‘setq’
------------------

As a practical matter, you almost always quote the first argument to
‘set’.  The combination of ‘set’ and a quoted first argument is so
common that it has its own name: the special form ‘setq’.  This special
form is just like ‘set’ except that the first argument is quoted
automatically, so you don’t need to type the quote mark yourself.  Also,
as an added convenience, ‘setq’ permits you to set several different
variables to different values, all in one expression.

   To set the value of the variable ‘carnivores’ to the list ‘'(lion
tiger leopard)’ using ‘setq’, the following expression is used:

     (setq carnivores '(lion tiger leopard))

This is exactly the same as using ‘set’ except the first argument is
automatically quoted by ‘setq’.  (The ‘q’ in ‘setq’ means ‘quote’.)

   With ‘set’, the expression would look like this:

     (set 'carnivores '(lion tiger leopard))

   Also, ‘setq’ can be used to assign different values to different
variables.  The first argument is bound to the value of the second
argument, the third argument is bound to the value of the fourth
argument, and so on.  For example, you could use the following to assign
a list of trees to the symbol ‘trees’ and a list of herbivores to the
symbol ‘herbivores’:

     (setq trees '(pine fir oak maple)
           herbivores '(gazelle antelope zebra))

(The expression could just as well have been on one line, but it might
not have fit on a page; and humans find it easier to read nicely
formatted lists.)

   Although I have been using the term “assign”, there is another way of
thinking about the workings of ‘set’ and ‘setq’; and that is to say that
‘set’ and ‘setq’ make the symbol _point_ to the list.  This latter way
of thinking is very common and in forthcoming chapters we shall come
upon at least one symbol that has “pointer” as part of its name.  The
name is chosen because the symbol has a value, specifically a list,
attached to it; or, expressed another way, the symbol is set to point to
the list.
5
  • 1
    You beat me to it by 41 seconds :-)
    – NickD
    Jan 24 at 19:59
  • 1
    Haha yeah... probably only because I just copy-pasted :p Jan 24 at 20:14
  • Yeah, but you still had to examine the intro manual, determine that the sections of interest were not there and find the old version so that you could copy/paste - it probably took you longer to do all that than for me to type two sentences and copy/paste one line of code (and delete one character) - and you still beat me :-D
    – NickD
    Jan 24 at 21:26
  • Okay... you win this one :) (indeed, it took me some time to 'investigate' things) Jan 24 at 22:22
  • 1
    What can I say? I'm slow...
    – NickD
    Jan 25 at 1:19
3

Use set instead of setq in the second form. It evaluates its first argument (i.e. it evals the intern that returns the symbol):

(set (intern (concat (car testlist) "-backup")) testlist)

setq is a macro that does not evaluate its first argument (so it's the whole (intern ...) form). As its doc string (C-h f setq) shows, it expects that argument to be a symbol, not an arbitrary lisp expression:

setq is a special form in ‘C source code’.

(setq [SYM VAL]...)

Set each SYM to the value of its VAL.
The symbols SYM are variables; they are literal (not evaluated).
...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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