Qual é o ponto de citação com argumento único e vírgula? (citação, argumento)

15

(quote x)faz x não ser avaliado, mas adicionar um ,na frente de xdentro quotefaz com que seja avaliado. Qual é o objetivo de usar aspas com um único argumento com uma vírgula na frente, assim (quote ,x):?

Motivado pela linha 59 de flechas irritantes :

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

Por que não é (put cmd 'aa-alts ,alternatives)igualmente bom?

The Unfun Cat
fonte

Respostas:

20

A vírgula é usada no contexto de uma lista com aspas posteriores (também conhecida como quasiquoted), que permite avaliar algumas partes da lista seletivamente. Consulte também este tópico para obter um exemplo de uso para aspas posteriores.

Alguns exemplos simples:

(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")

As vírgulas às quais você está se referindo estão em uma definição de macro que, por sua vez, usa um aspas 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))))))

,cmddentro da cota posterior, você pode colocar o valor de cmdno lugar, em vez do símbolo cmd.

Dan
fonte
1
Então, a citação na frente prognsignifica que você precisa colocar uma vírgula na frente das coisas que deseja avaliar, não importa a que distância esteja aninhada? (A ,cmdestá dentro de outra lista, não diretamente dentro (progn).)
The Cat Unfun
Parece uma boa oportunidade para testá-lo! Tente avaliar (setq a "a's value" b "b's value" c "c's value")e depois avaliar `(a '(,b c)).
Dan
Outras notícias: para avaliar, adicione o texto ao seu buffer temporário, coloque o cursor no final da linha e pressione Cxe.
The Unfun Cat
10

Isso é porque está dentro de uma macro. Uma macro precisa retornar um formulário Lisp, que por sua vez é avaliado.

Por exemplo, observando a primeira chamada desta macro:

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

Precisamos que a expansão contenha:

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

o que é o que (quote ,cmd)alcança. Se a macro usasse simples cmd, ela seria mantida literalmente e a expansão seria:

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

que é um erro, porque cmdnão está definido no ambiente em que a macro é chamada.

legoscia
fonte
Esta também é uma ótima explicação. Obrigado por esclarecer.
The Unfun Cat