Désolé pour le titre maladroit, mais j'ai du mal à décrire ce que je cherche en quelques mots ... p>
Je travaille sur un projet COMMON LISP DSL et je vous demande si ce qui suit est possible: p>
Le DSL pourrait avoir quelques fonctions p>
et p>
qui sera utilisé de la manière suivante: p>
Maintenant, c'est beaucoup de taper redondant, alors je me demande s'il est possible de créer une macro Expander
ça va permettre p>
sans changer (défunteur FOO (et reste de repos)) code> p>
(barre de défunement (arg)) code> p>
(FOO (barre 100) (barre 200) (barre 300) (barre 400) (barre 500)) code> etc. p>
(FOO (Développer la barre 100 200 300 400 500)) Code> P>
foo code> lui-même? p>
3 Réponses :
Il n'y a pas besoin de macro:
Hmm true, en utilisant appliquer code> est toujours une option, même si je me demandais si c'était possible sans. Dans le contexte, je pense que cela serait plus intuitif si vous pouviez utiliser la même fonction (la DSL est destinée aux personnes qui ne connaissent pas vraiment CL en soi)
"HMM True, l'utilisation d'applications est toujours une option" - pas toujours, uniquement pour les fonctions, pas pour les macros. ;-)
Non, cela ne peut pas être fait sans changer la signature des fonctions que vous définissez (ou éventuellement à l'aide d'une chose velue qui redéfinit la macroexpansion): vous avez ce que j'appelle une incidence d'impédance «Spread / Noscread Impédation» qui ne peut pas Soyez résolu avec une macro standard dans cl.
une fonction 'nosplead' est une fonction qui enveloppe tous ses arguments en une formelle. Une fonction «spread» a un argument formel par argument. J'ai appris ces termes lors de l'utilisation interlisp: ils peuvent le prédire, mais ils semblent être surtout inutilisés maintenant. Les fonctions CL peuvent être uniquement partiellement nosplead ( A Votre problème est que en particulier, dans cl une expression comme Dans votre cas, vous voulez quelque chose comme p> se transformer en p> et Cela ne peut pas arriver. P> Il y a eu des Lisps qui avaient été des choses qui avaient appelé des «macros d'épissage» dans lesquelles une expansion d'une macro pourrait être «épissée» dans une liste, de la manière dont (foo bar & repos plus) code>). Votre
foo code> est NOSPREAD. P>
appliquer code>. P>
foo code> est une fonction nosplead: il transforme tous ses arguments en une liste , mais vous voulez que la macro la traite comme une fonction de propagation, ce qui lui remet une liste unique d'arguments. p>
(x (Y ...)) / code> ne peut jamais être transformé en
(x a1 a2 ...) code> pour tout
y code>, fonction ou macro (mais voir ci-dessous), et c'est ce dont vous avez besoin pour arriver. p>
code> fait pour BackQuote. Il est peut-être qu'il existe des packages macro épisseurs pour cl, et il peut même être qu'ils sont portables: vous pouvez avoir un long chemin avec
* macroexpand-crochet * code>. Mais les macros CL standard ne peuvent pas faire cela. P> p>
Hein, merci pour la réponse détaillée et merci pour la mise à jour de la terminologie. Cela étant dit, à la recherche d'un paquet tourné deux qui semblent faire exactement ce que vous décrivez: QuickRef.common-lisp.net/cl-splicing-macro.html et QuickRef.common-lisp.net/quasiquote-2.0.html
@Ellipsenpark: Oui, j'étais vaguement conscient de cela. Autant que je sache, il utilise * macroexpand-hameçon * code> pour faire son travail. Il m'empêche un peu que cl ne possède pas plus de variables de crochet comme ça, comme ils sont très flexibles: j'ai suggéré une fois que les implémentations pouvaient être d'accord sur les quasi-standard, mais les gens ne l'aimaient pas, alors j'ai abandonné
Il peut être utile de scinder votre DSL en deux parties, une version plus simple que vous programmez contre et une version plus conviviale. Par exemple: