Zero が投げかける問い
Zero の前提はシンプルです。AI エージェントが——人間だけでなく——コードを読み、書き、修復する時代において、言語 それ自体 はどうあるべきか。
既存の言語は、エージェントがコードを書けるようになるよりずっと前に設計されました。簡潔な構文、表現力のあるイディオム、ライブラリのクレバーさといった優先順位は、エディタにタイプする人間にとっては理にかなっています。これらの言語は曖昧さや暗黙の変換を許容します。人間は隙間を埋めるのが上手いからです。エージェントはそうではありません。確率分布から正確なテキストを生成するため、言語のあいまいな端のひとつひとつが、どこかで誤ったトークンとなって跳ね返ってきます。
Zero は、制約を裏返したところからやり直します。まずエージェントのために設計し、人間もコードを読み続けることを受け入れ、そこから何が落ちてくるかを見る、という発想です。
原則 1: 小さく規則的な表面積
ほとんどのプログラミング言語は時間とともに膨らんでいきます。リリースごとに小さな便利機能が追加され——新しい演算子、新しい構文、既存のことを別のやり方で書く方法——、それぞれが人間の書きやすさに見合うコストを支払います。一方で、それぞれの追加はエージェントにとってのコストでもあります。学ぶべきバリアントが増え、間違える余地が増えるのです。
Zero は表面積を意図的に小さく保ちます。
- バインディング形式は ひとつ(
let)。 - 関数形式は ひとつ(
fun、必要に応じてpub)。 - 現時点のループは ひとつ(
while)。 - 直積型をモデル化する方法は ひとつ(
shape)。 - ペイロード付き直和型をモデル化する方法は ひとつ(
choice)。 - ラベル付き直和をモデル化する方法は ひとつ(
enum)。 - パターンマッチの構文は ひとつ(
match)。
演算子オーバーロードなし、デコレーターなし、マクロなし、暗黙の変換なし、真偽値強制なし、三項演算子なし。これらの「ない」ことは、それぞれが機能です。エージェントが間違ったバリアントを選びうる場所をひとつずつ取り除いています。
コストはわかりやすく、利便性機能が少ないこと。利点は、セッション中に Zero を学ぶエージェントが、ほぼ同等の 7 つの選択肢を比較せずに、正しい構文へ収束できることです。
原則 2: 明示的なエフェクト
ほとんどの言語では、どの関数からでもどこでも I/O ができます。JavaScript の console.log、C の printf、Python の print。関数のシグネチャからは、その関数がファイルへの書き込みやネットワークアクセスをするかどうかが読み取れません。それを知るには、本文を再帰的に読むしかありません。
Zero は逆の立場を取ります。関数が持つすべてのエフェクトは、シグネチャに現れます。
- I/O は
Worldケイパビリティ によってゲートされます。Worldを取らない関数は I/O できません——型システムがそれを強制します。 - 失敗は
raisesとcheckによってゲートされます。失敗しうる関数はその旨をシグネチャに書きます。呼び出し側はcheckなどの明示的な構文で認識します。
関数のシグネチャだけから、エージェント(あるいは静的解析器、あるいは人間のレビュワー)が深く気にする 2 つの質問に答えられます。
- 「これは外の世界に触れる可能性があるか?」——
Worldが現れる場合のみ「はい」。 - 「これは失敗する可能性があるか?」——
raisesが現れる場合のみ「はい」。
この性質はメインストリーム言語には存在せず、決して小さくない性質です。
コストはパラメータの引き回しです。I/O が必要な場所には World 値が回り、エラーが流れる場所には raises 句が繰り返されます。Zero はそれをこの性質の対価として受け入れています。
原則 3: 決定論的なツール
3 つ目の原則は、最も直接的にエージェントを意識したものです。コンパイラーが出力するものはすべて構造化データである、というものです。
JSON 診断 がその代表例です。
{
"code": "NAM003",
"message": "unknown identifier",
"line": 3,
"repair": { "id": "declare-missing-symbol" }
}
通常のコンパイラーエラーと違う点が 3 つあります。
- 安定したコード。
NAM003は今日も明日も同じ意味です。人間向けのメッセージの言い回しが変わっても変わりません。 - 構造化された修復プラン。 コンパイラーが診断を修正する方法を知っていると考えるとき、それを英語の提案ではなく、編集リストというデータで出力します。
- 複数の構造化チャネル。 診断、依存グラフ、サイズレポート、説明はすべて
--jsonモード越しに利用できます。
要点は、ツール——エージェントであれそれ以外であれ——がコンパイラー出力に作用するために英語をパースする必要がない、ということです。安定したコードの参照は厳密ですが、散文のパースはあいまいです。Zero は前者をコントラクトとして、後者を人間向けの便利機能として扱います。
原則 4: 言語の中に住むライブラリ
エージェントは、既存のパターンに従ってコードを書くのが得意です。一方で、多数の選択肢の中から適切な外部依存を選び、正しく統合し、API のドリフトを追いかけるのは苦手です。外部依存はすべて摩擦です。
Zero の設計は、能力を標準ライブラリに押し込めます——明示的にドキュメント化され、一貫性があり、言語の安定化に合わせて安定していく、という方針です。狙いは、Zero プログラムが日常的な作業のために標準配布の外へ手を伸ばす必要があまりない、という状態です。それによって、エージェントが推論すべき表面積を有界に保ちます。
これは現時点では到達点ではなく目標です。pre-1.0 の標準ライブラリは実在しますが、まだ拡張中です。原則は方向であり、目的地ではありません。
Zero が引き換えにすること
すべての設計判断は何かを犠牲にします。Zero がしている率直なトレードオフは次の通りです。
- 簡潔さよりも冗長さ。 純粋関数は
Worldを必要としません。I/O を行う関数は必要とします。エラーはシグネチャに現れます。結果として、JavaScript や Python の同等コードよりも注釈が多くなります。 - 魔法より明示。 反射的なメタプログラミング、振る舞いを静かにラップするデコレーター、暗黙のグローバルはありません。動的言語で「ただ動く」ように見えるものは、手で配線する必要があります。
- 動的より静的。 パラメータ、戻り値、シェイプフィールドには型が必須です。コンパイラーが多くの仕事をする代わりに、書き手(あるいはジェネレーター)がすべてのシグネチャを書くことになります。
- 変化速度より安定性。 言語は pre-1.0 で速く動いていますが、設計意図 としては、表面が落ち着いたらロックダウンする方針です。後からクレバーな新機能を追加するハードルが上がるのが代償です。追加の基準は「これがエージェントに与える助けは、エージェントに課すコストを上回るか?」になります。
このトレードが見合うかどうかは、何を最適化しているかによります。人間が単発のスクリプトを書くなら、摩擦は実在し、エージェントのメリットは抽象的に感じられるでしょう。1 日に数千の小さなプログラムを生成するエージェントを運用しているなら、その摩擦は何倍にもなって返ってきます。
Zero が目指していないこと
明示しておくべき否定的主張がいくつかあります。
- 「すべてのプログラミングの未来」ではない。 Zero は仮説であってマニフェストではありません。仮説は「エージェント・ファーストな制約は有用な言語を生む」というもの。メインストリーム言語がそれらの制約を採用すべきかは別の、もっと長い議論です。
- Vercel のデプロイ機能ではない。 Vercel Labs 発ではありますが、Zero は Next.js や Vercel ホスティングと結びついていません。独立したシステム言語です。
- 本番環境で Rust・Go・Zig の代わりにはならない。 pre-1.0 で実験的です。学習やフィードバックのために使い、顧客向けソフトウェアの出荷には使わないでください。
- 完成していない。 標準ライブラリの一部、可変性の構文、エラーハンドリング、ジェネリクスの制約は、1.0 までに動く可能性があります。
たとえ使わなくても興味深い理由
たとえ一度も Zero を書かなかったとしても、この実験には学ぶことがあります。
- 小さなシステム言語の中で、現実に動くケイパビリティベースのエフェクトシステムを示した最も明確な例です。「権限を渡せばエフェクトがシグネチャに現れる」というメンタルモデルは移植可能です。
- 診断の発想は、ここ 10 年すべてのコンパイラーが行うべきだったことです。構造化された出力は散文に毎回勝りますし、Zero の安定したコードへのコミットは、言語を変えずに他のツールも採用できる発想です。
- 「同じことを行う方法はひとつ、意図的に小さな表面積」という原則は、通常の言語設計の流儀に逆らうものです。この原則がどこで効き、どこで窮屈になるかを観察することは、明日どの言語を書いているとしても役立ちます。
次にどこを読むか
ここまでの一連のドキュメントを読み終えたなら、次に役立つのは外部の情報源です。
github.com/vercel-labs/zeroの Zero リポジトリ——サンプル、ソース、メンテナー自身の意図を述べたAGENTS.mdがあります。- 公式サイト
zerolang.ai——入門手順と公式の紹介。
どちらも進化中です。そこで見つかる情報は、サードパーティのチュートリアルよりも最新です。このドキュメントの原則は遅く動く部分で、その周辺の構文は言語が落ち着くまで動いていきます。
よくある質問
「エージェント・ファーストなプログラミング言語」とは?
人間だけでなく AI エージェントを、最初から言語の主要ユーザーとして扱う、という意味です。構文を機械的にパースできること、正しいプログラムを生成できること、エラー出力をデータとして読み取れること、修正を決定論的に適用できること——こうしたエージェントのニーズが、人間にとっての読みやすさや書きやすさと並んで、設計判断を駆動します。
既存の言語ではエージェントに合わないのですか?
既存の言語は人間向けに設計されています。文法にはショートカット、暗黙の変換、曖昧な構文が含まれていて、人間は許容できてもコードジェネレーターは詰まりがちです。コンパイラーは散文を出力し、データを返しません。エフェクトシステムも暗黙です。これらは致命的ではありません——エージェントは回避できます——が、初めからエージェント向けに設計された言語は、その摩擦を取り繕う代わりに最初から消してしまいます。
Zero の設計の中心原則は?
小さく規則的な文法(同じことを行う方法はひとつ)、World ケイパビリティによる明示的なエフェクト(アンビエントな I/O なし)、raises/check による明示的な失敗(隠れた制御フローなし)、決定論的なツール(安定したコードと修復プランを備えた構造化データとしてのコンパイラー出力)。これらの原則は互いに重なり合い、それぞれが他の原則をエージェントにとってより有用にします。
エージェント・ファーストにすることで、Zero が手放すものは?
簡潔さとアンビエントな便利さです。暗黙の真偽値解釈もなく、グローバルな print もなく、コールスタックを静かに巻き戻す try/catch もありません。関数はパラメータが多めになり、シグネチャに付ける注釈も増えます。その代わり、関数が 何をするか——失敗の可能性も含めて——をシグネチャだけで読み取れるようになります。
Zero は人間が書く言語に取って代わるのですか?
いいえ、それは目的ではありません。Zero は「エージェント・ファーストな設計はどう見えるか」を試す実験であり、他の言語がすべての選択を採用すべきだと主張しているわけではありません。興味深いのは実験から何が学べるか——どの制約がエージェントに最も役立つか、人間はどのトレードオフを許容できるか、そしてどのアイデアが時間をかけてメインストリーム言語に逆流していくか——です。