動画で読む
結論: 型注釈ゼロで、型検査が動き出した
Elixir v1.20 が 2026 年 6 月 3 日にリリースされました。一番の変更は、set-theoretic types(集合論的型、型を集合として扱い和・積・差で組み合わせる方式)に基づく 型推論とコンパイル時の型検査が、注釈を一切書かなくても効くようになった ことです。動的型付け言語として育った Elixir が、既存コードに手を入れずに型由来のバグを拾い始めた。運用者として最初に確認すべきはこの一点です。
私は普段 Rails と Next.js を触っていて、Elixir を本番で回しているわけではありません。それでも言語のメジャーリリースは、運用者目線で読む癖がついています。Node.js のリリースを同じ目線で読んだときのメモもありますが、今回の Elixir はそれ以上に「設計思想の節目」に見えました。型を後付けする言語は多いものの、注釈ゼロで始める設計は珍しいからです。
dynamic() という型が、既存コードに効く理屈
要点を先に。1.20 の型システムの肝は dynamic() という特別な型で、これが「型注釈なしの既存コードでも、明らかに矛盾する箇所だけを警告する」という穏当な振る舞いを実現しています。
dynamic() には公式が挙げる 2 つの性質があります。1 つは互換性で、「供給された型と受け入れ側の型が 互いに素(disjoint、重なりがゼロ) のときだけ型違反を出す」。もう 1 つは絞り込み(narrowing)で、コードが実行される流れに沿って dynamic() が具体的な型へ refine されていく。だから関数に注釈を書かなくても、パターンマッチや case の各節を辿るうちに型が狭まり、矛盾が浮かび上がります。
この「重なりがゼロのときだけ怒る」設計が効きます。動的型付けのコードに full な静的型検査をいきなり被せると、警告の洪水で誰も読まなくなる。私は TypeScript の any を潰す作業や、Ruby に Sorbet を後入れする現場で、この洪水に何度も溺れかけました。Elixir は逆に「確実に間違っている所だけ」に絞ることで、既存コードを壊さず、無視されない警告を出そうとしている。設計者がノイズの怖さを知っている、という印象です。
「実行すれば必ず落ちるバグ」だけを拾う線引き
ここも結論から。1.20 のコンパイラが検出するのは、デッドコードと「もし実行されれば実行時に必ず失敗する型違反」です。曖昧な疑いではなく、確実な誤りに対象を絞っている。
公式は「If T: Benchmark for Type Narrowing」という型絞り込みのベンチで 13 カテゴリ中 12 を通過した と書いています。ガード節の和・積・否定、パターンマッチによる型の refine、case や条件分岐での節をまたいだ絞り込み、タプルやマップのサイズ追跡まで対応する。注釈の無いコードからここまで型を復元できるなら、移行初日から「タイポで存在しない関数を呼んでいる」類のバグは拾えるはずです。
線引きが保守的なのは、運用者にとってむしろ安心材料です。「たぶん危ない」を大量に出されると、本当に危ない 1 件が埋もれます。確実な誤りだけを出す方針なら、警告が出た = 直す、という単純な運用に落とせる。CI に組み込んだとき、フレーキーな警告で赤くならないのは地味に大きい。長年放置された不具合がきっちり修正される瞬間を別の記事でも書きましたが、ツールは「正しく無口」であるほど現場で生き残ります。
既存コードベースへ段階導入するときの現実
先に要点を。1.20 をそのまま mix compile に通すだけで型検査の恩恵が出るので、導入コストは低い。一方で、警告ゼロを目指すと既存コードの設計の粗が可視化されるので、心の準備は要ります。
段階導入の流れは素直です。まず Elixir を 1.20 へ上げ、コンパイル時に出る型警告を一覧で眺める。確実な誤りだけなので件数は爆発しにくいはずですが、出た分は実バグの可能性が高い。私が TypeScript や Sorbet の導入で学んだのは、「最初の警告リストを “後で直す” に積むと永遠に消えない」ということです。少数のうちに片付けるのが結局いちばん速い。
ビルド面の補足もあります。1.20 では :module_definition: :interpreted というコンパイラオプションが追加され、大規模プロジェクトのビルドを最適化できるとされています。公式は BEAM 系言語の中で「合成ベンチでは最速」とも主張していますが、この種のベンチは前提条件で数字が動くので、自分のプロジェクトで mix compile の時間を実測してから信じるのが安全です。ベンチの順位より、手元のリポジトリでの体感が信用できます。
注釈を書かずに型の恩恵を受けたい、というのは少し図々しい願いだ。Elixir 1.20 はそれを、全部ではなく「確実な誤りだけ」という形で叶えてきた。
運用者として、1.20 をどう迎えるか
結論。今すぐ全面移行する話ではなく、「型検査という無料の安全網が 1 枚増えた」として、低リスクな所から試す段階です。判断材料を 3 つに絞ります。
まず、CI で型警告を可視化する。本番の挙動は変えずに、コンパイル時の型警告だけをログに出して傾向を見る。確実な誤りだけなので、出た警告は素直にチケット化できます。次に、移行は「思想と仕様を分ける」。型を入れる目的(壊れにくさ)と、どこまで注釈を将来書くか(仕様)を切り分けると、議論が空回りしません。この切り分けは要件定義の記事でも書いた、手戻りを減らす癖です。
最後に、期待値を正しく置く。1.20 は型注釈を書ける完成版ではなく、土台が動き出した版です。再帰型もパラメトリック型もこれから。だから「Elixir が静的型言語になった」と早合点せず、「動的型付けの良さを保ったまま、確実なバグだけ機械が拾ってくれる段階に来た」と読むのが、運用者として一番ズレない受け止め方だと思います。
まとめ: 安全網が 1 枚、静かに増えた
Elixir v1.20 は、注釈ゼロで型推論と型検査が効き始めた節目のリリースです。持ち帰る点を並べます。
- 2026 年 6 月 3 日リリース。set-theoretic types に基づく型推論とコンパイル時型検査が、注釈なしで動く
dynamic()の互換性(互いに素なときだけ警告)と絞り込みで、既存コードを壊さず確実な誤りだけを拾う- 「If T」ベンチは 13 カテゴリ中 12 通過。検出対象はデッドコードと「実行すれば必ず落ちる」型違反に限定
- 型シグネチャ正式版の前段で、再帰型・パラメトリック型・性能検証が残る開発マイルストーン
私は Elixir を本番で回してはいませんが、もし回していたら、まず CI に型警告を出すところから始めます。順位表の最速ベンチではなく、自分のコンパイルログに出た数件の警告から手をつけます。
よくある質問
- Elixir 1.20 を入れると型注釈を書く必要がありますか?
- いいえ。1.20 の型推論と型検査は注釈なしで効きます。set-theoretic types に基づき、既存の動的型コードでも矛盾が確実な箇所だけを警告します。型シグネチャ(関数の型注釈)を書ける正式版は今後のマイルストーンです。
- dynamic() 型とは何ですか?
- 型注釈の無いコードを扱うための特別な型です。供給された型と受け入れ側の型が互いに素(重なりゼロ)のときだけ型違反を出す互換性と、実行の流れに沿って具体的な型へ refine される絞り込みの 2 性質を持ち、既存コードを壊さずバグを拾えます。
- コンパイラはどんなバグを検出しますか?
- デッドコードと、もし実行されれば実行時に必ず失敗する型違反です。曖昧な疑いではなく確実な誤りに絞っています。型絞り込みのベンチ「If T」では 13 カテゴリ中 12 を通過したと公式が報告しています。
- 既存プロジェクトへの導入コストは高いですか?
- 低めです。Elixir を 1.20 へ上げて mix compile を通すだけで型警告が出ます。確実な誤りだけなので件数は爆発しにくい一方、出た警告は実バグの可能性が高いので、少数のうちに片付けるのがおすすめです。