LISPはS式(丸括弧)でできている、RubyはR式[角括弧]でできている
Rubyは許容可能なLISPと言われている。
なぜRubyは許容可能なLISPなのか - 翡翠はコンピュータに卵を生むか
著者は、
- RubyはLISPよりも濃い関数型言語であり。
- LISPマクロでしたいことの大半はRubyでできる。
という事実から、Rubyは許容可能なLISPであると結論している。
しかし私は今日別の理由、つまりRubyがなぜ許容可能なLISPであるのかの新たな解釈を発見した。
私は「許容可能なLISP」とは、LISPerが「LISPの継承者と名乗っても差し支えなかろう」と認めた言語をいうものと理解する。そしてLISPは括弧(S式)でできていることが最大の特徴であることから、括弧を多産しないつまりこれでもかというくらいに括弧が大量に現れない言語は、LISPerをしてLISP継承言語と認められないものと理解する。
Rubyではメソッド定義や呼び出しの括弧を省略できたりするものだから、この点からすればRubyを許容可能なLISPと呼ぶことは到底できない。
しかしそれはRubyの一側面に過ぎない。次のRubyのオブジェクト呼び出しコードを見ていただきたい。
R[:name][:age]['charlie'][21]['charlie'][0][:name][0,4] # => "char"
括弧括弧括弧、括弧だらけである。そしてこれは、Rubyの正しい構文に基づいて書かれており、しかもなんのトリックも施されていない、正真正銘のRubyなのである。
Rubyに覚えのある方は暫し、この呼び出しを実現するオブジェクトの実装を考えていただきたい。
確かにネストした丸括弧と、シーケンシャルな角括弧という違いはあるものの、これだけ括弧を並べることができるなら、Rubyを許容可能なLISPと言っても差し支えないであろう。
このような角括弧の連なり構文が可能なのは、実はRubyにおいて角括弧は再定義可能なメソッド呼び出しに過ぎないからなのである。
class Hash
def [](arg)
"I don't know."
end
end
h = {:name => 'charlie', :age => 21}
h[:name] # => "I don't know."
つまりこれは多数のクラスが各クラスの文脈に基づいて、角括弧メソッドを自由に定義し得るということを意味する。もちろん独自クラスにも角括弧を定義できる。
class CALC
def self.[](exp)
eval exp
end
end
CALC['40 - 32 / 2'] # => 24
さてそろそろ先のコードの実装を示そう。もちろん独自の角括弧メソッドの定義などはしていない。
R = ->a,b{
_ = Struct.new(a, b)
->x,y{ Hash[x, Array[ _[x, y] ]] }.curry
}.curry
R[:name][:age]['charlie'][21]['charlie'][0][:name][0,4] # => "char"
どうであろう。ここでも多数の角括弧が使われていることが見て取れる。しかもネストしている。ここで使われている角括弧は、Hash.[ ] Array.[ ] Struct.[ ]である。
説明すると定数Rはカリー化されたProcオブジェクトを参照している。このProcオブジェクトは2つの引数a,bを取り、カリー化されたProcオブジェクトを返す。このProcオブジェクトは2つの引数x,yを取りハッシュを返す。ハッシュはxをkey、配列をvalueとする。配列の要素はa,bをプロパティとするStructのサブクラス_から生成される、x,yを値とするStructオブジェクトである。
そしてRの呼び出し側において、最初の4つの括弧[:name][:age][‘charlie’][21]はProc#[ ]メソッドを呼んでいる。次の括弧[‘charlie’]はHash#[ ]を、次の括弧[0]はArray#[ ]を、次の括弧[:name]はStruct#[ ]を、最後の括弧[0,4]はString#[ ]をそれぞれ呼んでいる。
各角括弧の返り値を見れば理解が容易になるだろう。
R # => #<Proc:0x0000010085dc88 (lambda)>
R[:name] # => #<Proc:0x0000010085cec8 (lambda)>
R[:name][:age] # => #<Proc:0x0000010085c888 (lambda)>
R[:name][:age]['charlie'] # => #<Proc:0x0000010085c108 (lambda)>
R[:name][:age]['charlie'][21] # => {"charlie"=>[#<struct name="charlie", age=21>]}
R[:name][:age]['charlie'][21]['charlie'] # => [#<struct name="charlie", age=21>]
R[:name][:age]['charlie'][21]['charlie'][0] # => #<struct name="charlie", age=21>
R[:name][:age]['charlie'][21]['charlie'][0][:name] # => "charlie"
R[:name][:age]['charlie'][21]['charlie'][0][:name][0,4] # => "char"
このようなことから私は、Rubyにおける角括弧をR式と命名し、RubyがR式でできている、したがって”Rubyは許容可能なLISPである”と結論する次第である。
以上
(comment)
>推論が妥当でないように思われます.
媒概念不周延の虚偽と呼ばれる詭弁ではないでしょうか.
»m11mさん
コメントありがとうございます。ええ、そのとおりなんです。推論が妥当であったらネタになりませんからね。
ネタでしたか.
失礼しました. >m11mさん
いえ、いえ:)
blog comments powered by Disqus