Una de las cosas que hace brillar a Ruby es la capacidad de crear mejores lenguajes específicos de dominio, como
Aunque uno puede duplicar estas bibliotecas en LISP a través de macro, creo que la implementación de Ruby es más elegante. No obstante, creo que hay casos en que la macro de LISP puede ser mejor que la de Ruby, aunque no se me ocurre ninguno.
Entonces, ¿en qué área es mejor la macro de LISP que la "capacidad" de Ruby para crear DSL, si la hay?
actualizar
He preguntado esto porque los lenguajes de programación modernos se están acercando a la singularidad de LISP , como
- C obtuvo un preprocesador de expansión macro , aunque muy primitivo y propenso a errores
- C # tiene atributos, aunque este es de solo lectura, expuesto a través de la reflexión
- Python agregó decorador, que puede modificar el comportamiento de la función (y la clase para v 3.0), aunque se siente bastante limitado.
- Ruby TMTOWTDI que hace DSL elegante, si se aplica el cuidado, pero de manera Ruby.
Me preguntaba si la macro de LISP solo es aplicable a casos especiales y si las otras características del lenguaje de programación son lo suficientemente potentes como para aumentar la abstracción para enfrentar los desafíos actuales en el desarrollo de software.
Respuestas:
Lee en Lisp y luego decide por ti mismo.
Mi resumen es que Ruby es mejor para proporcionar una sintaxis conveniente. Pero Lisp gana, sin lugar a dudas, en la capacidad de crear nuevas abstracciones, y luego en capas de abstracción sobre abstracción. Pero necesita ver a Lisp en la práctica para comprender ese punto. De ahí el libro lo recomiendo.
fuente
But Lisp wins, hands down, at the ability to create new abstractions, and then to layer abstraction on abstraction.
Ahora se porque. . .Las instalaciones de Ruby para la creación de DSL no cambian la naturaleza del lenguaje. Las instalaciones de metaprogramación de Ruby están inherentemente ligadas a la sintaxis y la semántica de Ruby, y lo que sea que escriba debe derivarse al modelo de objetos de Ruby.
Compare eso con Lisp (y Scheme, cuyas instalaciones macro difieren ), donde las macros operan en el programa abstracto en sí. Debido a que un programa Lisp es un valor Lisp, una macro es una función que asigna una sintaxis esencialmente arbitraria a otra.
Efectivamente, un DSL Ruby todavía se siente como Ruby, pero un DSL Lisp no tiene que sentirse como Lisp.
fuente
Los DSL de Ruby no son DSL en absoluto, y odio absolutamente usarlos porque su documentación carece de cómo funcionan realmente. Tomemos ActiveRecord por ejemplo. Le permite "declarar" asociaciones entre modelos:
Pero la declaración de este "DSL" (como la declaración de la
class
sintaxis de Ruby en sí) es una mentira horrible que puede ser expuesta por cualquiera que entienda cómo funcionan realmente los "DSL" de Ruby:(¡Solo intenta hacer algo parecido a eso dentro del cuerpo de un
defclass
formulario Lisp !)Tan pronto como tenga un código como el anterior en su base de código, cada desarrollador en el proyecto debe comprender completamente cómo funcionan realmente las DSL de Ruby (no solo la ilusión que crean) antes de que puedan mantener el código. La documentación disponible será completamente inútil, ya que solo documentan el uso idiomático , que preserva la ilusión declarativa.
RSpec es incluso peor que lo anterior, porque tiene casos extremos extraños que requieren una extensa ingeniería inversa para depurar. (Pasé todo un día tratando de averiguar por qué se saltaba uno de mis casos de prueba. Resultó que RSpec ejecuta todos los casos de prueba que tienen contextos después de los casos de prueba sin contexto, independientemente del orden en que aparecen en la fuente , porque el
context
método coloca su bloque en una estructura de datos diferente de la que normalmente entraría).Los DSL de Lisp son implementados por macros, que son pequeños compiladores. Las DSL que puede crear de esta manera no son meros abusos de la sintaxis existente de Lisp. Son mini idiomas reales que se pueden escribir para que sean completamente fluidos, porque pueden tener su propia gramática. Por ejemplo, la
LOOP
macro de Lisp es mucho más poderosa que eleach
método de Ruby .(Sé que ya has aceptado una respuesta, pero no todos los que lean esto querrán leer la totalidad de On Lisp ).
fuente