Continuation is to be continued
RubyKaigi 2025, #rubykaigi
https://rubykaigi.org/2025/presentations/fetburner.html
ウォンテッドリーのバックエンドエンジニアの水野雅之です。4月16日から18日まで開催された RubyKaigi 2025 において、Ruby にネイティブ実装されている継続オペレータの解説とより良いインターフェースの提案を行う発表を行いました。
当日の発表スライドは Speaker Deck で公開しており、発表の録画については例年通りであれば公式の YouTube チャンネルから見られるようになるかと思います。
RubyKaigi はプログラミング言語 Ruby に関する国際会議で、2006年からコロナ禍等での空白期間を挟みつつも概ね年1回のペースで開催されています。Rails の様な応用よりは言語自体の新機能や処理系の改善といった基礎研究的な内容の発表が多いです。
今回 RubyKaigi 2025 の開催地は四国は愛媛県の松山市だったのですが、僕が隣県の香川県高松市出身だったのもあって今回発表できた事を嬉しく思います。同じ四国に20年住んでいても鉄路の利便性が低いのもあって松山にはあまり行った事が無いのですが、道後温泉等古くからの街並みを残しつつも地方にありながら栄えている良い都市でした。X の #RubyKaigi
ハッシュタグを見るに、他の Rubyist の皆さんも松山を満喫していたようですね。
Ruby は国内外で広く使われている言語だけあって国際色豊かな多くの参加者で賑わっており、公式発表では1518名もの参加者を数えたそうです!実際 RubyKaigi 会期中の昼休みときたら会場から徒歩圏内の飲食店はどこも行列ができていて歩き回る羽目になったり、僕が良く参加している地域 rb 勉強会の Omotesando.rb や Roppongi.rb のメンバーの大半が松山に居るので現地で懇親会が開かれたりと大変な盛況でした。興味深かったのは関数型コミュニティの勉強会で昔ご一緒した X の相互フォロワーや大学院時代の研究室の同期と drink up で会ったことで、如何に Ruby が人口に膾炙しているか思い知らされた感じがします。勿論 Ruby の最前線にある発表内容も RubyKaigi の魅力ですが、多様性に富んだ Ruby コミュニティの人々との交流も Kaigi の醍醐味ですね。
RubyKaigi 2025 で僕が行った発表の内容について深掘りすると、Ruby にネイティブ実装されている継続オペレータの call/cc は deprecated とされながらも DSL 実装においては依然として有用であることを非決定計算を題材に説明し、実装した DSL をベンチマークに用いて call/cc にはいくつか問題がある事を確認した後、より良い継続オペレータ実装の shift/reset を Ruby に導入することを提案しています。
call/cc は掻い摘んで言えば高機能な goto のようなもので、これを DSL 実装に用いればプログラマが明示的にブロック引数等で処理を切り出さずとも DSL 側で自由に制御フローを組み替えられるので、非決定計算のように複雑な制御フローを必要とする用途でも Ruby の構文を流用した DSL を構築できる利点があります。
とはいえ call/cc は高機能でも所詮 goto のようなものでしかないので、これを用いた非決定計算の実装は複雑極まりますし、メソッド呼び出しを跨いだジャンプを可能にするためにスタックの退避が必要でパフォーマンスもお世辞にも良いとは言えません。実際 call/cc を用いて実装した非決定計算の DSL で SEND + MORE = MONEY の覆面算を解くベンチマークを行った際、メタプログラミングを使った既存実装では 0.1 秒ほどで完了したにも関わらず、call/cc を用いた実装では数分経っても計算が終わらない始末でした。
Scheme のような他言語では call/cc より良い抽象化として shift/reset の様な限定継続が知られており、これは shift の箇所に関数呼び出しを行って reset の位置で return する様なコードを切り出せるので大半の用途では call/cc より使いやすく、reset 以降のコードは実行されないことから退避しなければならないスタックの範囲を限定できるのでパフォーマンスも向上できる利点があります。call/cc を用いた shift/reset の実装でも SEND + MORE = MONEY の覆面算が1秒も経たずに完了する様になりパフォーマンスの向上が見られたのですが、ネイティブ実装をすることで更なる性能の向上が行えるのではないかと考えています。(本当は RubyKaigi 2025 までに実装を終わらせて性能の比較まで行いたかったのですが、準備時間が足りませんでした)
余談ですが、RubyKaigi なのに発表の会場が真珠の間で面白かったです。Ruby ではなく Perl とはこれいかに。
元々ウォンテッドリーでは RubyKaigi のスポンサーになった上でエンジニアを派遣しているのですが、去年からはスポンサーブースの運営に協力することと、発表のプロポーザルを提出することを条件に参加者を募っていました。
僕も社内での RubyKaigi 参加条件を満たすためにプロポーザルを提出したのですが、アリバイ作りではなく一応 RubyKaigi に採択されるプロポーザルの傾向は調べた上で作成しており、RubyKaigi は実務よりは Ruby 自体の改善に重きを置いたカンファレンスですから、その趣旨に沿う形でテーマを選定しました。僕は Omotesando.rb や Roppongi.rb などで発表を行うのと並行してテーマの模索をしており、Roppongi.rb #21
でリストモナドについて発表した際に使った call/cc の話を深掘りできないかと当たりを付けた形ですね。
そして大まかな当たりを付けた後は勉強会駆動で shift/reset を使った DSL 実装を試してみたり、call/cc の内部実装について調査を行ってみたりして、その発表内容を下敷きとしてプロポーザルやスライドの作成を行っています。
この call/cc を使った DSL 実装の着想と、スライドの添削をして頂いた同僚の原さんには感謝してもしきれません。RubyKaigi のスライドには書きそびれてしまったのですが、ここに感謝を表明致します。
ウォンテッドリーでは RubyKaigi 2025 にシルバースポンサーとして協賛している様に、Ruby コミュニティへ積極的に貢献しています。Rubyist の採用も進めているので、興味がある方は是非カジュアルにお話ししましょう。