**Rustc を苦しめる ― 高階型(HKT)の擬似実装で挑む**

2026/03/14 16:25

**Rustc を苦しめる ― 高階型(HKT)の擬似実装で挑む**

RSS: https://news.ycombinator.com/rss

要約

日本語訳:


Summary

この記事では、Rust が高度な汎用抽象化(例:関数型スタイルのスクリプト言語や深く再帰的なデータ構造)をサポートする際に直面する困難について説明しています。主因は、高階型(HKTs)が欠如していることと、共帰性 trait 解決が限定的である点です。

  1. Rust で HKTs を試みる
    著者はまず

    Ast
    列挙型を使って FP スクリプト言語を構築しようとしました。この列挙型はラッパー型(
    Spanned
    ,
    Simple
    )を受け入れます。しかし、Rust には HKTs がないため、ジェネリックパラメータを型コンストラクタにすることができません。回避策として、
    Wrap
    トレイトと関連型
    Wrapper<T>
    を導入し、
    VecAsTypeConstructor
    のようなマーカー構造体で実装しました。

  2. 再帰的定義がソルバーを破壊

    Wrap
    を用いて
    Ast
    を書き直すと、リンクリストの
    Cons
    などの再帰型がコンパイル時に “overflow evaluating the requirement … PartialEq” のようなエラーを生成します。これは
    PartialEq
    のような trait に対して無限証明木が生じるためであり、Rust の帰納的ソルバーでは処理できません。

  3. Lean 4 が真の共帰性を示す
    共帰的推論がどのように機能するかを示すため、著者は Lean 4 を用いて「任意の数は 3 で割り切れる」ことを inductive 型

    S
    を使って証明しました。証明では
    obtain
    ,
    exists
    のタクティックと存在量化子が使用され、Rust の trait システムに欠ける洗練された論理的アプローチを示しています。

  4. Rust のソルバー環境
    Rust では Chalk が trait を論理推論へマッピングします。次世代ソルバーは

    Send
    のような auto‑trait を共帰的に証明できるものの、非共帰性循環にはまだ失敗します。最小例(
    Foo<W>
    とその
    Wrap
    実装)では、
    PartialEq
    実装が循環を作り、Rust はこれを不安全として拒否します。

  5. ICE がソルバーバグを露呈
    次世代ソルバーは

    Foo<Noop>
    を比較するときに内部コンパイラエラー(ICE)を引き起こし、循環 trait バウンドの取り扱いに具体的なバグがあることを明らかにしました。

  6. 広範な影響と変更への呼び掛け
    著者は Rust に HKTs やモナド、および包括的な共帰性サポートが欠如していることに苛立ち、これらのギャップが高度な型システム機能を本格的に利用する妨げになると主張しています。Lean 4、論理学、帰納/共帰推論などの学習リソースは有用だと述べつつ、記事は言語変更―段階的修正ではなく―が Rust を複雑な抽象プログラミングに適合させるために必要であると結論付けています。


欠落要素:改善された概要にはリストからのすべての重要ポイントが含まれ、例やエラー、ソルバー挙動を明示的に命名しています。元のテキストが伝える内容以外に推測は加えられていません。

本文

読書時間: 32 分


目次

  1. 前奏
  2. Rust は実際には HKT を持っていない、ということ
  3. 「1 + 1 は何?」―当然 Trait 要件評価のオーバーフロー
  4. 数学的証明と論理への逸話
    • 4.1 自然数を超えた帰納法
    • 4.2 カリーとハワードが共同でヤオイを斬った瞬間…
    • 4.3 記事の中の自己陶酔的 Lean 4 部分
  5. 今度はあなたが最も好きなプログラミング言語へ戻る
    • 5.1 Discord の会話に戻り、帰納循環とは何かを説明する部分
    • 5.2 共帰性の大災害

前奏

2026 年 2 月 28 日、私は FP スクリプト言語を書き始めました。
最初は計算機用に単純な

Ast
列挙型から始めました。

pub enum Ast {
    Binary { left: Box<Ast>, operator: Token, right: Box<Ast> },
    Unary  { operator: Token, right: Box<Ast> },
    Value  { value: Value },
}

ソースのスパン情報をオプションで付与したいと考えました。
最初の試みは次のように。

pub struct Spanned<T> { inner: T, span: std::range::Range }
pub struct Simple<T> { inner: T }

後にこれを汎用ラッパーへ抽象化しました。

pub struct Wrapper<T, M> { inner: T, metadata: M }

type Spanned<T>  = Wrapper<T, std::range::Range>;
type Simple<T>   = Wrapper<T, ()>;

この

Wrapper
Ast
に適用しようとすると、こうなります。

pub enum Ast<W: ???> {
    Binary { left: Box<W<Ast>>, operator: Token, right: Box<W<Ast>> },
    Unary  { operator: Token, right: Box<W<Ast>> },
    Value  { value: Value },
}

Rust は高階型(HKT)を持たないため、

W
を「型コンストラクタ」として扱うことはできません。
そこで GAT とトレイトソルバーの世界へ踏み込みました。


Rust は実際には HKT を持っていない、ということ

高階型を使えばジェネリックがさらに別のジェネリックを受け取れるようになります。

struct Foo<T>(T<i32>);

ここで

T
は arity 1 の「型コンストラクタ」です。
Rust では 単純 なジェネリックしかサポートされておらず、型コンストラクタは存在しません。

GAT を使ってラッパー・トレイトを定義してみました。

trait Wrap { type Wrapper<T>; }

struct VecAsTypeConstructor;
impl Wrap for VecAsTypeConstructor {
    type Wrapper<T> = Vec<T>;
}

これで

Foo
は次のように書けます。

struct Foo<T: Wrap> { inner: T::Wrapper<i32>, }
type Bar = Foo<VecAsTypeConstructor>;

動作しますが、あくまで一時的な回避策です。


「1 + 1 は何?」―当然 Trait 要件評価のオーバーフロー

小さな計算機を作り、テストを書きました。
コンパイラは次のように報告します。

error[E0275]: overflow evaluating the requirement `Wrapper<Ast<SpannedMarker>, std::range::Range<usize>>: PartialEq`

PartialEq
を手動で再実装しても改善しませんでした。
最小再現例では、再帰型でも同じエラーが発生します。

#[derive(Debug, PartialEq)]
struct Cons<W: Wrap> {
    inner: W::Wrapper<i32>,
    next : Option<Box<W::Wrapper<Cons<W>>>>,
}

Discord で議論しデバッグを重ねた結果、これは 帰納循環 の問題だと理解しました。


数学的証明と論理への逸話

カスタム帰納集合

S
のすべての要素が 3 の倍数であることを証明するために帰納法を探求しました。
Lean 4 を使って次のように書きました。

inductive S where
  | six     : S
  | fifteen : S
  | step    : S → S → S

def S.toNat (s : S) : Nat := match s with
  | six      => 6
  | fifteen => 15
  | step a b => toNat a + toNat b

def Threeven (i : Nat) : Prop := ∃ k, i = 3 * k

theorem three_divides_six : Threeven 6 := by exists 2
theorem three_divides_fifteen : Threeven 15 := by exists 5

theorem three_divides_threeven_plus_threeven
    (a b : Nat) (ha : Threeven a) (hb : Threeven b) :
    Threeven (a + b) := by
  obtain ⟨a', ha⟩ := ha
  obtain ⟨b', hb⟩ := hb
  exists a' + b'
  rw [ha, hb, Nat.mul_add]

最終的に次を証明しました。

theorem S.is_threeven (s : S) : Threeven s.toNat := by
  induction s with
  | six => apply three_divides_six
  | fifteen => apply three_divides_fifteen
  | step a b ha hb =>
      rw [S.toNat]
      apply three_divides_threeven_plus_threeven
      · exact ha
      · exact hb

今度はあなたが最も好きなプログラミング言語へ戻る

帰納循環 vs. 共帰性

Rust のトレイトソルバーは 帰納的 です。証明木は有限でなければならないため、

List<T>
のような再帰型では無限になる可能性があります。その場合 Rust は自動トレイト(
Send
等)に対してのみ 共帰的 とみなし、循環を許容します。

例:

Send

List<i32>: Send
├─ i32: Send          (基底ケース)
└─ Option<Box<List<i32>>>: Send
   └─ Box<List<i32>>: Send
      └─ List<i32>: Send  ← 循環

Send
が共帰的であるため、この循環は許容されます。

共帰性の大災害

汎用ラッパーを使った最小例です。

use std::marker::PhantomData;

trait Wrap { type Wrapper<T>; }

#[derive(Debug, PartialEq)]
struct Noop;
impl Wrap for Noop {
    type Wrapper<T> = T;
}

#[derive(Debug, PartialEq)]
struct Foo<W: Wrap>(PhantomData<W::Wrapper<Foo<W>>>);

Foo<Noop>
は帰納的に
PartialEq
を実装できません。証明木には循環が含まれるためです。

Foo<Noop>: PartialEq
├─ PhantomData<Noop::Wrapper<Foo<Noop>>>
└─ Noop::Wrapper<Foo<Noop>>: PartialEq  ← 循環

PartialEq
は共帰的ではないので、Rust は実装を拒否します。
次世代ソルバーを使うと内部コンパイラエラーに至ります。


結論

  • Rust は真の HKT をサポートしていません;GAT は部分的なワークアラウンドです。
  • トレイト解決はデフォルトで帰納的ですが、特定の自動トレイト(
    Send
    など)では共帰性が許容されます。
  • 再帰的ジェネリック型は無限証明木を引き起こすため、共帰的トレイト以外では失敗します。

これらの制約にも関わらず、トレイトソルバーを掘り下げることでタイプ理論や帰納・共帰性について深い理解が得られました。日常的な Rust プログラミングを超えたテーマです。

同じ日のほかのニュース

一覧に戻る →

2026/03/18 3:59

**スラグの十年**

## 日本語訳 --- ## 要約 Slug アルゴリズムのライブラリは十周年を迎え、パブリックドメインに移行しました。これにより開発者はライセンス費用から解放され、強力な GPU‑direct テキストレンダリングが提供されます。2016 年秋に開発され、2017 年中頃に *JCGT* に論文が掲載され、その直後に Slug ライブラリのバージョン 1.0 が公開されました。 **主要な技術的進歩** - **ダイナミック拡張(Dynamic Dilation)**:MVP 行列とビューポート寸法を用いて頂点シェーダで半ピクセル外側に自動拡張を計算します(式 \(d = \frac{s^3t + s^2\sqrt{u^2+v^2}}{u^2+v^2-s^2t^2}\))。これにより不要なパディングが排除され、エッジは鮮明に保たれます。 - **バンド分割最適化の削除**:ピクセルシェーダを簡素化し、バンドデータサイズを 4 つの 16‑bit コンポーネントから 2 に半減します。 - **アダプティブスーパーサンプリングの廃止**:ダイナミック拡張がエイリアシングを処理するため、追加コードはほぼ読み取り可能な文字だけに効果がありました。 - **絵文字レンダリングの簡素化**:レイヤーごとのループから独立したグリフレイヤリングへ切り替え、頂点数オーバーヘッドを削減しました。 これらの変更は、2016 年代のコンソールでの頑健性と高速化、高品質なアンチエイリアス出力(任意のスケールやパースペクティブ)を実現し、新しい GPU への保守性も向上させることを目的としていました。 **業界採用** Slug は C4 Engine のテキストエンジン、後に Radical Pie 方程式エディタで活用されました。Activision、Blizzard、id Software、2K Games、Ubisoft、Warner Brothers、Insomniac、Zenimax などの主要ゲームスタジオや、Adobe などの非ゲーム企業もライブラリを使用しています。 **パブリックドメイン状態** 特許 #10 373 352(2019 年に付与)は 2026 年 3 月 17 日からパブリックドメインへ譲渡されました。USPTO に Form SB/43 が提出され、料金が支払われたため、すべてのコードが自由に利用可能です。参照用頂点シェーダとピクセルシェーダは GitHub 上で MIT ライセンスされています。 **影響** 開発者は Slug の GPU‑direct レンダリングとダイナミック拡張を、ゲーム、アプリケーション、あるいは任意のグラフィックスソフトウェアにライセンス料なしで統合できます。簡素化されたシェーダは開発時間とリソース消費を削減し、パブリックドメイン公開によりコミュニティによる貢献が促進され、技術のさらなる洗練が期待されます。 ---

2026/03/18 5:23

**仕事を成し遂げる:メタプロンプティング・コンテキストエンジニアリング・スペック駆動型開発システム**

## 日本語訳: **GSD(“Get Shit Done”)** は、Claude Code、OpenCode、Gemini CLI、Codex、Copilot、および Antigravity など複数の AI コーディングランタイムを統合する軽量メタプロンプトフレームワークであり、コンテキストロット(文脈劣化)を緩和し、信頼性の高いコード生成を実現します。 インストールは `npx get-shit-done-cc@latest` で行い、ランタイムごとにグローバルまたはローカル設定(例:`--claude --global`、`--opencode --local` 等)を選択します。 コアワークフローは一連のコマンドによって駆動されます: - `/gsd:new-project` (プロジェクトスケルトン作成) - `/gsd:discuss-phase`、`/gsd:plan‑phase`、`/gsd:execute‑phase`、`/gsd:verify‑work`、`/gsd:complete‑milestone`、`/gsd:new‑milestone` - `/gsd:quick`(アドホックタスク)でオプションフラグ `--discuss`、`--research`、`--full` を付与可能。 各フェーズは構造化ファイル(`PROJECT.md`、`REQUIREMENTS.md`、`ROADMAP.md`、`STATE.md`)と XML 形式の計画を生成し、Git に対してアトミックにコミットします。コミットは `feat(08‑02): add email confirmation flow` のようなパターンに従い、正確な bisect と明瞭な履歴が保証されます。 GSD は研究者・計画者・実行者・検証者という 4 人のエージェントを調整し、メインコンテキストウィンドウ(≈30–40 %)を新鮮に保ちつつ数千行のコードを生成します。 設定は `.planning/config.json` に格納され、ユーザーは `mode`、`granularity`、`workflow.research`、`git.branching_strategy` およびモデルプロファイル(`quality`、`balanced`、`budget`)を指定できます。また、`.env` やシークレット・キー等の機密ファイルを保護する deny リストも用意されています。 本プロジェクトは MIT ライセンスで公開されており、OpenCode、Gemini CLI、および Codex 用のコミュニティポートが存在します。Amazon、Google、Shopify、Webflow のエンジニアに信頼されており、最小限の “ロールプレイ” オーバーヘッドを重視しています―数個のシンプルなコマンドで複雑なワークフロー管理を抽象化します。 今後のアップデートではエージェントオーケストレーションの拡張、クイックモードフラグの洗練、および設定オプションの強化を目指しています。ワークフローを簡素化しツールング・オーバーヘッドを削減することで、GSD は個人開発者および企業にとって開発サイクルの高速化とコード品質の向上を実現できます。

2026/03/18 3:37

Python 3.15 のJIT(Just‑In‑Timeコンパイラ)が再び順調に進んでいます。

## Japanese Translation: (すべての主要ポイントを取り入れています):** CPython 3.15/3.16 JIT プロジェクトは、初期段階でパフォーマンスマイルストーンを達成しました。macOS AArch64 上では、JIT が tail‑calling インタプリタより約11〜12 %高速であり、x86_64 Linux では標準インタプリタを約5〜6 %上回っています。また、パフォーマンステストは幅広い結果を示しています。`unpack_sequence` マイクロベンチマークを除けば、約20 %の遅延から100 %以上の速度向上まであります。 主な技術的進歩には次が含まれます: - **トレース記録**:単一の「tracing」命令とデュアルディスパッチテーブルを使用し、インタプリタの肥大化を削減。Linux 上では約6 %遅延から約1〜2 %高速に改善しました。 - **参照カウントの除去**:分岐除去最適化で、命令ごとのオーバーヘッドを削減し、貢献者にとって有益な学習機会を提供します。 JIT チームは 2025 年に主要スポンサーを失いましたが、コミュニティの監督によって努力が継続しています。コア貢献者には Savannah Ostrowski、Mark Shannon、Diego Russo、Brandt Bucher、Hai Zhu、Zheaoli、Tomas Roun、Reiden Ong、および Donghee Na が含まれます。中間レベルの貢献者数は 2 人から 4 人に増加しました。 Savannah の 4 台のマシンで毎日 JIT を実行し、パフォーマンスフィードバックを提供し、回帰を検出し、新しい最適化を検証します。スプリント計画(Cambridge コア スプリント)は、CPython 3.15 で 5 %高速な JIT、3.16 では 10 %、フリースレッディングサポートの追加、および JIT の各段階で活躍するメンテナーを 2 人ずつ確保することを目指しています。 これらの進歩により CPython は競争力を維持し、より広いコミュニティ参加を促進し、フリースレッディングなど将来の機能への土台を築いています。

**Rustc を苦しめる ― 高階型(HKT)の擬似実装で挑む** | そっか~ニュース