2009-11-10 4 views
3

Comment puis-je corriger la macro simple foo dans (elisp)Eval During Expansion?eval lors de l'expansion de la macro lisp emacs

Aucun des travaux de followings:

(defmacro foo1 (a) 
    `(setq (eval ,a) t)) 

(defmacro foo2 (a) 
    `(setq ,(eval a) t)) 

(defmacro foo3 (a) 
    `(setq ,a t)) 

Je ne comprends pas ce qui est dit dans (elisp)Eval During Expansion. Je pense que si j'avais compris, j'aurais pu réparer la macro.

Mise à jour: La solution de Huaiyuan fonctionne:

(defmacro foo7 (a) 
    `(set ,a t)) 

(setq x 'b 
     a 'c) 

(foo7 x) 
(assert (eq b t)) 
(assert (eq x 'b)) 

(foo7 a) 
(assert (eq a 'c)) 
(assert (eq c t)) 

(macroexpand '(foo7 x)) ; ==> (set x t) 
(macroexpand '(foo7 a)) ; ==> (set a t) 

Répondre

2

Essayez

 
(defmacro foo7 (a) 
    `(set ,a t)) 

La sémantique de elisp est souvent accidentelle à la mise en œuvre. Pour un exemple de macro-systèmes bien pensés et clairement spécifiés, je recommande Common Lisp's.

0

Que voulez-vous dire, "fix"?

La page à laquelle vous faites référence montre que la macro ne fonctionne que si vous l'appelez avec un nom qui n'est pas le même que le paramètre macro. Pour résoudre le problème en question, vous pouvez soit modifier la macro pour réduire les opportunités de conflit, soit les utiliser pour éviter tout conflit.

(defmacro foo (aVeryLongAndImprobablyConflictingName) 
    (list 'setq (eval aVeryLongAndImprobablyConflictingName) t)) 
0

Le correctif « droit » est de ne pas nécessiter une évaluation des paramètres fournis par l'utilisateur dans la fonction d'extension macro.

(defmacro foo4 (a) `(setq, t))

Bien que cela ne fait pas la même chose que l'une des foo1, foo2 ou foo3. Quel est le problème que vous essayez de résoudre?

+0

Votre foo4 est identique à foo3. – Yoo

+0

Alors c'est le cas! J'ai même cherché ça! – Vatine