2017に参加してきました。Rubyが大変楽しかったです。Ruby本体にパターンマッチ用の構文をいれようという話が実装を伴って出てきたのは今回が初めてのはずで、それ自体意義深い事だったように思います。裏を返すと馴染み深すぎてユーザに誤った印象を与えてしまいそう(オブジェクトに見えるので変数に代入したりすることができそうに思える)とも感じました。この辺のバランスは難しいですね。提案するパターンマッチ構文さて、発表に感化されて自分なりにプロトタイプを作ってみました。荒削りですが、いずれFeatureチケット化までこぎ着けたいところです。1設計の考え方パターンについては、メソッド仮引数構文類似のものを書けるようにする。Rubyの中で特別扱いされることが多いArrayとHashに対してパターンが書きやすくなっているというのが利点。反面、HashのキーとしてSymbolしか利用できなくなっている。Stringを指定したいというユースケースがどの程度あるかがポイントか。ユースケースとして多そうなのはJSONだが、JSON.parseにはsymbolize_namesというオプションがあるため問題になりづらいのでは。任意のオブジェクトに対するパターンマッチを可能にしたいので、ScalaのExtractor類似のプロトコルを組み込む。パターンマッチ対象のオブジェクトに対してdeconstructメソッドを呼んだ結果に対してマッチさせる。assignmentを実現したいので、1行でのパターンマッチに特化した文法(代入バージョン)もサポートする。パターンマッチとセットで語られる事が多い話題としてマルチディスパッチがあるが、言語に対する影響が大きすぎる気がして個人的には否定的。whenの代わりの"=>"やパターンとして使っている"=()"は、パースが簡単そうというだけの理由で選んでおり強い思いはない。award"をいただきました。受賞コードを抜粋するとこんな感じ。一応これはSchemeとしても有効なコードになっていて、実行すると6!を計算して出力します。その一例としてSICPに出てくる超循環評価機をポーティングしています(metacircular.rb)。いうことで、今回の作品は一言でいうと「PolyglotなSchemeサブセットのインタプリタ」でした。正確には「R5RSサブセット+一部R6RS拡張」になります。原理的には小文字にすることも可能です。純粋なR6RSサブセットをお求めの方のために、小文字バージョンも用意しておきました(entry-lowercase.rb)。実装のポイントはobj.callのシンタックスシュガーobj.()の活用です。remarksから引用します。(B))にすると((A).call(B))と解釈されパーサを通るようになります。実行時にmethod_missing/const_missingなどを使いながら構文木を組み立ててSchemeプログラムとして評価しています。()))と書くことにしようといったルールを決めていかないといけないのがちょっと大変でした。Refinementsも使っていて(metacircular.rb#L7)、RubyコードとSchemeコードが無理なく共存できるようになっています。Object.const_missingはRefinementsが有効にならないという仕様があり*2、これだけはグローバルに影響が出てしまうのが心残りです。追記(2015/12/23)実はここまで書いたその日の夜にmethod_missingでRefinementsが有効になるのはバグだとの判断がありプログラムが動かないようになっていました*3。accessesではRefinementsを有効化しないという記載があるためこの変更には納得するところで、図らずもTRICKの理念の一つである「Rubyの仕様を安定化する」ことに貢献できた感があります。GitHub上のコードはRefinementsを使わずにモンキーパッチをあてるように修正したので、少なくとも当面は動いてくれるはずです。Ruby」というタイトルで発表してきました。RubyKaigiの壇上に立つ日が来るとは。