Одна из вещей, которая делает Ruby сиять, - это возможность создавать доменные языки лучше, например,
Хотя можно скопировать эти библиотеки в LISP с помощью макроса, я думаю, что реализация Ruby более элегантна. Тем не менее, я думаю, что есть случаи, когда макрос LISP может быть лучше, чем макрос Ruby, хотя я не мог придумать ни одного.
Итак, в какой области макрос LISP лучше, чем «способность» Руби создавать DSL, если таковая имеется?
Обновить
Я спросил об этом, потому что современные языки программирования приближаются к сингулярности LISP , например
- C получил препроцессор расширения макросов , хотя и очень примитивный и подверженный ошибкам
- C # имеет атрибуты, хотя это только для чтения, через отражение
- Python добавил декоратор, который может изменить поведение функции (и класса для v 3.0), хотя и чувствует себя довольно ограниченным.
- Ruby TMTOWTDI, который делает элегантный DSL, если применяется осторожность, но в Ruby.
Мне было интересно, применим ли макрос LISP только к особым случаям и что другие функции языка программирования достаточно мощны, чтобы поднять абстракцию для решения задач, стоящих сегодня в разработке программного обеспечения.
Ответы:
Читайте на Лиспе и решайте сами.
Я хочу сказать, что Ruby лучше предоставляет удобный синтаксис. Но Лисп побеждает, умело создавая новые абстракции, а затем накладывая абстракцию на абстракцию. Но вам нужно увидеть Лисп на практике, чтобы понять этот момент. Отсюда и книга рекомендую.
источник
But Lisp wins, hands down, at the ability to create new abstractions, and then to layer abstraction on abstraction.
Теперь я знаю почему. , ,Возможности Ruby для создания DSL не меняют природу языка. Средства метапрограммирования Ruby неразрывно связаны с синтаксисом и семантикой Ruby, и все, что вы пишете, должно быть добавлено в объектную модель Ruby.
Сравните это с Lisp (и Scheme, чьи возможности макросов отличаются ), где макросы работают с самой абстрактной программой. Поскольку программа на Лиспе - это значение на Лиспе, макрос - это функция, отображающая один по существу произвольный синтаксис в другой.
По сути, Ruby DSL все еще ощущается как Ruby, но Lisp DSL не должен чувствовать себя как Lisp.
источник
DSL в Ruby вовсе не являются DSL, и я совершенно не люблю их использовать, потому что их документация прямо показывает, как они действительно работают. Давайте возьмем ActiveRecord для примера. Это позволяет вам «объявлять» ассоциации между моделями:
Но декларативность этого «DSL» (как и декларативность самого
class
синтаксиса Ruby ) - ужасная ложь, которую может разоблачить любой, кто понимает, как на самом деле работают «DSL» в Ruby:(Просто попробуйте сделать что-нибудь близкое к этому в теле
defclass
формы Lisp !)Как только у вас есть код, подобный приведенному выше, в вашей кодовой базе, каждый разработчик проекта должен полностью понять, как на самом деле работают Ruby DSL (а не только иллюзия, которую они создают), прежде чем они смогут поддерживать код. Доступная документация будет совершенно бесполезной, потому что они документируют только идиоматическое использование, которое сохраняет декларативную иллюзию.
RSpec даже хуже, чем выше, потому что он имеет причудливые крайние случаи, которые требуют обширного обратного проектирования для отладки. (Я потратил целый день, пытаясь выяснить, почему один из моих тестовых примеров был пропущен. Оказалось, что RSpec выполняет все тестовые случаи, которые имеют контексты после тестовых случаев без контекста, независимо от порядка их появления в источнике потому что
context
метод помещает ваш блок в другую структуру данных, чем обычно.)DSL Lisp реализуются с помощью макросов, которые являются маленькими компиляторами. DSL, которые вы можете создать таким образом, - это не просто нарушение существующего синтаксиса Lisp. Это настоящие мини-языки, которые могут быть написаны как полностью цельные, потому что они могут иметь свою собственную грамматику. Например,
LOOP
макрос в Лиспе намного мощнее, чемeach
метод Руби .(Я знаю, что вы уже приняли ответ, но не все, кто его прочтет, захотят прочесть всю версию On Lisp .)
источник