2009-09-01 8 views
0

Je suis assez nouveau à lisp mais j'ai joué avec ça. J'ai plusieurs problèmes dont j'ai besoin de clarifier. Voici ma petite macro que j'ai définie. Je me demande simplement comment je peux spécifier la fonction à utiliser dans le corps dynamiquement? Dites si je veux utiliser la fonction "+" ou "-" au lieu de "eq", ou même une autre fonction que j'ai définie? Comme je pensais qu'il serait possible de passer le nom de la fonction en paramètre mais cela ne marche évidemment pas. Je reçois également des erreurs variables non liées lorsque je modifie la liste (requête) qui est passée.Comment appeler une fonction particulière en fonction de la variable transmise?

+1

Avez-vous une idée pourquoi cela devrait être une macro et non une fonction? –

+0

Je l'ai changé en fonction et il semble fonctionner correctement. –

Répondre

0

funcall est la réponse! Décidé de simplement le transmettre et utiliser funcall pour évaluer la fonction.

2

Dans le corps de la macro, vous pouvez utiliser toute la bibliothèque d'exécution de Lisp pour générer l'extension réelle. Ainsi, par exemple:

(defmacro transform (query &key (test 'eq)) 
    (let ((row-var (gensym))) 
    `(lambda (,row-var) 
     (,test (nth 1 ,query) (nth 0 (nth 0 ,row-var)))))) 

Cette version utilise la « backtick » au lieu d'une simple apostrophe, qui permet de « unquoting » des formes dans le corps, permettant ainsi l'inclusion des formes générées dans le résultat.

Vous pouvez utiliser cette macro comme votre version originale:

(transform (...)) 

ou (passer d'une fonction de test explicite):

(transform (...) :test equal) 

Notez que vous ne devriez pas utiliser des symboles simples comme noms de variables extensions de macro (comme votre ligne argument à l'expression lambda généré) car cela pourrait accidentellement interférer avec l'utilisation de ce symbole sur le site de l'utilisation de votre macr o. Vous ne savez tout simplement pas quand vous écrivez votre macro, il y aura une variable appelée ligne quelque part lorsque votre macro est utilisée, et si elle n'est pas déjà utilisée dans la requête formulaire/expression. Votre définition originale "capture" la variable, en modifiant éventuellement la signification de ce que fait requête.

Questions connexes