RubyとLisp

ここにさんち、LispRubyに関して他人にもツッコミをいれつつぐじゅぐじゅ書いてきたわけだが、ようやく自分の中で整理できた気がする。ポイントは二つ。
一つ目はRubyの柔軟性 VS Lispのマクロ。
Rubyは(いまさらいうことでもないかもしれないが)、

関数がリストであるというのは確かにとても柔軟だとは思いますが、結局それでやりたいことの多くはRubyでブロックやプロシージャを使ってできるんじゃないだろうかと。

違いと言えば、マクロに相当することをするには、文字列の切り貼りをしてコードを作らなければいけないことだと思ってましたが、MinDI(http://redshift.sourceforge.net/mindi/)等を見てからは、文字列合成を最小限しか使わないメタプログラミングもあるなあと

に示されているように、メタプログラミング*1を可能にする柔軟性をもっている。
特にessaさんが示してくれたRubyでのメタプログラミングの手法はちょっと衝撃的。Rubyでのメタプログラミングは基本的には文字列を切り貼りしてevalするしかないと思ってました。確かにこういう手法をとれば、Lispのマクロに匹敵するかもしれない。
でも、それほどのRubyの柔軟性も一点においてLispのマクロに届かない気がしている。
それがポイントの二つ目、両者の言語の成り立ちの違いだ*2
Rubyオブジェクト指向パラダイムを基礎にしている。オブジェクト指向プログラマがプログラムを書くときの指針を示した枠組でそれ自体高級な土台だ。高級な土台を導入すると、小回りがきかなくて痒いところに手が届かない柔軟性の欠けた言語になりがちだ。でもRubyでは高級な土台に、筋のよい単純な仕組み*3を組みこみ、オブジェクト指向の枠組の中でそれら単純な仕組みを組みあわせることで柔軟性が実現されている。いややっぱりすごいねRuby
一方、Lispが基礎にしているのはλ計算だ。λ計算チューリングマシンとならんで計算可能性を論じることができるほど「プログラム」としてはプリミティブなモデルでしかない。そもそもがLispは低級極まるところから出発し、それに最小限のもの以外は加えないことで柔軟性を実現している。そのいさぎよさは真似できませんよLisp.
つまり、Rubyはある程度高級な土台を提供しておいて、さらにその隙間を埋めるような柔軟な手段を提供することで柔軟性を実現し、Lispは最低級な部品しか提供していないことで柔軟性を実現している。アプローチとしては全く逆だ。
もともと何も無いLispと、土台から掘りさげているRuby。この二つを比較すれば、もともと何も無いところからスタートしているLispのほうが究極的には柔軟なのではないか、というのが先に言った「一点」。言い換えると、Rubyで柔軟性を追及していくと、オブジェクト指向の枠組が邪魔になることがあるんじゃないか、ということ。

でもこれは、あくまで僕の印象でしかないので、本当は差がないかもしれないし、差があったとしても実用的には問題ではないかもしれない。そもそもどうやって差を測ればいいのかさえよくわかってないし。

というわけで僕の結論としての今後の方針は、Lispのマクロ手法をお手本にしつつ、Rubyでのメタプログラミングの手法を磨く、ということになりました。

*1:新しいプログラミング言語をその言語の上に構築してしまうこと、かな?

*2:この点は結局、http://d.hatena.ne.jp/sshi/20050407/p1で書いたことのいいかえに過ぎないかも

*3:ブロックとかevalとか