26

(quote x) makes x not be evaluated, but adding a , in front of x within quote makes it evaluated. What is then the point of using quote with a single argument with a comma in front of it, like so: (quote ,x)?

Motivated by line 59 from annoying arrows:

(put (quote ,cmd) 'aa--alts ,alternatives)

Why isn't (put cmd 'aa-alts ,alternatives) equally good?

Drew
  • 77,472
  • 10
  • 114
  • 243
The Unfun Cat
  • 2,413
  • 17
  • 32

2 Answers2

35

The comma is used in the context of a backquoted (a.k.a. quasiquoted) list, which allows you to evaluate some portions of the list selectively. See also this thread for an example of a use for backquoting.

A couple of simple examples:

(setq a "a's value" b "b's value" c "c's value")
'(a  b  c)                              ; => (a b c)
`(,a b ,c)                              ; => ("a's value" b "c's value")

The commas to which you're referring are in a macro definition that, in turn, uses a backquoted progn:

(defmacro add-annoying-arrows-advice (cmd alternatives)
  `(progn
     (add-to-list 'annoying-commands (quote ,cmd))
     (put (quote ,cmd) 'aa--alts ,alternatives)
     (defadvice ,cmd (before annoying-arrows activate)
       (when annoying-arrows-mode
         (aa--maybe-complain (quote ,cmd))))))

,cmd within the backquote allows you to put the value of cmd in place rather than the symbol cmd.

Dan
  • 32,980
  • 7
  • 102
  • 169
  • 1
    Ackey, so the quote in front of progn means that you have to put a comma in front of stuff you want evaluated, no matter how far it is nested? (The ,cmd is within another list, not directly within (progn).) – The Unfun Cat Jan 21 '15 at 14:23
  • This seems like a good opportunity to test it out! Try evaluating (setq a "a's value" b "b's value" c "c's value") and then evaluating \(a '(,b c))`. – Dan Jan 21 '15 at 14:25
  • Other newbs: to evaluate add the text to your scratch buffer, then place your cursor at the end of the line, then press C-x-e. – The Unfun Cat Jan 21 '15 at 14:27
12

That's because it's inside a macro. A macro needs to return a Lisp form, which then in turn gets evaluated.

For example, looking at the first invocation of this macro:

(add-annoying-arrows-advice previous-line '(ace-jump-mode backward-paragraph isearch-backward ido-imenu smart-up))

We need the expansion to contain:

(put 'previous-line 'aa-alts '(ace-jump-mode backward-paragraph isearch-backward ido-imenu smart-up))

which is what (quote ,cmd) achieves. If the macro would use plain cmd instead, it would be kept literally and the expansion would be:

(put cmd 'aa-alts '(ace-jump-mode backward-paragraph isearch-backward ido-imenu smart-up))

which is an error, because cmd is not defined in the environment where the macro is invoked.

legoscia
  • 6,072
  • 30
  • 54