Upgrade to Pro — share decks privately, control downloads, hide ads and more …

なぜGoのジェネリクスはこの形なのか? - Featherweight Goが明かす設計の核心

なぜGoのジェネリクスはこの形なのか? - Featherweight Goが明かす設計の核心

Go 1.18でジェネリクスが導入されました。本セッションでは、その仕様、特に「なぜ型制約にinterfaceを使うのか」「なぜコンパイルにモノモーフィゼーションという手法が選ばれたのか」という設計上の選択について、その背景を解説します。
この設計の背景には、Goジェネリクス設計の根幹をなす理論的支柱、Featherweight Goという論文があります。この論文は、Goの父であるRob Pike氏や、Haskellなどで知られる型理論の権威Philip Wadler氏らが参加し、Goのジェネリクスに「理論的な正しさ」を与えるために行われました。この論文で示された理論的な裏付けが、初期案であったcontractsから現在のinterfaceベースの仕様へと繋がりました。
このセッションでは、Featherweight Go論文を基に、Goのジェネリクスの仕組みを深掘りし、以下の点をお話しします。

- interfaceが型制約として採用された経緯(contracts案との比較)
- モノモーフィゼーションの仕組みと、それがもたらす性能上のメリット
- 現在の仕様では実現できない「共変レシーバ」と、それが解決する「式問題」の解説

このセッションを聞くことで、Goのジェネリクスがなぜ現在の仕様になったのかを深く理解し、そのトレードオフを意識した上で、より自信を持ってコードを書けるようになります。

Avatar for QualiArts

QualiArts

October 06, 2025
Tweet

More Decks by QualiArts

Other Decks in Programming

Transcript

  1. Featherweight Goのアプローチ Goチームの要件 
 • 使いやすく理解しやすいこと
 • ランタイムコストが低いこと
 • 可能な限り保守的な拡張であること

    
 方針
 • 構造的サブタイピングとジェネリクスの組み合わせ
 • 追加の言語機能なしに型制約を導入
 • モノモーフィゼーションに基づいたコンパイル戦略 

  2. FGG

  3. まとめ FGの世界
 • 多態性をインターフェースで表現
 • 型の安全性は実行時に型アサーションで保証(プログラマの責任)
 • 常にパニックのリスクが伴う 
 FGGの世界


    • 多態性を型パラメータで表現
 • 型の安全性はコンパイル時に型制約で保証(コンパイラの責任)
 • パニックのリスクをコンパイル時に排除 

  4. ジェネリクスのコンパイル戦略 モノモーフィゼーション 
 • 型ごとに使われている部分の専用コードを生成
 • List[string] →(コンパイル)→ string専用のList
 •

    ランタイムで型アサーションが制限されない 
 • ランタイムオーバーヘッドが低いが、メモリをより食う 
 イレイジャ
 • コンパイル時に型情報を削除
 • List<String> →(コンパイル)→ List
 • ランタイムで型アサーションができない 
 • メモリはあまり食わない 

  5. Expression Problem Eval(評価) String(文字列化) PrettyPrint (整形) Num (数) 実装済み 実装済み

    後から追加したい Plus (足し算) 実装済み 実装済み 後から追加したい Mul (掛け算) 後から追加したい 後から追加したい 後から追加したい 行(データ型)と列(操作)のテーブル 関数型言語は列の追加が得意、オブジェクト指向言語は行の追加が得意
  6. Goと共変レシーバ リリースされた Goのジェネリクスも不変 (invariant) な設計を採用 - 構造体を定義した時点での型制約が、その後のすべてのメソッドで一貫して適用 - Plus[T any]ならメソッドも

    anyのまま、Plus[T Expr]ならメソッドも Exprのまま 現在のGoで、式問題のような拡張性を実現するには
 • 柔軟性を諦め、静的な安全性を取るか
 • 静的な安全性を諦め、柔軟性を取るか
 • 2つのトレードオフに直面