再びZigへ戻る - Zig → Rust → Zig
(gracefulliberty.com)- ZigはCの不便さを減らそうとする低レベル言語として出発し、明示的なメモリ割り当てや隠れた制御フローがないといった哲学によって、あらためて見直す価値のある言語になった
- RustはZigの頻繁な変更や未成熟なエコシステムから離れるための実用的な代替案だったが、FFI・クロスコンパイル・隠れた割り当てといった点で限界を見せた
- Zigに戻る決断には技術的な理由だけでなく、ガバナンスやLLM生成コード方針をめぐるRustプロジェクトへの信頼低下も影響した
- 2026年のZigは依然として不安定で、Zig 0.17.0はビルドシステムを壊す予定だが、言語感覚は2020年と大きく変わらず、パッケージ管理の体験は良くなっている
- ZigはRustのようなコンパイル時メモリ安全性を提供しない代わりに、ReleaseSafe・テスト・ファジング・assertionの哲学によって、単純さとランタイム安全性のバランスを選んでいる
Zigに惹かれた出発点
- Zigは2020年に初めて触れたが、当時はコンパイル時コード実行と単純な抽象化を備えた小さな新言語に見えた
- Cを学びながらコンピュータを直接制御する感覚は良かったが、古い抽象化や不足したツールは不便だった
- 新しく不安定であっても、ZigはCの代替言語を約束しており、「次の言語」を学べる点が魅力だった
- Andrew KelleyのSoftware Should Be Perfectは、プログラミング言語とソフトウェアを見る基準を形作った
- 失敗しうる明示的なメモリ割り当て
- 隠れた制御フローがないこと
- 普遍的な再利用性
- Zigでおもちゃのプログラミング言語、literate programmingツール、Webサーバーを作りながら、Cより快適だが危険要素は少ない言語のように感じた
Rustへ移った理由
- Zigではコードが頻繁に壊れ、学生だった自分には最新の言語バージョンに合わせてプロジェクトを継続的に修正する時間が足りなかった
- 当時はanyzigがなく、1つのシステムで複数のZigバージョンを簡単に扱うのが難しかった
- 数か月ぶりにプロジェクトへ戻ると、理解していない大きなリファクタリングをしないと再び動かないことがあった
- エコシステムもまだ小さかった
- 新米プログラマとして必要なものをすべて自力で実装する力量が不足していた
- ライブラリや例が少なかった
- 標準ライブラリが継続的に変わっていた
- 基本的なドキュメントも不安定だった
- Rustはすでに何年も安定化が進んでおり、強力なエコシステムを備えた言語だった
- Rustの学習は大変だったが、身につければコードは安定して動作し、その安定性が重要だった
- 高速で低レベルな言語でありながら必要な表現力を提供し、Zigで経験した不安定さのコストも減らしてくれた
- Rustは、より組み込み検査の少ない言語を使うときにも役立つメモリモデルを形作る助けになった
- panicのないコードでは、隠れた制御フローやガベージコレクタなしに再利用可能なコードを書けた
- ただしRustには、メモリ割り当てを隠し、Cとの作業を難しくする面があった
再びZigに目を向けさせた不満
- Rustは、望んでいた再利用可能なプログラムを作るのに完璧な言語ではなかった
- FFIが難しい
- クロスコンパイルが煩雑
- 隠れた、失敗しないものとして扱われるメモリ割り当てが負担になる
- LLVMに縛られているため、Cほど多くのプラットフォームをサポートするには長い時間がかかるか、不可能なこともある
- ガバナンスも気になる点として残った
- Rust Foundationには複数の大企業のfoundation membersがいる
- 世界最大級の企業が毎年数十万ドルを提供すれば、Rustの開発方向に影響を与える可能性があると見ている
- オープンソースコミュニティでLLM生成コードを受け入れるプロジェクトが増えたことも衝撃だった
- 複数のプロジェクトでメンテナと利用者がLLM方針を書いたり要求したりしていた
- ZigはプロジェクトでLLMを完全に禁止していた
- Rustはアンケートを実施し、コミュニティ全体の雰囲気は反LLM寄りだったが、公式方針をすぐには作らなかった
- Rustの方針提案には、PRコメントで次の話題に言及できない条項が含まれていた
- LLMの長期的な社会的・経済的影響
- LLMの環境への影響
- LLM出力物の著作権上の地位
- LLM利用者に対する道徳的判断
- その条項は反発の後に削除されたが、そのような条項が存在したという事実だけでRustプロジェクトへの信頼は低下した
- 方針自体は主にLLMを制限し、slopを減らす内容なので妥当だと見ている
- この経験が、数年ぶりにZigを真剣に見直すきっかけになった
2026年のZig
- Zigは依然として不安定だ
- Webで見つけたZig 0.16.0の例で始めようとしたが、すでに古い例だった
- Zigで生産的に作業するには、標準ライブラリのソース一式を手元に置き、慣れておくのが最善だ
- Zig 0.17.0はまもなくリリース予定で、すべてのプロジェクトのビルドシステムを壊す予定だ
- メンテナたちは安定化へ移行しようとしており、このような破壊的変更はその過程の一部だ
- 幸い、言語そのものは2020年以降それほど大きく変わっていない
- たいていの直感は今でも通用した
- ライブラリの一部は作り直されていたが、コードは読みやすかった
- 現在のZigコードも6年後に見分けがつくだろうと考えている
- 今のZigにはパッケージマネージャがある
- 以前は依存関係の管理にgit submoduleを使っていた記憶がある
- 組み込みツールのほうがはるかに良い
- プロジェクトはgitとtarballで依存関係を定義できる
- ベンダリングも簡単に機能する
- エコシステムは依然として広大ではないが、そもそも広大なエコシステムはZigの目指すところでもない
- 公式パッケージレジストリはなく、別のNPMやcrates.ioも必要ないという立場だ
- 現在のZigは適切なバランスを実現していると評価している
メモリ安全性を見る考え方
- ZigはRustのようなメモリ安全性保証を提供しない
- これは単純さのためのトレードオフであり、Rustのアフィン型の複雑さは、安全性の利得に見合うほどの価値があるとは考えていない
- だからといってZigが安全性を放棄したわけではない
- Zig is safer than unsafe Rustという見方では、unsafe Rustを書かなければならない場面ではZigのほうがより良い選択かもしれない
- Zigでは言語をより安全にしようとする作業も進んでいる
- アプローチはunsafeコード領域ではなく、リリースモードに焦点を当てている
- 現在のZigのReleaseSafeモードは、assertion失敗時にクラッシュし、すべてのメモリを初期化する
- Andrew KelleyはReleaseSafeにFil-Cのようなものを含める方向に関心を持っている
- この方式は
unsafeを避けたRustのコンパイル時メモリ安全性を提供しないが、一部が言うようなdeath spiralではないと見ている - メモリ安全性はスペクトラムであり、あらゆる状況に最適な1つの方法はない
- Zigの方式は、ReleaseSafeをランタイムで可能な限り安全にし、テストとファジングで正しさを確認することだ
- 検査されないillegal behaviorはこの過程で見つけるべきであり、正しさが証明された後は、ほかのリリースモードのバイナリも安全に配布できると考えている
- この方式にはRustモデルと比べた欠点があるが、単純さを強く追求するZigの方向性において、厳密に劣っているとは見ていない
- コンパイル時メモリ安全性が、複雑な型システムや長いコンパイル時間というコストを払うだけ重要なら、Rustを選べばよい
- Zigのメモリ安全性モデルはassertionの哲学にもつながっている
- ReleaseFastでassertionを無効化する代わりに、テストを通じてassertionが正しく、その経路がunreachableであることを証明したと信頼する
- それによってZigはコードを最適化できる
- 関連する記事としてyour assertions are correctがある
今後の使い方
- 標準ライブラリとリリース変更履歴をそばに置きつつ、Zigでソフトウェアの問題に取り組む準備ができた
- 低レベルの詳細を扱いたくないときは、好みのスクリプト言語を使う予定だ
- 今後のソフトウェア開発ではZigを中核ツールにするつもりだ
- Zigにずっと留まり続けない可能性も開いている
- Rustの安定性や型システムが必要ならRustを使うこともできる
- Zigのアプローチに対する考えが完全に変わるかもしれない
- 複数の言語は共存できるし、共存すべきだ
- Zigは、ソフトウェア品質を無視せずに受け入れることでユーザーに集中するソフトウェア観を体現している
- 人々は信頼できて強力なソフトウェアを受け取るに値し、LLM時代には丁寧に作られたソフトウェアが希少になり、人々は質の下がるslopを受け入れるよう圧力をかけられていると見ている
3件のコメント
Zigを学習している途中で新バージョンが出るという話を見て、学習を諦めた経験があります。
安定版が出たらまた学習リストに入れてみてもよさそうですが、今のところは破壊的変更があまりに多くて、手を出すのが怖いですね。
Zig は言語仕様を変更するたびに頻繁に後方互換性を捨ててしまうので、これでは少なくとも 1.0 が出るまでは重要なシステムで使うのは難しいと思います。
Ghostty は std.IO の変更でかなり苦労しているように見えます。イシュー
他の言語の例で言えば、もし Java で
Futureが登場した後に JDBC API が Future や CompletableFuture を返す形に変わっていたら、確かに大きな進歩はあったでしょうが、その代償としてとてつもない混乱を生んでいたでしょう。Lobste.rs のコメント
いつか Zig をもう一度試してみたい
本当にやってみたいのだが、これまではほかのことで忙しかった
最後に Zig を触ったときは、約3時間で コンパイラエラーに遭遇し、かなり印象に残った。公平に言えば、そのバグはすでに最新ブランチでは修正済みだった
「LLVM に縛られているので、C ほど多くのプラットフォームをサポートするには非常に長い時間がかかるか、永遠に無理だろう」という話には疑問を感じる
LLVM がサポートしていないどのプラットフォームをターゲットに開発したいのか、その点で Zig がどう優れているのかが気になる
Zig が tier-4 の C コードを生成し、それを GCC が hppa、alpha、sh 向けにコンパイルできる、という話なのか聞いてみたい
問題は、Zig には LLVM 以外の公式バックエンドがあるが、Rust は LLVM を使っているという点である
ソフトウェアの再利用性を最大化しようとするシステム言語なら、可能な限り幅広く実行できるべきであり、Zig のように C を置き換える意図があるなら特にそうだと思う
ghostty の成功を見て、Zig が 1.0 に到達したら ゲーム開発に使ってみるつもり
ただ、自分が作るタイプのゲームにそこまでの性能が本当に必要なのかはよく分からない
「Zig は安全性を捨てたわけではなく、unsafe Rust より安全だ。どうせ unsafe Rust を使わなければならない状況なら、Zig のほうがよい場合がある」といった話はかなりよく見かけるが、見るたびによく理解できない
特に筆者が 安全性はスペクトラムだと認めていながら、局所的な unsafe 領域を使う代わりに、すべてがずっと unsafe な言語へ切り替えることを勧めている点が不思議だ
抽象機械を少し推論しやすくなる可能性はあるにしても、そのトレードオフには納得できない