以下の内容はhttps://gfx.hatenablog.com/entry/2026/01/23/212644より取得しました。


個人で静的型付け言語のコンパイラをフルスクラッチで作れる時代が来た!

今年に入ってからふと思いつきで新しいプログラミング言語 "Wado" (ワドゥ)を設計しつつagentic codingで実装したところ、なんと3週間ほどで基礎的なところができちゃいました。実装的にはまだ本当に基礎的なところで、B-Tree Mapを実装できる程度です*1

github.com

このWadoは、2026年1月3日にinitial commitが行われました。それから一ヶ月も経っていない今、静的型付け、ジェネリクス、トレイトおよびトレイトによる演算子オーバーローディング、クロージャ、モジュールシステム、shebangによるペライチスクリプトの実行、そして実用的なパフォーマンスを備えた処理系が動いています。

開発者は私一人です。スタートアップでVP of Technologyとして働きながら、二人の子供(mfxとrfx)を育てる傍らでの開発です。コードの100%以上はコーディングエージェントが書きました。100%以上というのはつまり、私が時々コメントやdead codeを消すので、正味105%くらいがagentic codingだろうという意味です。

我ながら驚きますが、これは誇張でも冗談でもありません。2026年、ソフトウェアエンジニアが片手間でプログラミング言語を設計し、コンパイラまで完成させられる時代が本当に来たのです。

Agentic Coding革命が突きつけた問い

半年前、私は「Agentic coding革命が "成った" 世界で……」というブログを書きました。AIによるagentic codingが、「革命」と呼べるくらいの、不可逆的で激しい変化をもたらしていることを記録したものです。この頃は、この「革命」をすごいと思う気持ちと、戸惑う気持ちが半々くらいでした。

そして今、Wadoの開発を通じて実感しています。この革命は、プログラミング言語に求められる性質をも変えつつあります。

パフォーマンスの重要性

最も重要のなのは、実行速度かもしれません。agentic codingで同じ開発時間を使うなら、実行時性能の差は決定的な選択要因になります。もしある言語が別の言語より10倍以上遅いとしたら、遅い方を選ぶ理由はありません。

Wadoのベンチマーク結果を見てください(x86_64, wado -O2 + wasmtime v40):

整数演算ベンチマーク(素数カウント)

  • C (gcc -O3): 3,450ms
  • Wado (wado -O2 + wasmtime): 3,717ms(Cの1.08倍)
  • JavaScript (Node.js): 4,319ms(Cの1.25倍)
  • Ruby: 65,847ms(Cの19.1倍)
  • Python: 81,775ms(Cの23.7倍)

浮動小数点演算ベンチマーク(マンデルブロ集合の計算)

  • C (gcc -O3): 150ms
  • JavaScript (Node.js): 179ms(Cの1.19倍)
  • Wado (wado -O2 + wasmtime): 185ms(Cの1.23倍)
  • Python: 4,351ms(Cの29.0倍)
  • Ruby: 5,994ms(Cの40.0倍)

ペライチファイルをwado run hello.wadoで実行できるスクリプト言語として、この性能は破格です。Pythonより20〜30倍速く、ネイティブコードに迫る速度で動作します*2

明示性と予測可能性こそが生命線

さて、Wadoの設計原則においてひとつ重要なことは、「明示性」です。ソースコードを読んだ時に情報量が多いことは、もともと人間にとっても重要でしたが、agentic coding時代においてはさらに重要です。 「ほかのファイルを参照しなければならない」「コード上に現れない暗黙のコスト」これらはcoding agentにとって扱いにくい性質かもしれません。強い静的型付け、明示的なエラーハンドリング、大域脱出をする例外がないこと。これらは、agentic codingの質を安定させると感じています。

coding agentが過剰なまでにtry-catchを書いたり、いちいちアトリビュートの存在チェックやnullチェックをするコードに辟易した経験はありますよね?静的型付けと明示的なnull、大域脱出、そしてanyのような脱出ハッチが「そもそも用意されていない」ことは、品質の安定化に直結すると考えています。

Wadoは強い静的型付けで、nullは Option<T> で表現します。エラーハンドリングは全てResult<T, E>で行います。大域脱出例外はありません。そしてマクロもありません。coding agentがよくやる典型的な防衛的コードを書けないように設計されています。

学習可能性

「新しい言語は事前学習されていないので、coding agentにとって使いづらいのでは?」と思われるかもしれません。しかし、cheatsheet程度のペライチのドキュメントとわかりやすいエラーメッセージがあれば、coding agentは新しいプログラミング言語を普通に使いこなせます。いま大量のE2Eテストコードがありますが、それはほとんどすべてがcoding agentが書いたものです。B-Tree Mapやエラトステネスの篩などのアルゴリズムも特に問題なく書けます。まあ、他の言語にある構文がWadoにもあると思い込んで書いてエラーになることはあるようですが…。

Wadoは、主に既存の言語(特にRustとTypeScript)の構文の部分を組み合わせつつ、独自の構文は最小限にしています。十分に学習コストの低い言語であれば、新しい言語でもcoding agentは問題なく使いこなせます。

なぜWadoを作ったのか

プログラミング言語への思い入れ

少し個人的な話をさせてください。

私はもともと、Perlが母語と言っていいくらい精通しています。Perlの"better shell+sed+awk, easier C"という設計背景は今でも好きですし、"Easy things should be easy and hard things should be possible"というLarry Wallの設計哲学は私の座右の銘で、私が管理しているOSSにはこの一文を載せていることも少なくありません。「プログラマの三大美徳」も、私のソフトウェアエンジニアとしての価値観に強い影響を与えています。まあ、TMTOWTDI (There's more than one way to do it) は今の時代ちょっと違うかなと思っていますが…。

一方で、CやC++やJavaを使う中で静的型付け言語に傾倒してゆき、今はRustやTypeScriptがお気に入りの言語です。しかし、それぞれに欠点があります。

Rust: 素晴らしい言語です!Wadoコンパイラの実装言語でもあります。しかし、ライフタイムとそれに伴う世界で一番複雑な型システム、そしてマクロ。結果として、コンパイルの遅さは開発効率に無視できない悪影響を与えています。cfg/featuresによる複雑なコンパイル条件分岐も、コードリーディングを難しくしています。

TypeScript: 素晴らしい言語です!『JavaScriptプログラマーのためのTypeScript厳選ガイド』という単著も書いている程度には好きで、よく知っている言語です。しかし、JavaScriptのレガシーを引きずっていて意味不明な仕様がたくさんありますし、主にJS由来の使うべきでない機能が多すぎてlint configのメンテに時間が吸われます。そして、これまた複雑すぎる型システム(まあ好きではあるんですけど)のわりに、ランタイムに型がないことによって安定したソフトウェア開発が少し難しいです。

Wadoは、これらの言語の良い部分を学びつつ、agentic coding時代に最適化された新しい選択肢を目指しています。

直接のきっかけ:AssemblyScript

Wado開発の直接のきっかけは、ちょっとしたつまづきでした。あるソフトウェアの一部をWasmで実装したくなり、当然AssemblyScriptに行き着きました。ASはWasm実装の言語としてかなり良いです。しかし、いくつかの点で不満がありました。

Wasm初期の設計を引きずっていること。TypeScript/JavaScriptのレガシーを引きずっていること。構文がWasmと親和性が高くないこと。さらに、最近は開発も停滞しています。

であれば、2026年に相応しい「Wasmが透けて見える」言語を作ってみようと、思い立ちました。

タイミングの幸運:2026年という時期

まさに今は絶好のタイミングです。

Wasm Component ModelとWASI P3(Preview 3)の仕様が固まってきたことで、これらを前提とすることで実装や意思決定が大幅に簡略化できました。wasmtime使うとネイティブの80〜90%程度の速度で動作するとされています。Wasm GCを活用することで、メモリ管理ルーチンをバンドルする必要がなくなり、wasmのサイズも削減できます。

1年前だったら、この判断はできませんでした。1年後だったら、もう普通でした。2026年1月という、まさにこのタイミングは、Wasmを中心とした新しい言語を設計するのに最高に面白いタイミングでした。

Wasm GC: 性能とシンプルさのトレードオフ

Wasm GCの採用は、pros/consがあります。GCのオーバーヘッドは確実にあります。しかし、「Wasmが透けて見える軽量な言語」という観点からは、Wasm GCの活用は重要な選択でした。

ライフタイム管理がないことで、言語仕様がシンプルになります。wasmサイズが削減できます。そして何より、agentic codingとの相性が良いのです。

実際のwasmバイナリサイズを見てください(wadoのリポジトリで make report-wasm-size の現在の出力です):

Hello World(最小プログラム):

Program Language Size (bytes)
hello_world wado 1090
hello_world c 2122
hello_world zig 4449
hello_world assemblyscript 6913
hello_world moonbit 22884
hello_world rust 42587
hello_world tinygo 161350

PI近似計算(浮動小数点演算):

Program Language Size (bytes)
pi_approx zig 10608
pi_approx assemblyscript 11372
pi_approx wado 11786
pi_approx c 14151
pi_approx moonbit 32940
pi_approx rust 62952
pi_approx tinygo 186022

ちなみに浮動小数点数演算がバイナリの量を大幅に増やすのは、浮動小数点数の文字列化のためのコードがとても大きいからです。WadoはいまryuというRustライブラリをwasm化したものをバンドルして使っていますが、これをWado自身で実装することで最適化によるコード削減が可能となり、AssemblyScriptより少し小さくなるのではないかと予測しています。

設計と開発のスピード

構文についてのディスカッションをcoding agentとすることで、一人で思索にふけるよりずっと効率的に設計ができました。ディスカッションの結果はとしてドキュメントとしてリポジトリに残し、後から参照できるようにしています。

構文の試行錯誤は、驚くほど簡単です。「こういう構文を実装したい」と思ってから、1時間もするとできあがります。構文の変更も、同様に簡単です。まあ、最適化ロジックの実装やセマンティクスの変更はもっと時間がかかりますが、実際のところ、構文の変更はセマンティクスの変更や新機能の追加よりずっと簡単なのです!

何もかもがありえないスピードで開発が進む。これが、agentic coding時代の現実です。

Wadoの特徴

さて、これらの背景を踏まえて、Wadoの特徴をまとめます。

Rust + TypeScriptのハイブリッド構文

  • Rust風の構文
  • ES modules風のimport構文や豊富なリテラル
  • TypeScript風のリテラル型…は、あったらいいなと思うものの、未実装

Wasm CM / WASI P3専用

  • ネイティブに匹敵する性能(上記ベンチマーク参照)
  • UB(未定義動作)なし
  • Component ModelとWASI P3を前提とした言語仕様と標準ライブラリ
  • Wasm CMと相互運用可能な型をビルトインとして提供
    • variant(Rustのenum的なデータ型)
    • enum(ペイロードのない列挙型、未実装)
    • flag(ビットフィールド、未実装)
    • Option
    • Result
    • Future(未実装)
    • Stream(未実装)

Wasm GC活用

  • Rustのライフタイム管理や借用はなし
  • 参照のGCによる自動管理
  • Wasmサイズの削減

強い静的型付け

  • ジェネリクスあり(monomorphization)
  • 型推論
  • タプル

値のセマンティクス

  • 配列、文字列、構造体などはすべて値のセマンティクスで、代入はコピー
  • リファレンス(&T)と変更可能なリファレンス(&mut T)あり
  • ムーブの挙動は考え中

明示的エラーハンドリング

  • 大域脱出例外なし
  • Result<T, E>によるエラー処理
  • panic()unreachable() はWadoレベルではキャッチ不可

シンプルで予測しやすい構文

  • マクロなし
  • Rust & TypeScript からの良い部分の組み合わせ
  • エフェクトシステムにより、関数シグネチャの情報量を増加

Coding Agent Friendly

最初からcoding agent friendlyなツールチェインを意識して作っています。

wado dumpコマンドは、コンパイラの内部状態を詳細に確認できます:

wado dump file.wado                           # 全フェーズを表示
wado dump --ast file.wado                     # AST構造を表示
wado dump --ast --unparse file.wado           # ASTをWadoソースコードとして表示
wado dump --tir file.wado                     # 型付きIRを表示
wado dump --tir --unparse file.wado.          # TIRを疑似ソースコードとして表示
wado dump --optimize file.wado                # 最適化後のフェーズを表示
wado dump --optimize --unparse -O2 file.wado  # 最適化後のTIRをソースコード化(擬似Wadoコード)

coding agentは、このツールを驚くほど効果的に使っています。問題を診断し、修正し、検証する。この一連のフローを正しく実行してコンパイラの開発をしています。

Wadoの開発を通じて

私はプログラミングが好きです。プログラミング言語が好きです。しかし、プログラミング言語の設計と実装は「あくまでも空想として楽しむ」だけだと思っていました。それが今や、形になりつつあります。それも、ただの「おもちゃ」を超えた性能と実用性を備えたものとして。

人間が手で書くコードの量は減りつつありますし、現に私自身、Wadoのコードはほとんど書いていませんし、コンパイラのコードに至っては1行も書いていません。

それでも、コードを読む作業は必要です。Wadoのコードを大量に読みますし、Rustで書かれたコンパイラのコードもまだまだ読む必要があります(この時代のcoding agentは、よく途方もなく酷い品質のコードを書きます)。つまり「読みやすく、速い」プログラミング言語は今後も必要です。その要求があるかぎり、これからも多くのプログラミング言語が作られるに違いありませんし、個人がagentic codingで新しい言語と言語処理系を作り、それが世界に受け入れられることもあるかもしれません。

AIの功罪についてはまだまだ議論が続くと思いますが、少なくともcoding agentは私にとって一生遊べるおもちゃのような楽しみを生み出す装置になりました。

参考

*1:TreeMapかHashMapがひとつのマイルストーンだろうと思って実装していたので、それ以外のことはまだまだ全然できません

*2:JavaScriptもまたこのベンチマークではネイティブコードに匹敵しますが、JavaScriptの最適化器はシンプルな計算はネイティブコードに匹敵する性能を出しますが、実際のアプリケーションにおけるパフォーマンスがCとは比較にならないほど遅いことはよく知られています。




以上の内容はhttps://gfx.hatenablog.com/entry/2026/01/23/212644より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14