2012-04-01 (Sun) [長年日記]
_ Feature #6242: Ruby should support lists
RubyはLISPなのでリストをサポートするべきだというチケットを登録。
チケットに添付したパッチでは、Listというクラスを導入して、NilClassとConsをListのサブクラスにしている。
最初、%S(1 2 3)のような形でS式をサポートしようかと思ったけど、このネタ自体を思い付いたのが今日であまり時間もなかったので、 S[1, 2, 3]のような形でお茶を濁してしまった。
ちゃんとしたS式の代りにcons演算子を追加してみた。 Haskellではconsは:、MLやScalaでは::のようだが、Rubyだとどちらも使えないので苦肉の策で:::を使うことにした。 ポイントは右結合であるということで、
1 ::: 2 ::: 3 ::: nil
は、
1 ::: (2 ::: (3 ::: nil))
という意味になる。
もう一つのポイントは、右側のオペランドがレシーバに、左側のオペランドが引数になるということ(たしかScalaがそうしていたと思う)。 つまり、上の式は、
(nil.:::(3)).:::(2).:::(1)
という意味になる。 左側をレシーバにすると、Objectに:::メソッドを追加しないといけなくなるし、ユーザ定義のリストクラスを作った時に:::を使えない。
後でfoldl/foldrを追加して、foldl/foldrを使って+, flatten/concat, map, flat_map/concat_map, filter, length/size, sum, reverseなどのメソッドを定義してみたが、Ruby(というかCだけど)で関数プログラミングができてなかなか楽しかった。