web-dev-qa-db-fra.com

Qu'en est-il de Lisp, si quelque chose facilite la mise en œuvre de systèmes de macro?

Je suis un schéma d'apprentissage à partir du SICP Et j'ai l'impression qu'une grande partie de ce qui fait du programme et, encore plus, Lisp Special est le Système macro. Mais, étant donné que les macros sont élargies à la compilée, pourquoi les gens ne font-ils pas que les systèmes de macro équivalents pour C/Python/Java/Peuvent? Par exemple, on pourrait lier la commande python à expand-macros | python ou peu importe. Le code serait toujours portable aux personnes qui n'utilisaient pas le système de macro, on développerait simplement les macros avant de publier le code. Mais je ne sais rien de tel que cela sauf des modèles en C++/Haskell, que je recueillis n'est pas vraiment identique. Qu'en est-il de Lisp, si quelque chose facilite la mise en œuvre de systèmes de macro?

21
Elliot Gorokhovsky

Je suis un programme d'apprentissage du SICP et j'ai l'impression qu'une grande partie de ce qui fait du programme et, encore plus, LISP Special est le système macro.

Comment? Tout le code dans SICP est écrit dans un style macro-free. Il n'y a pas de macros dans SICP. Seulement dans une note de bas de page à la page 373 sont des macros jamais mentionnées.

Mais, étant donné que les macros sont élargies au moment de la compilation

Ils ne sont pas nécessairement. LISP fournit des macros dans les deux interprètes et les compilateurs. Ainsi, il pourrait ne pas y avoir de temps de compilation. Si vous avez un interprète LISP, les macros sont élargis au moment de l'exécution. Étant donné que de nombreux systèmes LISP ont un compilateur à bord, on peut générer du code et la compiler au moment de l'exécution.

Testons d'utiliser SBCL, une implémentation commune des LISP.

Commissons SBCl à l'interprète:

* (setf sb-ext:*evaluator-mode* :interpret)

:INTERPRET

Maintenant, nous définissons une macro. La macro imprime quelque chose quand il est appelé pour le code élargi. Le code généré n'imprime pas.

* (defmacro my-and (a b)
    (print "macro my-and used")
    `(if ,a
         (if ,b t nil)
         nil))

Utilisons maintenant la macro:

MY-AND
* (defun foo (a b) (my-and a b))

FOO

Voir. Dans la case ci-dessus, LISP ne fait rien. La macro n'est pas étendue au temps de définition.

* (foo t nil)

"macro my-and used"
NIL

Mais au moment de l'exécution, lorsque le code est utilisé, la macro est élargie.

* (foo t t)

"macro my-and used"
T

Encore une fois, au moment de l'exécution, lorsque le code est utilisé, la macro est élargie.

Notez que SBCL ne se développerait qu'une seule fois lors de l'utilisation d'un compilateur. Mais diverses implémentations LISP fournissent également des interprètes - comme SBCL.

Pourquoi les macros sont-elles faciles dans Lisp? Eh bien, ils ne sont pas vraiment faciles. Seulement dans Lisps, et il y en a beaucoup, qui ont un support macro intégré. Puisque de nombreux LISP disposent de vastes machines pour les macros, on dirait que c'est facile. Mais les mécanismes de macro peuvent être extrêmement compliqués.

3
Rainer Joswig

homoiiconicité facilite beaucoup la mise en œuvre de macros. L'idée que le code est des données et des données est un code permettant de plus ou moins (sauf capture accidentelle d'identificateurs, résolue par macros hygiéniques ) à substituer librement l'un pour l'autre. Les LISP et le schéma facilitent cela avec leur syntaxe de S-expressions spécialement structurées et donc faciles à transformer en asts qui forment la base de macros syntaxiques .

Les langues sans S-expressions ou homoiconicité se dérouleront dans des difficultés à mettre en œuvre des macros syntaxiques, bien que cela puisse toujours être fait. Project Kepler tente de les initier à Scala par exemple.

Le problème le plus important avec l'utilisation de la syntaxe Macros en dehors de la non-homoiconicité, est la question de la syntaxe générée arbitraire. Ils offrent une flexibilité et une puissance énormes, mais au prix que votre code source ne peut plus être aussi facile à comprendre ni à maintenir.

1
World Engineer