8回にわたってお届けしてきたこのシリーズも、いよいよ最終回。今回はその他の新しい機能、さらに、まつもとさんの口からは次のバージョンの話も飛び出します。
ラムダ
目立つ機能としては、「->
」によるラムダ(λ
)を入れたり、「.()
」による呼び出しを入れたということですね、やっぱり関数型言語の影響が大きく、ラムダをこんな記号(->
)で導入しました。
― まずこの話があったときは、まず最初に何があったかというと、「ラムダ」って書きづらいと。
1.8だとラムダメソッドってのがあって、lambdaだっけ、(綴りに)自信がないけど。Lispの人たちはそれこそ湯水のように使うけれど、普通のプログラマにはなじみがないし、読みにくい、書きにくい、長いメソッド名どうよって話があって。
あと、メソッドって再定義できるじゃないですか。「lambda
」って書いても、本当にラムダを返すのか自信がない。ラムダじゃないものが返せてしまうかもしれない。いろんな最適化のことを考えると、こういうものは言語組み込みであった方がうれしいよねって思って、この2点から新しい記法を取り入れました。
ただエライ不評で、「この記号λ
に見えないじゃん」って。ターミナルっぽいフォントで表示して横に傾けるとλ
に見える、って言うとみんな笑ってくれるけど、それでも迫害は止まらないんです。
これがラムダです。Perl 6も同じ記号でラムダなので、Perl 6が何時か出たら(市民権が得られる)。これを最初取り入れたときは、Perl 6がRuby 1.9より先に出るかなと思っていたんですけど、全然そんなことなかったですね。
YARV
それからYARV。実装の話ですけど、バイトコードエンジンですよね。インタプリタの中心的部分を新しいものに差し替えました。僕よりもっと頭のいい人が書いているので、頭の良さの差の分だけ早くなっています。
― このバイトコードっていう話もずっとあって、M17Nと同じくらいから二本柱としてやってましたね。
頑張りましたけど、僕は力尽きました。力尽きたところでささだくんがやって来たのでラッキーと。ささだくんという、現在東大の講師のひとがVM化しただけで、倍速くなりました。
「コア性能最大50倍」、これを最初に出したとき、横にささだくんがいて「そんなデマは口に出さないでください」って怒られました。ホントは50倍じゃない。でもベンチマークは結構良くなっていて。
YARVで良くなるのはコアの性能で、例えばforループを回す時間とか、フィボナッチが速くなるとか、そういうのはありますけれど、例えばStringメソッドの文字列探索の時間とか、ガーベジコレクションの時間とか、そういうのは変わらない訳です。その辺はあまりいじってないので。だからそういうものがボトルネックになっているプログラムについては、変わらないですね。
― Webアプリ、というかぼくらが普段作っているRailsのアプリとかだと、あまり影響しなさそう。SQLで頑張った方が速くなるかもしれない。
そう、びっくりするほど速くなるわけではない。
そしてRuby 2.0へ
あとはRuby 1.9が出たので、Ruby 2.0やろうかなあと。それで、こんなことやりたいなあということを。まず「キーワード引数」。これは今でも一部呼び出し側はありますけど、受け側もやりたいなあと。
― 呼び出し側というのは?
最後にハッシュを付けてキーワード引数っぽく呼べるようになってるんですけど、受ける方もキーワード引数っぽく受けられるようにしたいなあ。
― つまり、(メソッドの引数に)何とかっていうキーがあって、(それを)この変数に代入して欲しいというコードが書けると。
そう、それを言語に組み込みたいなあと。
― それは便利ですね。
そう、いまはキーワード引数使いたくても、受け側が面倒くさいのでちょっとパスというケースが結構あって、みんな「デフォルトでなければこれをしてください」という処理を、みんな同じように「def foo(opt={})
」と。[1]
― あー、なんかPerl 5と同じようなことしてる気がしますね。
そういうのは非生産的なので、言語仕様をチェンジしたいなと。
あと「セレクターネームスペース」と言ってるんですが、Rubyだとオープンクラスというものがあって、既存のクラスをどんどん書き換えられるわけです。特徴の一つではあるのですけど、前に出てきたString#chars
みたいに名前が重なっちゃったってのもあるし、書き変えちゃったりするとグローバルに迷惑をかけることがある。「整数の+メソッド書き変えちゃって、1 + 1は5になります」とか。そこまで変なのはないかもしれないけど、整数の演算では、1/2はゼロなんですけど、二分の一が欲しいって人もいて、0.5が欲しいって人もいる。
その辺を切り替えるライブラリがあるんですけれど、上手く行く場合だけとは限らない。何が起きるか安易に予測できないので、オープンクラスで行った変更を、ある名前空間なりに閉じ込めたい。ある空間では1/2のメソッドを再定義したので、二分の一を返しますけど、その名前空間の外では相変わらずゼロを返すと。
― わざわざ書き変えているんだから、それを使いたい部分があるわけですよね
そうそう、それを使いたい名前空間では有効なんだけど、切り替えを区分けしたいと。それをNamespaceと(言っている)。セレクタはメソッド名ですよね。同じメソッド名で呼んでも、名前空間によって意味がかわるという概念が、プログラム言語設計の界隈ではいわれているんですけど、ただ今のところ、これをRubyで効率よく実装する方法をまだ思いついていない。やるだけなら今、明日にでもできるんだけれど、Ruby全体がいまより5倍遅くなる。それはちょっと嫌でしょ。そういうことにならないような実装について、これから考えないといけない。
あとPerlっぽい変数がRubyにはいっぱいあるんです。例えば「$/
」とか、「&,
」とか「$:
」とか、とかPerlっぽい変数がいっぱいあるんですが、正直失敗だったと思います。だからもう無くそうと。
あと特異クラスは今のRubyでは隠そう、隠そうとしていてオブジェクトそのものは、なるべく外に見せないようにしようとしています。けど、まあ見えちゃってるんで、いっそあきらめてちゃんと見えるような状態でバランスを再構築できるかもしれないなと。
― 何か前の2つは「やってみたい」機能で、後の2つは「後悔」機能と。
これは思いついたものを4つあげただけで、まだやりたいことはあると思うんです。とりあえず今は1.9に集中しているので、これについてはまだ本気では考えていないです。
1 キーワード引数の実装例は『Rubyスクリプティングテクニック』の16章にも書かれています。