ハクソク

世界を動かす技術を、日本語で。

Zig – 型解決の再設計と言語の変更

概要

  • Zigメインブランチの2026年の主な変更点をまとめた内容
  • 型解決ロジックの大幅な再設計と、それに伴うユーザー向け改善
  • io_uring・Grand Central Dispatchベースの新I/O実装の導入
  • パッケージ管理ワークフローの2つの大きな強化
  • 各変更点の実例や利点、今後の展望について解説

型解決ロジック再設計とユーザー向け改善

  • Zigコンパイラの内部型解決ロジックを、より論理的かつ直感的な設計に再構築
    • 30,000行規模のPRを2〜3ヶ月かけてマージ
  • 型の「フィールド解析」がより遅延的に実行されるよう変更
    • 未初期化の型に対しては、Zigが型の詳細を気にしなくなった
    • 型を名前空間として使うパターンで、不要なコードの取り込みを防止
  • 依存ループ発生時のエラーメッセージが非常に詳細かつ分かりやすく改善
    • 依存関係のどこでループが発生しているか、明確に特定可能
  • インクリメンタルコンパイル機能の大幅なバグ修正と高速化
    • 不要な再解析(オーバーアナリシス)問題の解消
  • その他、多数のバグ修正・小規模な言語仕様変更・パフォーマンス向上
    • 詳細はCodeberg上のPR参照、バグ報告も歓迎

io_uring・Grand Central Dispatch対応 std.Io 実装の追加

  • std.Io.Eventedにio_uring・Grand Central Dispatch(GCD)ベースのI/O実装を追加
    • **ユーザ空間スタック切り替え(fibers/green threads)**を利用
  • これらは実験的段階であり、今後の課題として以下が残る
    • エラーハンドリングの強化
    • ロギングの削除
    • IoMode.evented利用時のパフォーマンス低下の原因調査
    • 未実装関数の補完・テストカバレッジ拡充
    • 関数ごとの最大スタックサイズ取得組み込み関数の追加
  • I/O実装の切り替えが容易で、アプリケーションコードの変更が最小限
    • **Hello, World!**の例で、I/O実装のみ差し替え可能
  • Zigコンパイラ自体もstd.Io.Eventedで動作確認済み
    • ただし現状、パフォーマンス低下が未解決

パッケージ管理ワークフローの2つの強化

  • 取得済みパッケージをプロジェクトルートのzig-pkgディレクトリに保存
    • .zig-cache外に配置することで、自己完結型ソース配布やオフラインビルドが容易
    • .gitignore等での除外推奨
  • 依存パッケージのグローバルキャッシュも追加
    • 未使用ファイルを除外し、再圧縮して保存
    • 複数PC間でのキャッシュ共有や、将来的なP2Pトレント配布の基盤
    • パッケージの人気度やネットワーク障害時の耐障害性向上
  • **zig build --fork=[path]**フラグ追加
    • パッケージのソースをプロジェクトごとに上書き・編集できるように

まとめ

  • Zigの2026年の進化は型解決・I/O実装・パッケージ管理の3本柱
  • 開発体験向上と今後の拡張性に重点を置いたアップデート
  • 詳細や最新情報はCodebergや公式ドキュメント参照推奨

Hackerたちの意見

Zigを本番や半真面目なアプリケーションで使ってる人の意見を聞きたいな。ソフトウェアの安定性が大事なところでどうなの?常に変わる言語との経験はどう?アップデートや書き直しのサイクルはどんな感じ?使ってるパッケージが言語に追いつかないことってある?Bunはある程度成功してるみたいだけど、他の人たちはどうなんだろう。
言語自体はあまり変わらないけど、標準ライブラリは変わるね。人によるけど、標準ライブラリにあまり頼らない人もいれば、まだ必要な古いコードをコピーする人もいる。> 使ってるパッケージが言語に追いつかないことってある?サードパーティのパッケージを使うのは結構問題があるよ。個人的にはあまり使わない方がいいと思う、余計な手間が増えるから。
Zig 0.15はかなり安定してるよ。毎日直面する一番の問題は、ちょっとしたことで起こる静かなコンパイラエラー(SIGBUS)だね。例えば、インポートパスのタイプミスとか。これが[たまに]クラッシュを引き起こす理由はまだわからないけど、大きな変更セットで見つけるのは本当に面倒。`zig ast-check`が時々エラーをキャッチしてくれるけど、Claudeは僕が誤って変数名を再利用したところを見つけるのが得意だよ(90%の確率で簡単なミスなんだけど、残りの10%ではメッセージなしのコンパイラクラッシュが起こる)。OPの変更はこういう問題に特に対処してるみたいだね。それと、今の.zig-cacheは173GBで、テストしてる小さいLinux ARM VPSにちょっと問題を引き起こしてる。アップグレードについては、lightpandaを0.14から0.15にアップグレードしたけど問題なかったよ。lightpandaに関しては、0.16の変更はそんなに悪くないと思う。唯一の潜在的な問題はlibcurlの使用と小さなWebSocketサーバー(CDP接続用)から来るかもしれないけど、それらは比較的孤立してるから、期待してるよ。ライブラリ開発者としては、0.16の追跡を諦めた。というのも、変更が僕には響かないし、変化が速すぎるから。今のところ、ライブラリで0.16のサポートを期待してる人はいないと思う。数人の勇敢な人たちから「dev」ブランチにPRをもらったけど、みんなそのアレンジに満足してるみたい。
最近Zigを学ぼうとしたけど、イライラしたよ。ドキュメントの多くは0.15用だけど、最新は(またはだった)0.16で、標準ライブラリがかなり変わったから、既存の解説が通用しなくなっちゃった。もっと安定したら再挑戦するつもりだけど、うまく動いたときは好きなんだよね。
約25万行のZigコンパイラのコードベースを維持してるよ。[0] いくつかの破壊的なZigリリースを経験したけど(そのほとんどの間、コードベースはもっと小さかったし)、Writergateが100K行を超えてからの主な問題だった。言語や標準ライブラリの変更は、少なくとも1、2年は大きな痛点じゃなかったよ。数年前にアップグレードがあったけど、時間がかかった記憶がある(たぶん0.12から0.13にアップグレードしたと思うけど、正確なバージョンはうろ覚えかも)。でも、最近はずっとスムーズに進んでる。今は破壊的なリリースは「ちょっと面倒」って感じで、Zigの良いところや悪いところを聞かれても、あんまり思い出さないんだよね。[0]: https://github.com/roc-lang/roc
俺みたいにこのソフトウェアを知らない人のために:Bun、JavaScript用のパッケージ管理サービスみたいなものだよ。https://en.wikipedia.org/wiki/Bun_(software)
3つのプロジェクトでコンパイラを0.14で更新するのをやめた。正しいツールチェーンを手に入れるのが、俺の(段階的な)ビルドプロセスの一部なんだ。外部のZigパッケージは使ってない。これらのプロジェクトを0.15にするために必要な面倒な変更の一つは、ミックスインを実装するために使ってた`usingnamespace`を削除することだと思う。プロジェクトは全部数千行で、それほど大変じゃないはずなんだけど、アップグレードから得られるものが今のところやる価値がないって感じ。まあ、これでいいと思う。
ミッチェル・ハシモト(Ghosttyの開発者)はZigについてよく話してる。GhosttyはZigで書かれていて、彼はそれをすごく気に入ってるみたい。彼にはその変化が全然気にならないみたい。少し前のスレッドで彼に聞いてみたよ:https://news.ycombinator.com/item?id=47206009#47209313 TigerBeatleの製作者たちもZigがどれだけ良いかを絶賛してる。
C++の永遠に後方互換性を保つ約束は、2026年には心の死を招いた大きな設計ミスだった。コードを修正しなきゃいけないのは面倒かもしれないけど、長期的には正しいアプローチなんだ。
私は2つの「プロダクション」Zigコードベースで作業したことがあるよ:tigerbeetle [0] と sig [1]。これらの大きなZigプロジェクトは、タグ付きリリース(変更されないもの)を維持して、新しいタグ付きリリースにアップグレードするんだ。通常、リリースが出てから数日か数ヶ月後にアップグレードする。アップグレード自体は、行う変更の量によって1週間くらいかかるよ。このプロジェクトは他のZig依存関係を使わない傾向もあるね。[0]: https://github.com/tigerbeetle/tigerbeetle/pulls?q=is%3Apr+a... [1]: https://github.com/Syndica/sig/pulls?q=is%3Apr+author%3Akpro...
> BunがZigをある程度成功させているのは知っているけど、他はどうなんだろう。成功の度合いはどれくらい?
開発者におめでとう!30,000行のPRは、言語コンパイラ(しかもかなり非トリビアルなコンパイラ)にとって誇らしい成果だね。でも、これほどの規模の変更は本格的な開発を意味していて、ちょっと考えさせられる。以下の2点は理解してるよ:1. 言語開発は一般的に難しいテーマで、特に広く採用されることを目指している言語や、インフラで数十年単位の使用を期待している言語にとっては特にそう。2. Zigはまだ若い言語で、1.0には達していなくて、TFAの投稿時点で明確に進化中だ。これらの点を考慮すると、次のコードバーグの投稿からの以下のカジュアルさには驚かされる:‘’’このブランチは「インスタンス化できない」型(noreturnのような、値を持たない型)の意味を変更します。最初はここでこれをやるつもりはなかったけど、マスターの意味に合わせるのがかなり難しかったから、既存の意味があまり意味をなさなかったんだ。’’’ Zigの言語やコンパイラ開発における特定の戦略や用語は知らないけど、ここでの「ブランチ」という言葉は、これは言語に完全に/正式に採用された変更ではなく、むしろ完全に実装された提案だと思う。たとえそれが変更の提案に過ぎなくても、書き直しの規模が大きく、著者がそれが好意的に受け入れられることを期待しているという明確な示唆は、あまり見られない自信に思える。生産用途のある言語の意味を変更することは、ほぼ定義上メジャーな変更で、PRが意味を変更すると軽々しく述べて、深い議論(以前にあったかはわからないけど)やその変更の限られた影響に関する真剣な正当化や声明なしに進めるのは、他のあまり「真剣」でない言語の進化(または退化)を見てきた中では経験したことがない。これは「この開発者」の問題なのか、Zigの問題なのか、それとも僕が現代の言語(あるいはもっと大規模な開発)プロジェクトに疎いだけなのか?それと、TFAの全体的な流れにはあまり重要ではないけど、著者が「現代のZig」というフレーズを使っているのが、Zigの年齢と現在の変化の速度を考えると、すごく面白い表現に感じた。
mluggはZigのコア貢献者の一人で、Zig財団のメンバーだと思う。彼らは依存関係の解決に取り組みたがってたから、これを整理してくれて本当に嬉しいよ(不明瞭な循環依存エラーに以前やられたことがあるから)。まだ正式な言語仕様はないけど、かなり速く進んでるから、正直なところ、標準の必要性は感じないよ。今はそれが彼らの目標じゃないからね。
元々、Zigの型システムは「ゼロ」型(noreturnとも呼ばれる)に関してあまり厳格ではなかった。これはここで提案され、議論され、受け入れられた: https://github.com/ziglang/zig/issues/3257 後に、Matthew Luggがフォローアップの提案を行い、それは公に、またZSFコアチームの会議でも議論された。 https://github.com/ziglang/zig/issues/15909 彼はこう書いている:> この振る舞いの(かなり論争のない)サブセットが[私たちが議論している変更セット]で実装されました。今はこれを閉じますが、いつかこの意味をもっと正確に再訪することになると思うので、その時はCodebergに新しい問題を開くつもりです。これがカジュアルなHN読者にどれだけ明らかかはわからないけど、僕にとってこの変更セットはZigという言語を実験的な領域からかなり正式に指定されたものへと移行させるものだと思う。なぜなら、型解決を有向非巡回グラフにするから。どれだけのバグが解決されたかを見れば、その感覚がつかめるよ。この変更セットだけで、次のコンパイラのリリースはかなり堅牢になるだろう。デザインや開発について話すのは好きだけど、とはいえZigプロジェクトは完全な透明性を目指しているわけではない。READMEにもこう書いてある:> Zigは自由でオープンソースソフトウェアです。誰でもバグ報告やパッチを歓迎します。ただし、ZigのガバナンスはBDFN(Benevolent Dictator For Now)で、Andrew Kelleyがすべてのデザインと実装に最終的な決定権を持っています。言語やプロジェクトが信頼できる手にあるかどうかはあなた次第。これだけは言えるよ:私たち(開発チーム)は強いビジョンを持っていて、プロジェクトに深く関わっている。自分たちの夢を実現するためだけでなく、私たちがサポートする尊敬するユーザーの夢を実現するためにもね[1]。さらに、501(c)(3)の非営利団体として、私たちには悪化させる動機はない。 [1]: https://ziglang.org/documentation/master/#Zen Matthewと一緒に仕事するのは素晴らしい経験だ。これからも何年も彼を同僚と呼べることを楽しみにしてる。
ちょっと考えただけなんだけど、こういう振る舞いがもっと普通になったのは、Cの全体的な混乱のせいかもしれないね。Cは一応正しいルールに従ってるはずなのに。
> Zigの言語やコンパイラ開発に関する特定の戦略や用語は知らないんだ。 確かに知らないね…聞いてみればよかったんじゃない? > 一般的に悪いアイデアだと思う。 > 以前に起こったかもしれないこと、わからない。 確かにわからないね。聞いてみればよかったのに。言語BDFNのアンドリュー・ケリーの返答をチェックしてみて。
誰かのコミュニケーションがカジュアルで非公式な場合、文脈がないと本当に区別がつかないよね。* 著者が軽薄で、状況を真剣に受け止めていない。 * 著者が高い信頼関係を持つ読者を前提にしていて、必要なことはすでにやっているから、わざわざ言い直す必要がない。今回は、まだ1.0に達していない言語の開発ログ(いわゆる「マーケティング投稿」ではない)なんだ。ある程度「ここにいるなら、たぶん背景があるよね」というのは妥当だと思う。投稿はPRに直接リンクしていて、PRには著者が何をしているかが明確に伝わるコンテキストがたくさんある。言語の(マイナーな)変更が軽く触れられているのを読むのはちょっと変な感じだね。私たちは言語が非常に安定していることに慣れているから。でも、Zigはまだ1.0じゃない。アンドリューと仲間たちはユーザーの安定性を真剣に考えているけど、今日この言語を選ぶと、ある程度の破壊は覚悟しないといけない。1.0以降の言語を維持している者として、こういう破壊的な変更には本当に価値があると思う。ユーザー数が少ないうちに問題を修正するのは良いことだよ。ユーザー数が増えすぎて、実際に修正するのが難しくなると、明らかな欠陥を抱えなければならないのはイライラする。ユーザー全員が修正してほしいと思っているのにね。(例:C言語のビット演算子の優先順位の問題。)まだ柔軟なうちに、できるだけクリーンで堅牢な言語を提供するのが未来のユーザーにとっても良いことだよ。
型解決のための3万行のPRは怖そうだけど、これがまさに1.0未満の意味なんだ。Rustも安定化する前に似たような基盤の再構築を何度も経験したことを思い出して。古いシジルベースのポインタ構文を覚えてる? 後方互換性を確保する前に型システムを正式に整えるのは、一時的な混乱の価値があるよ。本当の試練は、この新しい設計が将来の型システムの変更をより小さく、段階的にするかどうかだね。もう一度3万行を書き直す必要がなくなるかどうかがポイント。
Zigチームの成果には感心してる。俺はGhosttyターミナルエミュレーターを定期的に使ってるけど、Zigで作られてて超安定してる。素晴らしいソフトウェアだよ。これでZigの基盤技術がしっかりしてると感じる。でも、ZigよりRustの方が好きなんだ。主な違いは、Rustが「クローズドワールド」モデルを選ぶのに対して、Zigは「オープンワールド」モデルを選ぶことだね。Rustではトレイトを明示的に実装しなきゃいけないけど、Zigでは形が合えば、構造体のメンバーに`.`があれば(渡した型に関係なく)、動くんだ(Zigを使ってないから、ちょっと曖昧な説明でごめんね)。これがZigに非常に強力なメタプログラミング能力を与えるけど、どんな型の「形」が使われるかがわからないから面倒なんだ。ZigはC++のテンプレートに似てる部分もある。これがあちこちに波及効果をもたらす。Rustが生成するドキュメントは、構造体がサポートする関数について非常に豊富で明示的だよ(各トレイトが明示的に登録されて実装されてるから)。Zigではコードの動的な性質がオートコンプリートやドキュメント、LSPサポートなどで問題になるんだ…。
> でも、私はZigよりRustの方が好きだな。主な違いは、Rustが「クローズドワールド」モデルを選ぶのに対して、Zigは「オープンワールド」モデルを選ぶことだね。Rustではトレイトを明示的に実装しなきゃいけないけど、Zigでは形が合っていれば、または構造体のメンバーに`.`があれば(渡す型に関係なく)、動くんだ。(Zigは使ったことがないから、説明が曖昧でごめん。)具体的な例があったりする?実際にどうなるのか興味あるな。君の説明はGoのインターフェースに似ている気がするけど、私のZigの理解では、フィールドの親ポインタのバリエーション以外に直接の相当物はないと思うんだ。