Quel est le point de citation avec un seul argument et une virgule? (citation, arg)

15

(quote x)fait que x ne soit pas évalué, mais l'ajout d'un ,devant devant xdedans le quoterend évalué. Quel est alors l'intérêt d'utiliser quote avec un seul argument avec une virgule devant, comme ceci (quote ,x):?

Motivé par la ligne 59 de flèches ennuyeuses :

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

Pourquoi n'est-il pas (put cmd 'aa-alts ,alternatives)aussi bon?

Le chat unfun
la source

Réponses:

20

La virgule est utilisée dans le cadre d'une backquoted liste (alias quasiquoted), qui vous permet d'évaluer certaines parties de la liste sélective. Voir aussi ce fil pour un exemple d'utilisation de backquoting.

Quelques exemples 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")

Les virgules auxquelles vous faites référence se trouvent dans une définition de macro qui, à son tour, utilise un guillemet arrière 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))))))

,cmddans la citation arrière vous permet de mettre la valeur de cmden place plutôt que le symbole cmd.

Dan
la source
1
Ackey, donc la citation devant prognsignifie que vous devez mettre une virgule devant les éléments que vous souhaitez évaluer, quelle que soit leur imbrication? (Le ,cmdest dans une autre liste, pas directement à l'intérieur (progn).)
The Unfun Cat
Cela semble être une bonne occasion de le tester! Essayez d'évaluer (setq a "a's value" b "b's value" c "c's value")puis d'évaluer `(a '(,b c)).
Dan
Autres newbs: pour évaluer, ajoutez le texte à votre tampon de travail, puis placez votre curseur à la fin de la ligne, puis appuyez sur Cxe.
The Unfun Cat
11

C'est parce que c'est à l'intérieur d'une macro. Une macro doit renvoyer un formulaire Lisp, qui à son tour est évalué.

Par exemple, en regardant la première invocation de cette macro:

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

Nous avons besoin de l'extension pour contenir:

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

c'est ce qui (quote ,cmd)réussit. Si la macro utilisait cmdplutôt plain , elle serait conservée littéralement et l'expansion serait:

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

ce qui est une erreur, car cmdn'est pas défini dans l'environnement où la macro est invoquée.

legoscia
la source
C'est aussi une excellente explication. Merci de l'avoir expliqué.
The Unfun Cat