昨年に引き続きScala Matsuri 2024に参加してきた。 色々あって体調を崩してしまっており長時間の外出に少々不安はあったが、それを押し切って来る価値はあったし、幸い何も起こらずに済んだのでよかった1。
オフライン会場ではレシーバとイヤホンが借りられ、それを使うと同時通訳で発表を聞けたのだが、特にリスニングがさっぱりな私としてはとても体験がよかった。 通訳者の方はもちろん、レシーバをアルコールティッシュで拭いて衛生を確保されていたスタッフの方も大変だっただろうから感謝したい。
特に印象に残ったセッションのうち、ある程度消化できたものについて忘れない内に書いていく。
Ironライブラリで守られた型安全性 (Raphaël Lemaitreさん)
スライド: https://scalamatsuri.rlemaitre.com
篩型と呼ばれる、型に述語を記述することで受け付ける値を制限する仕組みを提供するライブラリを紹介するセッション。
たとえば、「Int型の内、正の値で42よりも小さいもの」を表す型はInt :| (Positive & Less[42])
と記述する。
Int
値をInt :| (Positive & Less[42])
型の変数に格納したいときはintVal.refineEither[Int :| (Positive & Less[42])]
のようにすると、条件に合致しない値はLeft
値を返して弾いてくれる。
モデルを定義する際に使えば、かなり可読性がよくなるし、例外に頼らないエラーハンドリングに役立つだろう。
篩型自体もぜひプロジェクトに取り入れてみたいと思うものだが、私が真に驚かされたのは篩型が違和感なく表現できてしまうScala 3の型システムについてだ。 私は一見「そこまでやる必要があるのか?」とすら思ってしまうほど表現力の高いScalaの型システムとそれがもたらす堅牢性が大好きだ。 Scala 3でも、TypeScriptでおなじみのUnion Type, Intersection Type, Literal Typeなどが取り入れられた。 初めて聞いたときは「どこまで型の表現力を高めるつもりなんだ!?」と面白半分だったのだが、今こうして篩型を見るとLiteral Type, Intersection Type、そして元々あるHigher Kinded Typeの組み合わせで、特別な仕組みを導入するでもなく実に自然な形で篩型が表現されている。 スライドの最後に「Scala 3の型システムは信じられないほど強力だ」とあるが、全くもって同意しか無い。
私が業務で携わっているプロジェクトではまだScala 2を使っているが、頑張ってScala 3に上げたいと思った。 また、Scala本体についてもコップ本第4版を読んだきりでScala 3についてはあまりキャッチアップできていなかったのだが、急いでScala 3 Bookを読まなければという気持ちになった。 早速明日から読んでいくことにする。
あとopaqueをずっと「オパキュー」と読んでいたのだが、「オペーク」が正しいということがわかり、一つ上のScalaプログラマに成長した。
Scalaの開発者ツールエコシステム(Tomasz Godzikさん)
スライド: https://slides.com/tomekgodzik/scala-ecosystem
Metalsくらいまでは知っていたが、Scala Stewardを皮切りにどんどん知らない便利ツールが出てきた。 特にMdocはScalaでもdoctestが使えるようなので取り入れたい。 となるとやはり入出力を切り離して短いコードでテストできるメソッドを書いてやる必要があるんだよなぁ。
Scala Toolkitも公式ドキュメントを見ると、Scala-CLIでちょっとスクレイピングしたいときなどに、Pythonのrequestsのような感覚で使えたりしてよさそうだ。
Scalafmt, Scalafix, Wartremoverの使い分けが未だにピンと来ていないのでどうせなら質問しておけばよかったなとセッションが終わって1分くらいした頃に思ったが後のMatsuriだった。 誰か教えてほしい。
(2024-06-10T20:41追記)
などとTwitterでもぼやいていたら、吉田さんが懇切丁寧に教えてくださった。本当にありがとうございます。
scalafmtについて言及してないけど以前書いたものをとりあえずhttps://t.co/n1TtvgeE3q
— Kenji Yoshida (@xuwei_k) June 9, 2024
あとは、scalafmtと"scalafixのSyntacticRule"が若干領域被ると言えなくもないけれど、scalafmtだけで済むものならば、scalafmtにやらせるのは基本的には一番いいと思います
— Kenji Yoshida (@xuwei_k) June 10, 2024
全く書いてなかったけど、最近は2でも3でもcompiler本体に少し書き換えと色々警告出す機能増えてるから、それとの使い分け問題もあるな…
— Kenji Yoshida (@xuwei_k) June 10, 2024
あとこれは、警告や書き換えをしたい個々のものに対してどれを使うか?であって、プロジェクト全体としては併用はあり得るというか普通というか、個人的には全部併用しています
— Kenji Yoshida (@xuwei_k) June 10, 2024
(追記ここまで)
あとCouriserの読み方がずっとわからず「クーシエル」のような読み方をしていたのだが、「クルシェ」が正しいということがわかり、一つ上のScalaプログラマに成長した。
Property-based testing: テストライブラリ活用方法(Magda Stozekさん)
スライド: https://slides.com/magdastozek/property-based-testing-scala-20-min
Property-Based Testingについてはコップ本を読んでいたときやHaskellをかじったときに少しだけ目にしたが、実際にどういう使い方をするのか、使う上でどういう課題があるのかはさっぱり知らなかったので、TwitterのTLも含め
- エッジケースになるようなトリッキーなデータでテストを行ってくれる
- ジェネレータが誤ったテストデータを作ってしまわないよう注意し、プロパティベースのテストが落ちたときはメソッドにバグがあると確信できる状況にしておく
- Ironライブラリで篩型を導入しておくとこれがやりやすい
- テストを書く前にエッジケースは何かを考えなければならず、TDDに使うには向いていない
- まずは通常のExample-BasedなテストでTDDし、後でProperty-Basedなテストを書くべき
- 重要なコンポーネントのみProperty-Basedなテストを採用すべき
- CIではやはりそのランダム性が問題になることがあり、CIでは回さないようにしたり、seedを固定するなどのやり方もある
といった実用を通した知見が聞け、面白かった。
Twitterで流れていたこの辺もあとでチェックしたい。
- https://fsharpforfunandprofit.com/posts/property-based-testing-2/
- https://xuwei-k.github.io/slides/scalaprops/#1
- https://gakuzzzz.github.io/slides/property_based_testing_for_domain/#1
また、もはやScalaとは全く関係ないのだが、Property-Based Testingといえばラムダノートからも本が出ていた。 Property-Based Testingの本、それもErlang/Elixirで書かれているとなれば需要はかなり限られてしまうはずだが、それでもProperty-Based Testingに関する和書がほとんど無い状況で和訳し出版してくれた気概にシビれたので、こちらもちゃんと買って目を通したい。
いつ継承を使い、いつ使わないのか(がくぞさん)
スライド: https://gakuzzzz.github.io/slides/when_to_use_subtyping_when_not_to_use/#1
Scalaでパターンの多い分岐を書く方法としては直和型を使う方法と、OOP由来のサブタイピングを使ったポリモフィズムを使う方法の2つがあるが、どんなときにどちらを使うのかというのがこのタイトルの表したいことのようだった。 分岐を扱う方法として直和型とポリモフィズムの2つがあることはGood Code, Bad Code ~持続可能な開発のためのソフトウェアエンジニア的思考でもたしか触れられていたのだが具体的な使い分けの基準までは触れられていなかったので、気になっていたセッションの1つだった。
代数的データ型がどう代数的なのかという話がされていて、とても説明が丁寧な印象だった。
特に
- ポリモフィズムでは分岐パターンの追加(つまりサブクラスの追加)は既存のコードを変更することなく行えるが、インターフェースに新たな操作を追加した場合はすべてのサブクラスに追加の実装をしなければならない
- 直和型を使う場合は新たな操作を追加するのは既存のコードの変更することなく行えるが、分岐パターンの追加(ケースの追加)をする場合はその型を使っている箇所すべてを変更しなければならない
という比較がとてもすっきりした。 このように両者のメリット/デメリットを言語化してもらえると、自分で考える軸が得られるのでとてもありがたい。
余談だが、15:20〜16:00にかけA会場/B会場ともに興味深いセッションが重なっており、どう動くかとても悩まされた。 Oxに関するセッションは後でスライドを確認する予定だが、参照透過性に関するディスカッションについてはこれから面白くなるというタイミングでB会場を離れなければならなかったので、少し心残りになってしまった。
まとめ
今回はある程度消化できたセッションについてのみ書いたが、他のセッションも面白かった。 今の自分ではまだ理解が難しいものもあり、また来週末にゆっくり時間をかけて消化したい。
Ironのセッションを聞いているうちに、やはりScalaの型システムの表現力は素晴らしい!という気持ちになり、とにかくScala 3に対するモチベーション、またScala全体に対するモチベーションがグッと上がった。 Scalaは知りたくなることが無限に湧いてきて、ずっと味のするガムのようで良い。
登壇者, スタッフ, 通訳者, スポンサー, その他開催に関わったすべての方々に感謝したい。 ありがとうございました。
- 詳しい話は割愛するが最悪の場合でも誰かに感染したり救急搬送されるなど他の参加者やスタッフの方に迷惑をかける類の体調不良ではなく、参加して問題ないだろうと判断した。↩