L'une des choses qui fait briller Ruby est la possibilité de mieux créer des langages spécifiques au domaine, comme
Bien que l'on puisse dupliquer ces bibliothèques dans LISP via une macro, je pense que l'implémentation de Ruby est plus élégante. Néanmoins, je pense qu'il y a des cas où la macro de LISP peut être meilleure que celle de Ruby, bien que je ne puisse pas en penser un.
Alors, dans quel domaine la macro de LISP est-elle meilleure que la "capacité" de Ruby à créer DSL, le cas échéant?
mise à jour
Je l'ai demandé parce que les langages de programmation modernes approchent de la singularité LISP , comme
- C a un préprocesseur d'extension de macro , bien que très primitif et sujet aux erreurs
- C # a des attributs, bien que ce soit en lecture seule, exposé par réflexion
- Python a ajouté un décorateur, qui peut modifier le comportement de la fonction (et de la classe pour la version 3.0), mais semble assez limité.
- Ruby TMTOWTDI qui rend DSL élégant, si des soins sont appliqués, mais de manière Ruby.
Je me demandais si la macro de LISP n'est applicable qu'à des cas spéciaux et que les autres fonctionnalités du langage de programmation sont suffisamment puissantes pour élever l'abstraction pour relever les défis actuels du développement logiciel.
Réponses:
Lisez sur Lisp et décidez par vous-même.
Mon résumé est que Ruby est mieux à même de fournir une syntaxe pratique. Mais Lisp gagne, haut la main, à la capacité de créer de nouvelles abstractions, puis de superposer l'abstraction sur l'abstraction. Mais vous devez voir Lisp en pratique pour comprendre ce point. D'où le livre recommande.
la source
But Lisp wins, hands down, at the ability to create new abstractions, and then to layer abstraction on abstraction.
Maintenant je sais pourquoi. . .Les installations de Ruby pour la création DSL ne changent pas la nature de la langue. Les installations de métaprogrammation de Ruby sont intrinsèquement liées à la syntaxe et à la sémantique de Ruby, et tout ce que vous écrivez doit être shunté dans le modèle objet de Ruby.
Comparez cela avec Lisp (et Scheme, dont les fonctionnalités de macro diffèrent ), où les macros opèrent sur le programme abstrait lui-même. Parce qu'un programme Lisp est une valeur Lisp, une macro est une fonction mappant une syntaxe essentiellement arbitraire à une autre.
En effet, un Ruby DSL ressemble toujours à Ruby, mais un Lisp DSL n'a pas à se sentir comme Lisp.
la source
Les DSL de Ruby ne sont pas du tout des DSL, et je déteste absolument les utiliser parce que leur documentation repose sur leur fonctionnement réel. Prenons l'exemple d'ActiveRecord. Il vous permet de «déclarer» des associations entre les modèles:
Mais le caractère déclaratif de ce "DSL" (comme le caractère déclaratif de la
class
syntaxe de Ruby elle-même) est un horrible mensonge qui peut être exposé par quiconque comprend comment les "DSL" Ruby fonctionnent réellement:(Essayez simplement de faire quelque chose de proche dans le corps d'un
defclass
formulaire Lisp !)Dès que vous avez du code comme celui-ci dans votre base de code, chaque développeur du projet doit comprendre pleinement comment les DSL Ruby fonctionnent réellement (et pas seulement l'illusion qu'ils créent) avant de pouvoir maintenir le code. La documentation disponible sera totalement inutile, car elle ne documente que l' usage idiomatique , ce qui préserve l'illusion déclarative.
RSpec est encore pire que ce qui précède, car il a des cas de bord bizarres qui nécessitent une ingénierie inverse approfondie pour déboguer. (J'ai passé une journée entière à essayer de comprendre pourquoi l'un de mes cas de test était ignoré. Il s'est avéré que RSpec exécute tous les cas de test qui ont des contextes après des cas de test sans contexte, quel que soit l'ordre dans lequel ils apparaissent dans la source , car la
context
méthode place votre bloc dans une structure de données différente de celle qu'il utiliserait normalement.)Les DSL Lisp sont implémentés par des macros, qui sont de petits compilateurs. Les DSL que vous pouvez créer de cette façon ne sont pas de simples abus de la syntaxe existante de Lisp. Ce sont de véritables mini-langues qui peuvent être écrites de manière totalement transparente, car elles peuvent avoir leur propre grammaire. Par exemple, la
LOOP
macro de Lisp est beaucoup plus puissante que laeach
méthode de Ruby .(Je sais que vous avez déjà accepté une réponse, mais tous ceux qui liront ne voudront pas lire l'intégralité de On Lisp .)
la source