¿Cuál es el punto de cita con argumento simple y coma? (cita, arg)

15

(quote x)hace que x no se evalúe, pero al agregar un ,frente xdentro se quotehace evaluar. ¿Cuál es entonces el punto de usar comillas con un solo argumento con una coma delante de ella, así (quote ,x):?

Motivado por la línea 59 de flechas molestas :

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

¿Por qué no es (put cmd 'aa-alts ,alternatives)igual de bueno?

El gato no divertido
fuente

Respuestas:

20

La coma se usa en el contexto de una lista con comillas invertidas (también conocida como cuasicotipada), que le permite evaluar algunas partes de la lista de forma selectiva. Vea también este hilo para ver un ejemplo de uso para backquoting.

Un par de ejemplos 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")

Las comas a las que se refiere están en una definición de macro que, a su vez, utiliza un comillas invertidas 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 de la cita posterior le permite poner el valor de cmden lugar de el símbolo cmd.

Dan
fuente
1
Ackey, entonces, la cita en frente prognsignifica que tienes que poner una coma delante de las cosas que quieres evaluar, sin importar cuán lejos estén anidadas. (El ,cmdestá dentro de otra lista, no directamente dentro (progn).)
The Unfun Cat
¡Parece una buena oportunidad para probarlo! Intenta evaluar (setq a "a's value" b "b's value" c "c's value")y luego evaluar `(a '(,b c)).
Dan
Otros novatos: para evaluar, agregue el texto a su búfer de memoria virtual, luego coloque el cursor al final de la línea, luego presione Cxe.
The Unfun Cat
11

Eso es porque está dentro de una macro. Una macro necesita devolver un formulario Lisp, que a su vez se evalúa.

Por ejemplo, mirando la primera invocación de esta macro:

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

Necesitamos la expansión para contener:

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

que es lo que (quote ,cmd)logra Si la macro usara simplemente cmd, se mantendría literalmente y la expansión sería:

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

lo cual es un error, porque cmdno está definido en el entorno donde se invoca la macro.

legoscia
fuente
Esta también es una gran explicación. Gracias por explicarlo.
The Unfun Cat