LISPはS式(丸括弧)でできている、RubyはR式[角括弧]でできている
なぜRubyは許容可能なLISPなのか - 翡翠はコンピュータに卵を生むか
著者は
という事実から
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である
と結論する次第である
以上