Rubyを輝かせる要因の1つは、次のようなドメイン固有言語を作成する能力です。
これらのライブラリはマクロを介してLISPで複製できますが、Rubyの実装はよりエレガントだと思います。それでも、LISPのマクロはRubyのマクロよりも優れている場合があると思いますが、LISPのマクロは考えられませんでした。
それで、もしあれば、DSLを作成するRubyの「能力」よりもLISPのマクロの方が優れているのはどの領域ですか。
更新
現代のプログラミング言語は LISPの特異点に近づく なので、これを尋ねました。
LISPのマクロが特別な場合にのみ適用可能であり、他のプログラミング言語の機能が抽象化を高めて今日のソフトウェア開発の課題に対処するのに十分強力であるかどうか疑問に思いました。
LISPの場合 を読んでから、自分で決めてください。
私の要約は、Rubyは、便利な構文を提供するのに優れています。しかし、LISPは、新しい抽象化を作成し、抽象化に抽象化を重ねる能力に勝っています。しかし、LISPを見る必要があります実際にはその点を理解するために、本がお勧めします。
RubyのDSLオーサリング機能は、言語の性質を変えません。 Rubyのメタプログラミング機能は、本質的にRuby構文とセマンティクスに関連付けられており、作成したものはすべてRubyのオブジェクトモデルに入れ替える必要があります。
マクロが抽象プログラム自体に作用するLISP(およびScheme、マクロ機能 differ )とは対照的です。 LISPプログラムはLISP値であるため、マクロは本質的に任意の構文を別の構文にマッピングする関数です。
事実上、Ruby DSLはまだRubyのように感じます)が、LISP DSLはLISPのように感じる必要はありません。
RubyのDSLはDSLではありません。それらのドキュメントは、実際にどのように機能するかについて完全に記述されているため、使用することは絶対に嫌いです。たとえば、ActiveRecordを取り上げてみましょう。これにより、モデル間の関連付けを「宣言」できます。
class Foo < ActiveRecord::Base
has_one :bar
has_one :baz
end
しかし、この「DSL」の宣言性(Rubyのclass
構文自体の宣言性と同様)は、Ruby "DSLs"が実際にどのように機能するかを理解している人なら誰でもわかるような恐ろしい嘘です作業:
class Foo < ActiveRecord::Base
[:bar,:baz,:qux,:quux].each do |table|
has_one table if i_feel_like_it?(table)
end
puts "Just for shits and giggles, and to show"
puts "just how fucked up Ruby really is, we're gonna ask you"
puts "which SQL table you want the Foo model to have an"
puts "association with.\n"
puts "Type the name of a table here: "
has_one gets.chomp.to_sym
end
(LISP defclass
フォームの本体内のそれに何かcloseしてみてください!)
上記のようなコードがコードベースにあるとすぐに、プロジェクトのすべての開発者はRuby DSLsactually(彼らが作成した錯覚だけでなく)コードを保守する前に作業します。利用可能なドキュメントは、イディオマティック使用法。宣言的な錯覚を保持します。
RSpecは、デバッグに大規模なリバースエンジニアリングを必要とする奇妙なEdgeケースがあるため、上記よりもさらに悪いです。 (私のテストケースの1つがスキップされた理由を理解するために丸一日費やしました。RSpecがコンテキストaftercontext
メソッドはブロックを通常とは異なるデータ構造に配置するため、ソースに表示される順序に関係なく、コンテキストのないテストケース。)
LISP DSLは、小さなコンパイラであるマクロによって実装されます。この方法で作成できるDSLは、LISPの既存の構文の単なる悪用ではありません。それらは独自の文法を持つことができるので、完全にシームレスに書くことができる実際のミニ言語です。たとえば、LISPのLOOP
マクロは、Rubyのeach
メソッドよりもはるかに強力です。
(私はあなたがすでに回答を受け入れたことを知っていますが、これを読んだ人全員がOn LISPの全体を読みたがるわけではありません。)