プログラミング言語の入門が終わったら何の勉強をすればいいの?

JJUG CCC 2022 Fallで「Javaの入門が終わったら何の勉強をすればいいの?」という内容で発表を行いました。
基本的なものが作れるようになったけども、イマイチプログラムが組めないというときに、何を勉強すればいいかをまとめました。

資料はこちらです

とりあげた本についてまとめておきます。

フレームワークは入門でやってる前提です。Java入門書「プロになるJava」ではJavaの基本から簡単なDB操作、Spring Bootまで取り上げてます。

開発作業について

まず最初に、ユーザーは直接的にはコンピュータに載ったプログラムを動かすことでサービスを体験するので、プログラマが直接ユーザーと関わることはないし、プログラムですら直接使われるわけではありません。
そこでプログラムがどのように動いて、そしてそのプログラムをどのように作るか、そのために全体としてどういう知識が必要になるか、というイメージを持つことが大切です。

このエントリではいろいろな本を取り上げますが、どのような分野が必要になるかを把握して、本屋さんに行って自分のレベルに合う本を選ぶのがいいのではないかと思います。
何を作るにしても必要になるプログラミングの基本です。作りたいものを作ればいいとコメントがありますが、ここで取り上げている基礎を勉強すると「作りたいもの」自体のレベルもあがっていくと思います。

概要

ここで取り扱う内容はコンピュータサイエンス、計算機科学といった分野としてまとまっています。つまり、コンピュータサイエンスをまんべんなくやりましょう、という話なんですが、それっぽいタイトルの本にだいたいまとまっています。

ただ、コンピュータサイエンスというタイトルの本は細かく正しく書かれていて分厚く読みにくかったりするので、応用情報技術者試験の本が読みやすいです。ただし、受験対策ではなく内容理解のための本が大事です。しかし受験対策のほうが人気がある。
高橋麻奈さんの本がオススメなのですが、受験対策には向いていないので紙版は出なくなっていますね。Kindle Unlimitedで読めるので、サービス利用者は追加の課金なしに読めます。

プログラミング言語

資料とは順番違いますが、先にプログラミング言語を。
プログラマが直接関わるのはプログラミング言語を利用して書くソースコードです。
入門書はとにかく動かせるようになることに主眼が置かれるので、細かい条件や背景などは省略されがちです。けれども入門が終わったらもう少し突っ込んだ解説が必要になります。
Javaでは「Java本格入門」を挙げています。

ただ、もっと突っ込んだ勉強をしようとするときに、言語仕様などを読む必要が出てきますが、言語仕様を読むためには「プログラミング言語」というものがそもそも何かということを知っておく必要があります。
そこで入口として、命題論理、述語論理などの論理学から、ラムダ計算、型付ラムダ計算という流れで勉強するのもいいかと思います。

そして、型理論です。「型システム入門」という本がありますが、あまりオススメしません。型理論を本格的に勉強するには必ず読まないといけない本ですが、広く勉強する一部としては専門的すぎます。

そこで「プログラミング言語の基礎知識」をおすすめします。この本は「型システム入門」のダイジェストのような本で、たったの176ページ!ただし、3行読むのに1時間かかったりします。

先にコンパイラを作ってみるというのも手です。「ふつうのコンパイラをつくろう」ではJavaCCを使ったパーサーをもとにx86コードを出力するコンパイラを作っています。ただ、ネイティブコンパイルするものではなく、インタプリタだけ作ってもいいと思います。

アーキテクチャ

プログラミング言語がわかったら、次はプログラムを実行する環境です。
Javaであれば、JVMがどのように動くか、特にJITGCについて理解しておく必要があります。「Javaパフォーマンス」にはそのあたりがよく説明されています。チューニングの話まで進むと難しくなっていきますが、概要の説明はそんなに難しくないです。

OSもプロセスまわりは把握しておいたほうがいいけど、「入門コンピュータ科学」での説明くらいでいいかな。

プロセッサについては「プロセッサを支える技術」を挙げていたけど、より範囲の広い「コンピュータアーキテクチャ技術入門」がいいかもしれない。コンピュータの処理を理解するために、パイプラインやキャッシュといった仕組みは知っておく必要があります。

機会があれば、FPGAでハードウェアをいじくってCPUを作ったりすると、コンピュータが動くイメージの解像度がかなり高くなります。

ミドルウェア

サービスを構築するときに、いろいろな役割のサーバーが必要になります。その中でもリレーショナルデータベースは重要なので、ちゃんと勉強しましょう。
まずは正規化などのテーブル設計を確認しておきましょう。

また、リレーショナルデータベースがどのように動くかというのは、NoSQLデータベースにも応用ができるので、ひととおり知っておくといいです。
この本はMS SQLサーバーの仕組みですが、大枠はどのRDBMSでも同じなのと、ここまで読みやすくデータベースの仕組みを解説した本も他にないので、読んでおくといいです。
資料にあげてたRDBMS解剖学は絶版で中古も高い・・・

あとは「ソフトウェアアーキテクチャの基礎」に運用も含めて細かく解説されています。

ネットワーク

サーバーを構築して複数のコンピュータを連携させると、必ずネットワークで通信します。
「ネットワークはなぜつながるのか」には、イーサネットや光ケーブルといった物理層TCP/IPなど通信プロトコルがまとまっているので、一度読むといいです。

プロになるJava」ではソケット通信でHTTPクライアント・サーバーを構築するサンプルを載せているので、実装してみるといいと思います。

デプロイ

プログラムを動かす環境を理解して、プログラムが書けたとしても、それをコンピュータに載せなくてはユーザーは使えません。
そこで、プログラムをコンピュータ上に配置するデプロイの作業が必要になります。
いまではソースコードから実行ファイルを作成してサーバーに配備する手順は複雑化しているので、自動化が大切です。そして、作ったものをなるべく早く使ってもらってフィードバックを得る必要も出ているということで継続的インテグレーション(CI)という考え方が必要になります。

また、作ったプログラムを公開するときには、プログラムが変な動きをしないかどうか確認する必要があります。このような作業をテストといいます。ユニットテストで自動化することも大事ですが、そもそもテストというのはどういう作業かということも知っておく必要があります。

理論

「プログラミングに数学は必要か?」のような議論が起きたときに、「物理シミュレーションを組むなら微分積分必要だろうけどアプリケーションによるのでは?」のような話をする人がいますが、離散数学はコンピュータの動作の基礎でもあるため、アプリケーションによらず必要です。離散数学は、とりあえずどういう内容を扱っているかを確認しておくといいと思います。

集合や論理に関しては、「論理と計算のしくみ」で扱われているので、そちらを見てください。

論理については野矢先生の本を見ておくのもいいですね。論理はプログラミングにとどまらず全ての事柄について、正しく考えるために必要です。

また、グラフ理論も重要なのでちゃんと勉強しておくほうがいいですが、この本は物語になっていて読みやすいです。

ソート、探索といったアルゴリズム、そしてアルゴリズムの設計法も大切です。

指摘があって確認したのだけど、データ構造やグラフといった話題を扱っているこちらのほうがいいかも。

計算可能性の話は、「数学ガール/乱択アルゴリズム」をおすすめします。

物語の冗長性がまだるっこしい人はこちらを。

計算理論の基礎」は絶版か・・・

あと、「プロになるJava」では、プログラムの複雑さを分解して順に練習していくというサンプルをやっています。知る限り他にはないアプローチなので、難しい処理が書けるようにならないという人は、Javaではない言語ででも書いてみるのもいいと思います。

開発手法

さて、プログラムやコンピュータの動きが把握できたとしても、ユーザーがやりたいことを実現できなければ意味がありません。
その入口になるのは、ユーザーの要件をまとめる要件定義です。「はじめよう!要件定義」は読みやすくよくまとまっていておすすめです。

要件が固まったらそれをシステムに実装できるよう詳細化を行う必要があります。そのための手法としてDDDが定番になっていますが、エリック・エヴァンスの本は「そのエピソードに2ページ要る?」みたいなのが多くて読むのがつらいので、最初はこのあたりを読むのがいいと思います。

あと、DDDは具体的な作業どうするん?というのがわかりにくいので、ICONIXというユースケースロバストネス図を基本にした分析手法を知っておくといいかもしれません。

業務システムの場合は、業務知識の概要があるといいです。
Webサービスにしても販売管理、流通管理、生産管理などは裏側で必要になることが多いです。

開発プロセス

開発プロセスとしては、いまやアジャイルが当たり前になっていますね。
カイゼンジャーニー」はひとりから始めてチームにアジャイルプロセスを浸透させていく話で、読みやすく実用的でいいです。

同じ著者たちの「いちばんやさしいアジャイル開発の教本」は、アジャイルについてもっと知りたい場合にいいと思います。

また、いまは共同作業にGitHub(or 代替サービス)が不可欠です。GitHubよくわからんな人は、よこなさん、しょぼちむさんの本を読んでおきましょう。

まとめ

勉強することが、とにかくたくさんありますが、期限が決まっているわけではなく10年15年かけて勉強していけばいいので、じっくりゆっくりやっていけばいいと思います。
最初にあげた絵を地図として、いつか全部わかるようになろうという意思をもって日々いろいろやって少しずつでも近づいていけば、そのうちいろいろわかるようになっていると思います。

ブログは思考の叩き台

前のブログで、「適当に言ってるだけ」「分析がちょっと雑」というコメントがついていた。

でも物事を適当じゃなく言ったり雑ではない分析をするには、最初に適当に言ってみることや、雑な分析を出してみることが大切だと思う。

まず、人に読ませる前提で書き下ろすことが思考の整理につながる。
そして、具体的に思考を形にすることで、それに対するフィードバックが得られる。
「くだらない」というコメントが付くことでも、「このテーマに期待している人がいる」ということがわかる。そうすると、もう少しちゃんと考えてみるか、ということにもつながる。

そうやって、思考というのはフィードバックを得ることでどんどん形が作られていく。
自分だけではなく、他の人もこのエントリを見て何か別の意見を書くかもしれない。コメントもそういった意見のひとつだし、そこから考えを広げていく人がいるかもしれない。
思いついたけど詳細は他の人に考えてもらいたいような内容を書いておくと、興味をもった誰かが、自分が書くよりもすばらしい記事を書いたりする。

幸い、技術系のブログでは否定的な意見にしても ちゃんと記事の内容をふまえたものばかりで、個人攻撃のようなコメントがつくことはないので、ブログを書くことのデメリットはほとんどない。
ということで、考えたことを公開することは、自分やその周辺の思考の向上につながるので、適当でも雑でも内容がないようなものでも出していくのがいいんじゃなかろうか。

ところで、この本には、人の脳はだれかに向けて言葉を考えるときに より活性化するというようなことが書かれています。
次のように、推論=思考は社会的にやるべきという話がいろいろな視点でまとめられてて面白いです。

人間は、 他人に自分の考えを納得させたり、他人から騙されたりしないように進化しました。言い換えると、推論は社会的な活動であり、そのように行われるべきなのです。

TwitterをSpaceXやTeslaと同じようにはエンジニアリングできないのでは

Twitterを買収したイーロン・マスクが週80時間勤務に備えろといって、それができないなら退職という話をした結果、エンジニアを含め社員の多くが辞めたという話がでてます。
https://jp.reuters.com/article/twitter-departures-idJPKBN2S806D

イーロン・マスクとしては、Teslaのようにハードに働く少数精鋭のチームを作りたいようです。

ただ、TeslaやSpaceXは製造業で、たとえばSpaceXならロケットを安く確実に作るというように、作るものは基本的に決まっているプロダクトで、要求が超シビアな中でどのように作るかが問題になるのでそれがハマる面があるんではないかと。

SNSは作るものは決まっておらず、市場を見ながら自分たちで作るものを決めていく必要があります。要求も自動運転車やロケットのようには高くありません。
※末尾に追記で3社のミッションについてを挙げています。

あとTwitterのような巨大サービスは、イーロン・マスクの言うような超優秀な精鋭だけで運用するのは難しく、そこそこ優秀な多くのエンジニアが必要になる傾向があります。規模の大きいサービスでは必ず障害が発生します。少数の精鋭だけだと、日々発生するトラブルの対応に追われて機能開発ができなくなります。

そうすると、同じエンジニアリングの哲学を適用するのは難しい気がします。

追記
ところで、くだらない記事だというコメントついてますが、こういうエントリ書いてますね。
くらだないブログエントリの素晴らしさについて - きしだのHatena

さらに追記(19:50)
考えまとまってないなぁとか、特にたいしたこと書いてないなぁとか躊躇してブログ書かずTwitterだけで終わってたら、はてブのコメントに書かれてるような視点は得れなかったわけです。

そして追記(21:30)
たとえばTeslaのミッションは「太陽光発電で動く電気自動車を広めて持続可能な社会を作る」、SpaceXのミッションは「人類を多惑星化する」「火星や他の惑星に人を送り込めるこれまでにないパワフルな打ち上げロケットを作る」です。
これらを実現するために必要なことのすべてがわかるわけではないけど、「品質のよい電気自動車を安く作る」「ロケットエンジンの出力をあげる」などは必要かつ目的に近づきます。
一方で、Twitterのミッションは「世界に関するもっとも正確な情報源になる」と言っていますが、そのために何が必要か、なにを作れば近づくかはよくわかりません。候補は挙げれても、TeslaやSpaceXのようにハッキリと納得できるものにはならないと思います。
https://twitter.com/elonmusk/status/1589413653190938624
これがTeslaやSpaceXで作るものが決まっていて、Twitterで作るものが決まっていないという話が表す事柄です。
実際にElon Muskも「これから変な機能をたくさん追加するだろう。そしていいものは残すし、ダメなものはすぐ消す」みたいなことを言ってます。

また追記(23:30)
ブログは議論のたたき台で、とりあえず出していろいろ意見もらって、こうやって追記していい感じにまとめていくのがいいと思ってます。

ついでに追記(11/20 12:30)
ブログは議論のたたき台ってことをまとめた

美術館がブリロボックスを購入したのは値段以上の効果があったのでは

2025年にオープンする鳥取県立美術館でウォーホルのブリロボックスを5箱3億円で買ったことが話題になってます。

ブリロボックスは、スチールウールの配送用段ボールを模した木製の箱です。
位置づけとしては「部屋干しトップ」の配送用の箱を木で作ったものをイメージしてもらえばいいかと。

そういう作品なので、「見ても価値がわからない」という批判も出てくるわけです。
https://www.yomiuri.co.jp/national/20221026-OYT1T50268/3/

冒頭にあげた記事では「ポップアートとか意味すら分からない人が大多数」という意見も出ていました。
けれども、意味すら分からない人が大多数であればこそ、「新たな視点で物事を柔軟にとらえ、想像力を豊かにする教育効果もある」ことになります。

追記(2022/11/19)
平井知事が「まさに現代美術史がたどってきた道筋を、私たちが歩いているということなのかもしれません」と言ってます。
「令和の世に議論が深まったとか言われても困る」というコメントがついていますが、100年近く前に起きた議論に令和になってようやく追いついてきたわけで、そうやって文化を進めることが公立美術館の役目だと思います。 むしろ令和になっても公立美術館が「写真みたいでキレイよね」とかやってるほうが困ると思います。そういうのは商業美術館でやればいいので。
https://newsdig.tbs.co.jp/articles/-/206591 --ここまで

で、そういったブリロボックス周辺の事情は「美学への招待」に解説されています。

たとえば次の部分は、今回の騒動をそのまま説明しています。

貴重なものが絵画に再現され、それが習慣になると、絵画に描かれたものは貴重なものだ、ということになります。(中略)しかし、『ブリロ・ボックス』には居心地の悪さを感じます。何しろ、それは無価値なものを再現した芸術品であり、芸術品である以上、当然高価なものだからです。

ブリロ・ボックスのような現代アートの背景には次のようなものがあります。

かつて、自然を模倣するのが芸術だ、という考え方が定説でした。(中略)絵画について言えば、肖像画や風景画がこの理論のモデルケースであるのは、明らかです。ところが、写真の発明はこの機能を絵画から奪い取りました。そこで、印象派に始まり、抽象画に至るさまざまな非写真的な絵画が生まれてきました。この芸術の新しい傾向に現れた哲学的判断は、《芸術は非自然のものだ》であったと思われます。

ブリロボックスは1964年の作品ですが、1962年の作品に「マリリン」があります。

1960年ごろには写真も芸術としての立場を確立していたのですが、ウォーホルはこの劣化コピーを並べることでも芸術になるのかという挑戦をしたわけです。

マリリンの場合は、コピー元はスターの写真であってそれなりの美的価値がありましたが、ブリロボックスの場合は、そのコピー対象をスーパーに並んでいる商品にして、さらにその価値を問ったといえます。

たとえばこれが1辺3mくらいに巨大化するとか、逆に1辺5cmにミニチュア化すると、それはわかりやすい美術的価値になったかもしれません。
けれどもブリロ・ボックスは実物大です。ダンボールか木箱かだけが違います。ただ、元が量産品であることを示すことが大切なので5点購入というのは必要だと思います。

芸術と言えば、それだけで、人びとが納得するようになり、多少奇矯なふるまいや言動でも許されるような、そういう状況に至っています。このような状況において、芸術の自己反省とでも呼べるような作品が生まれてきたわけです。このような作品は、残念ながら、虚心に見たり感じたりすれば分かる、というようなものではありません。一点の曖昧さもない『ブリロ・ボックス』が難しいのは、この意味においてのことなのです。

こういった意味では、「ブリロ・ボックス」に「見ても価値がわからない」というのは当然で、そして「3億の価値があるのか」「なぜ5点必要なのか」という議論が起きること自体がこの作品の持つ意味なので、こうして全国的に話題になったということは、すでに3億円の価値があるように思います。

ところで一辺4.5cmのものがAmazonに売っているので欲しい。

ゆるっとIT vol.12「3年ぶりに帰ってきたIT怪談」 カンペ

昨日2022/10/27に行われた『ゆるっとIT vol.12「3年ぶりに帰ってきたIT怪談」』のカンペです。
これを見ながら話してました。

前振り

今日はほんとに怖い話をするので、資料なしでやりますね。

昔話

ちょっと昔話をしましょう
ぼくの最初の仕事はPHPでした。PHP3とPostgreSQLで英語学習サイトをつくるというものです。
当時webでプログラムを動かすというのは出たばかりで、請け負う業者がいなかった
みんなVBやってましたからね
なので大学追い出されたてで何の実績もないぼくに仕事がまわってきた。

もうちょっとして、東京の会社に声をかけられました。
で、iPhoneアプリをつくってほしいと。
これも、iphone出たばっかりで技術者がいなかった。
なので福岡のぼくに話がまわってきたわけですね。

共通するのは、新しい技術で技術者がいないので実績ないけど仕事がまわってきたことです。
若い人は年寄りがやってない新しい技術をやるって感じでしたね。

現在の話

現在の話をしましょう
iphone 14がでましたね。でもうれてません。売れてないので減産しました。
iPhoneというのは、一番最新で一番高性能なCPUがのるデバイスです。
それが売れてない。
もう速いCPU作っても売れない。ということになってます。
そうすると速いCPUがつくられなくなる。

これはハードウェアの話ですけど、ハードウェアがとまるとソフトウェアもとまります。
もうすでにとまりつつありますね。あたらしいプログラミング技術がでてない。もちろん細かいものは出てますが、ちょっとした便利機能です。
みなさんに会うの3年ぶりくらいですけど、3年前と同じ言語やフレームワーク使ってる人おおいんじゃないですか
そして、気になる技術もないということないですか
rustやpythonに興味あっても当面仕事ではつかわない感じですよね。

未来の話

それから、未来の話をしますね
プログラミング教育が義務化されました。
「プログラミングネイティブ」がどんどんでてくる
いまでも学生でプログラムコンテストやってましたーという人がたくさんいる
やつら、プログラム超くめる

怖い話

じゃあ怖い話をします。
技術がかわらなくなって、出来のよい新人がはいってくるとどうなるか
いままでは若い人は新しい技術をひっさげてきたわけです。
住み分けがあったわけですね。
cobolerのように、若者よせつけないレガシーのお守りで生きてはいけばいい
もしくは道具がかわるなら新しい道具のつかいかたおぼえればいい

でも同じ技術を高度に使う能力をひっさげてくるわけです。
技術かわらないんで勉強しなくても生きていけるんだけど、そうすると若者に圧倒的な差で窓際においやられますよ、という怖い話でした。
若い人にとっては、上がつまってるのでなかなかアピールできないということでもあります。

基礎をやりましょう。アルゴリズムやら論理、あと最近では倫理という技術も大切になってきてます。
経験をつみましょう。ちゃんと考えながら経験しておけば、能力差をまかなえます。

そうやって、怖い世界にたちむかっていきましょう

Javaの-XmsはMemory Startingの略?

Javaのメモリ確保指定のオプションで、最大メモリは-Xmx、初期メモリは-Xmsで指定します。
-XmxのほうはMemory maXimumかなーと感じるのだけど、-Xmsのほうはminimumでもないしなんだろーと思いながら「まぁ気にしてもしかたない」と25年くらい放置してたわけです。
それがちょっとTwitterで話題になってて、調べてみたらStack Overflowにそれっぽいものがありました。

Yes, ms = minimum heap size / heap memory start size and mx = maximum heap size.

https://stackoverflow.com/questions/58164083/why-did-java-chose-xmx-and-xms-naming-convention-for-heap-sizes

-Xmsは最小メモリではなく初期メモリなのでMemory Startingというのは説得力があります。

enumの使い方のおさらいと高機能enumとしてのSealedクラス

Javaでは複数の定数をまとめて扱う型としてenum(列挙型)が用意されています。
これはこれで便利なのですが物足りないところもあって、それがSealedクラスなどを使うことで解決できるようになるので、解説します。

enum

enumは状態やデータ区分を表すのによく使われます。
構文は次のようになります。

enum 型名 {
  列挙1, 列挙2, ...
}

例えば次のような状態を表すとします。

この状態を表すenumは次のようになります。それぞれの値は大文字で書くようにします。

enum State {
  READY, RUNNING, SUSPENDED, TERMINATED
}

enumではそれぞれの値ごとに処理を行うということがよくあります。そこでswitchと相性がいいです。

State s = State.READY;

switch (s) {
  case READY -> System.out.println("準備完了");
  case RUNNING -> System.out.println("実行中");
  case SUSPENDED-> System.out.println("停止中");
  case TERMINATED-> System.out.println("終了");
}

switch文の場合はenum値が足りなくても大丈夫ですが、switch式では全てのenum値を処理しないとエラーになります。

このことを考えると、enum値すべての処理をするswitchは式にしておいたほうがいいですね。(Java 14以降)

var message = switch (current) {
    case READY -> "準備完了";
    case RUNNING -> "実行中";
    case SUSPENDED -> "停止中";
    case TERMINATED -> "終了";
};

enumに値を持たせる

enum値それぞれに数値などを割り当てたい場合があります。そういう場合はフィールドとして定義することができます。 メソッドも定義できるのでgetterを用意するか、toStringメソッドをオーバーライドすることになりますね。 フィールドはprivate finalにしておきましょう。

enum State {
    READY("準備完了"),
    RUNNING("実行中"),
    SUSPENDED("停止中"),
    TERMINATED("終了");

    private final String name;
    State(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    @Override
    public String toString() {
        return name;
    }
}

ただまあ、フィールドとコンストラクタとgetterを定義していくのめんどいので、Lombokを使いたくなります。

@Value
enum State {
    READY(1, "準備完了"),
    RUNNING(2, "実行中"),
    SUSPENDED(3, "停止中"),
    TERMINATED(4, "終了");

    int code;
    String name;

    @Override
    public String toString() {
        return name;
    }
}

Sealedクラスを拡張enumとして使う

JavaenumはCのenumよりは便利なのですが、パラメータを追加したいという使い方ができません。
例えばMouseEventというenumがあって、CLICKEDとMOVEDがあるんだけど座標も持たせたい、というような場合です。あとCLICKEDにはどのボタンかも持たせたい。

という場合にSealedクラスが使えます。実際に使うのはinterfaceになるけど。

enum Button {
    LEFT, MIDDLE, RIGHT
}
sealed interface Event {
    record Clicked(Button button, int x, int y) implements Event {}
    record Moved(int x, int y) implements Event {}
}

sealedをつけたクラスやインタフェースでは、そのnestedクラスだけで継承が行えるようになります。nestedクラス以外で継承を行う場合にはpermitsで指定します。

sealed interface Event permits Clicked, Moved {}
record Clicked(Button button, int x, int y) implements Event {}
record Moved(int x, int y) implements Event {}

そして、Java 19でプレビューとして導入されたpattern matching for switchとrecord patternを利用すれば、enumのように扱えます。

Event e = new Event.Clicked(Button.RIGHT, 7, 3);
var message = switch (e) {
    case Event.Clicked(var b, int x, int y) -> 
            "%sボタンが%d,%dでクリックされた".formatted(b, x, y);
    case Event.Moved(int x, int y) -> 
            "%d,%dに動いた".formatted(x, y);
};

ここでEvent型はSealedなので、継承するクラスはClickedかMovedに限られるため、可能なすべての型をチェックしたことになります。

ということで、recordとsealedクラスとパターンマッチとswitch式を組み合わせると高機能enumのように使えるという話でした。