25

(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
  • 75,699
  • 9
  • 109
  • 225
The Unfun Cat
  • 2,393
  • 16
  • 32

2 Answers2

34

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,584
  • 6
  • 98
  • 168
  • 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,012
  • 29
  • 54