読者です 読者をやめる 読者になる 読者になる

RubyKaigi 2016に行ってきた

RubyKaigi 2016が京都であるということで、行ってきました。 俺は京都に住んでいて、今回の会場の国際会館には行ったことはないけれど、会社とわりと近いので、行かない理由がない!

この記事は個人用のメモで、RubyKaigiってどんなところだろうとか、どんな内容が話されていたのか気になっている人には役に立ちません。時間を無駄にしたい人だけ読もう。

RubyKaigiとは

RubyKaigiはいいぞ

Ruby3 Typing

Matzの話。最近は静的型付け言語が流行っていて、動的型付けのRubyオワコンだよねみたいな風潮が嫌なので新しいことをしたいという話。 俺はよく知らなかったので、タイプヒンティングみたいなのが入るのかなーと思っていた。

class Duck
  def bake(Fire f) -> Coal
  end
end

class IMac < Computer
  def bake(Fire f) -> DropBox
  end
end

def ahiruyaki(Duck duck) -> Coal
  duck.bake
end

そもそもbakeメソッドを実装していればあひるでなくても焼けるのがDuck Typingで、型を固定するとIMacを焼くことができない。戻り値も共通のスーパクラスがない。

俺は「とはいえ想定しない型を渡されても困るから、表明したほうが良いのでは?」と以前は思っていて、だからmikutterでも type_strict というユーティリティメソッドがある。しかし長くメンテナンスを続けていって、いろんな機能拡張を行っていくにつれ、「type_strictさえなければ動くのに!」ということがしばしば発生してる。短期的には型を指定するのは一見悪くないんだけど、長く使うコードだと癌になるということを身をもって体験しているところだった。

とはいえ型がなければ、そもそも短期的に事故る、そこをどうするか。Rubyでは全ての値はオブジェクトで、全てが何らかのクラスのインスタンスなので、型=クラスと考えている時期が私にもありましたけれど、型というのは同じ振る舞いをする集団であって、クラスではない。IMacもDuckも、bakeできるという意味においては同じ型で、このことを踏まえればDuck Typingによってどんなクラスでも引数として受け取れるメソッドは、特定の型のオブジェクトのみを受け入れているにすぎないと言える、のかな。タイプヒンティングはクラスと型を取り違えていて、少なくともRubyにとってはあまりよい手ではなさそう。クラスを限定すると、不必要なものを要求してしまう。joinメソッドさえあればいいのに、Arrayであることを要求してしまうとか。過不足無く要求を明示できれば、安全且つ将来にわたって拡張性を担保できる。

MatzはGolangインターフェイスを取り上げて、あれはかなり上手くやっている方だと言っていた。確かにあの仕組みだと、クラスではなく型自体を明確に要求できて良い。そのGolangにMatzが「おしい!」と言っていた点は確か:

という点だったと思う。「名前を決めるのはめっちゃ大変」というのはかなり同意できて、日本語だったとしても、一言で説明できないと思うことは結構多い。今のRubyではこういう検査機構は無くて、型がほしいという人が本当に意味しているのはこういった検査機構がほしいということだと思う。型を静的に書くためには名前をつける必要がある。「絶対に型は書きたくない!」というフレーズがやたらと取り上げられているけれど、俺は「型の名前を考えたくない!」というのがその真意だと受け取った。確かにロジックは頭のなかに出来上がってるのに名前で迷ってしまって手が止まるということはよくあるので、名前を考える機会を増やさずにいくらかでもその恩恵に肖ることができるなら嬉しい。

ここからは俺の知識では正確な意味を捉えかねる部分だった。今時だと俺が使った中ではPHP Stormとかは静的にコードを解析して、かなり正確に要求される型を予測して、静的にエラーとなりそうな箇所を教えてくれる。Rubyは動的にメソッドを追加・削除することができてしまうのでこれが難しい。そんな中でもJavaScriptとかはわりと頑張ってるんだけど、動的になればなるほど静的な解析には限界があるなあと思う。

しかし何らかの方法で、あるメソッドが書き換えられてないと分かってしまえば、その部分については予想できる。完全ではないが、現代のRubyでは実行時にしかわからないエラーのうちのいくつかが、実行前にわかるのではないか。100%は無理だが、8割、5割でも分かれば、今より良いよね、という趣旨のことを言っていたのだと思う。

実行前というのはコンパイル時かというとそういうわけでもないようで、Gemとかには静的解析した結果みたいなファイルをつけておいて、そのファイルがRubyランタイムやIDEから利用できれば良さそうという言及があった。これは確かTypeScriptにそんなのがあったなーと思いながら聞いていたけれど、これは実際にはぜんぜん違うものを意図しているのかもしれない。

値というのはメモリ上のビット列に過ぎず、それがどういった値なのかを説明するのが型だったが、それはコンピュータの都合だったのでなんやかんやあって動的型が流行り、しかし最近は型推論が強くなったりマシンスペックが上がってIDEがいろいろと助けてくれるとかもあって、これからは静的型が優勝なんだなあと俺は思っていた。一方Matzはもっと長い目でこの流れを見ていて、Ruby3.0が出る頃にはまた動的型付けにボールが戻って来ているかもしれない、と言っていた。刹那の流行に流されて後追いになっていくと、本当に時代遅れの言語になっていきそう。確かに他の言語と同じことをやったのでは後追いになるので、追い越していったほうが面白くなると思う。

俺は目先のことしか見ていないんだなーということがよくわかった。Rubyがこれからどうなっていくのかわからないけれど、きっとなんかいい感じになると思いました!

dRuby

この3日間めっちゃ濃かったのでまともにまとめてたらめっちゃ時間かかってしまうので以下簡単にしか書かない。

これ標準ライブラリだったの知らんかった。Rubyなんもわからん。これ使ったらmikutterプラグインを複数プロセスで動作させられるのでは…。 フィルタは普通に今でもマルチスレッドだし、どうしても同じプロセスにロードされてないといけないプラグインっていうのもあるけど、それって依存プラグインでしょ?プラグインの定義ファイルで依存プラグイン明示してるし、静的にわかるじゃん。しかもforkするみたいな感じじゃなくて、既に起動してるmikutterにattachできるし、既にサーバから起動してるmikutterにUIだけattachして使うみたいなアホなことも頑張るだけでできるのでは…。

Ruby何もわからんなと思いました。

A proposal of new concurrency model for Ruby 3

Rubyはスレッドがない時代に生まれたのでC extensionがスレッドセーフに書かれておらず、その頃から互換性があるのでマルチスレッドで動くと破滅するという認識だったので、GVLがなくなって複数スレッドが同時に動くというのは無理なんだろうなあと思っていた。

でもRuby 3ではGuildという仕組みが導入される予定らしくて、複数スレッドが同時に動くことができるようになるらしい。 Threadは(必ず?)(ひとつの?)Guildに属して、同じGuildのThreadは同時に走らないが、違うGuildであれば並列に実行しようとすると。グローバル変数とかもGuildごとに分けるらしい。まあそうじゃないとおかしなことになるわな。 確かErlangかなんかは同じプロセスに複数のVMを持てたような気がするけど、Guildはそれに近い使い勝手になるのかな。実際の実装は知らん。でもRubyはもともとThreadのことは考慮されていなかったということは、C extensionで(Cの)グローバル変数とかstatic変数とか使ってたらあかんのでは。Cなんもわからん。

今気づいたけどこのセッション英語だったのか。その割には俺ちゃんと理解してるな(全く違う理解をしている可能性もある)。日本人の英語聞き取りやすいのでは?でも日本人となら日本語で話したほうが良いと思います。英語なんもわからん。

Unifying Fixnum and Bignum into Integer

数がFixnumになったりBignumになったりしてだるかったのでIntegerだけにするぞという話。 もともとFixnumとBignumは両方ともIntegerのサブクラス。FixnumとBignumはRuby 2.4ではIntegerを指す形で残るので、互換性あるよーという話。うああ、数という意味でFixnum使ってるコード手元にあるし…。Ruby 2.4でも普通に動くけど、Integerに直しておこう。

数値なんもわからん。

Fearlessly Refactoring Legacy Ruby

リファクタリングの話。mikutterとかは、6年前といえばユニットテストとか存在すら知らなかったし、mikutterにはテストがあんまりない。それが最近は苦痛で、PluggaloidをはじめとしたGemにはある程度テストを書いている。書いているうちに成長してきて、今はPluggaloidのテストとかマジアレだなと思ってる。つらいなあ。

このセッションのキーワードは Characterization test と Suture gem、ということでいいのかな。このセッションこそどの程度理解したか自信がないんだけど、要はリファクタリング前のコードの入力に対する出力を記録して、それがリファクタリング後とちゃんと一致することを以ってコードの意味が変わってないことを検証するというのがSutureの少なくとも一機能らしい。 Suture gemは面白くて、リファクタリング前と後を両方実行するとか、最後の方は集中力切れてて微妙なんだけど、どっちを実行するかを乱数で決めたりとかしてたような気がする。Sutureについては曖昧な感じだけどマニュアルしっかりしてるっぽいし実際に使っていったらわかりが発生するかも。

レガシーなコードにはテストがないので、リファクタリングの前にテストを書いてからリファクタリングするのが定石だと思うけど、どうせレガシーなコードはミュータブルなのでテスト書けず、まずは副作用をなくしてからテストを書きたい、しかし書き換えると言ってもそもそもテストがなくてだな…となって無限再帰に陥ってどれくらいかかるか見積もりもできない。憶えがありすぎる。mikutterお前のことだよ。2010年の俺、この記事見てるか。

リファクタリングなんもわからんけど、Sutureは手札に入れておくべきだと思いました!

How to create bindings 2016

お世話になっておりますと思いました!

GIの紹介。おお、Gtk3の実装に使われているGIっちゅうのはこうなっとったのか!と思いながら聞いていたけれど、どう使うかはわかった(つもりになった)がどうなってるかはなんもわからんかった。すごいなあ。

Learn Programming Essence from Ruby patches

俺もここ半年くらいになってようやくRubyのパッチとか読むようになったんだけど、このセッションはRubyのパッチを読んで学びを得ようと言う奴だった。 俺は、Rubyはでかいのでとりあえずパッチだけちょっと見とこうと思っていたが、パッチはその変更に関連する箇所しか出てこないし、コミットメッセージでその変更の内容や理由が説明されていていいぞっておっしゃられていて、たしかになーと思いました!

Ruby Reference Manual 2016 Autumn

るりまの話。よくお世話になる〜。mikutterに関するマニュアルとかちゃんと書きたいと思っていて、そのために役立つことがないかと思って聞いた。 本来の目的という意味では特に新たに得られたものはなかったかなという感じだったんだけど、るりまとるびまって1文字しか違うやんけとか、るりまのSEOとかいう面白いワードが出てきて個人的にはとても満足した。

あれ、なんか本当に良い話だったんだけど俺の文章スッカスカだな。日本語なんもわからん。

Modern Black Mages Fighting in the Real World

TDでFluentdの0.12→0.14で、APIがアレだった部分を修正したいけど互換性ぶっ壊れる…というところで、黒魔術を使ってうまく両立してやったぜ!という話。 mikutterでもそういうところあって、何度かおさけーさんにそのことを褒めてもらって第一話の平沢唯みたいにニヤニヤしたことがあったんだけど(アへへへへヘアへへヘ)、Fluentdはmikutterみたいな悪ふざけじゃなくてちゃんとしたものだから、ちゃんと大変な思いでちゃんと黒魔術を使っていて、すごいと思いました!

個人的には、Module#prepend確かに便利そうだけどどうやって実用するのかなんもわからんなと思っていたので、その実用例が見れて最高に盛り上がった。

It's More Fun to Compute

国際会館の最強の音響をフルに使って、Rubyでいろいろ演奏していてすごいと思いました!俺もPocket mikuでmikutterの効果音再生したりしてたけど、こちらはSonic Piを使っていました。 複数トラックを演奏するのにdrubyをさらっと使っていて、優勝かよって思いました!

Optimizing Ruby

Rubyは全然最適化されていないので、まだまだ早くなる余地があるとのこと。1+1とかも、Integer#+をオーバライドできるので単純に2に置き換えることはできない。 この話で初めてdeoptimizationという言葉を聞いた。純粋なメソッドは一旦最適化してしまって、メソッドがオーバライドされて純粋でなくなったら非最適化するというアプローチで、今まで最適化できなかった1+1のような式も思い切って最適化できるらしい。なるほど定義が変わったら戻してしまえばいいということかな? 確かにこの理屈だと、Rubyだったら無理そうだなーと思っていた最適化もできるようになりそうだし、実際かなり早くなっているらしい。Ruby3は3倍早くするとか無理じゃねと思ってたけど、目標に向かって着実に高速化を進めておられて、すごいと思いました!

まとめ

ほんと話聞いてただけなのにこの三日間は滅茶苦茶疲れて、翌日は1日寝てました。

3日というのはかなり長くも感じたし短かったような気もするし、とても充実してました。たくさんおもちゃを入荷したのでしばらくは遊べそうです。フィリスのアトリエの発売延期してつらいなあと思っていたけれど、調度良かったかも。

Rubyなんもわからんなと思いました!あと、RubyKaigiはいいぞ!