13

(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?

18

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.

  • 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
10

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.

  • This is also a great explanation. Thanks for spelling it out. – The Unfun Cat Jan 21 '15 at 14:30

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.