ADR-0004: 記述構文は TOML 風方言とし、意味論が同じ要素は既存言語から借用する
状態: Accepted
文脈
dowel.build の構文を、独自 DSL / Rust 風 / TOML 風のいずれにするか。
独自構文は認知負荷の懸念があり、既存言語への擬態は誤った期待を生む懸念がある。
決定
基本構造を TOML とし、値の位置にのみ限定的な式を許す。
意味論が既存言語と一致する要素(match、コメント記法など)は、その記法を借用する。
根拠
馴染みには2つの層がある
- 表層の親近性 — 見た目が既知の言語に似ている。学習開始時のとっつきやすさ
- 意味論の予測可能性 — 見た目から挙動が正しく推測できる
擬態は前者を上げるが、後者を下げる場合がある。Starlark は Python に似せた結果、 Starlark が持たない Python 機能を試して失敗する報告が繰り返し出ている。
Rust 風を採らない理由
match は自然に嵌まるが、ターゲット宣言という中心的な構文に Rust の対応物が存在しない。
候補(関数呼び出し / 属性つき定数 / 疑似的な項目宣言)はいずれも冗長・迂遠・
Rust に存在しない構文のいずれかとなり、認知負荷低減という目的を達しない。
TOML 風を採る理由
dowel.tomlを既に読む利用者にとって、最も馴染みのある参照点が TOML である- ADR-0003 で分離を選んだことにより、 2ファイル間で表層構文が共通になるという副産物が得られる
認知負荷の主因は構文ではない
実際につまずくのは意味論である。PRIVATE と INTERFACE の使い分け、
なぜこのフラグが伝播するのか、変数のスコープはどこまでか。
CMake の難解さも if() の構文ではなく、文字列型・二重スコープ・遅延評価の混在に由来する。
構文の親近性が下げるのは初日の負荷であり、意味論の明快さが下げるのは以後ずっとの負荷である。 型・診断・来歴への投資が正しい重点となる。
借用するもの / しないもの
借用する:
match ... { A => x, B => y }— 網羅的分岐///* */#コメント、生文字列
借用しない:
letによる束縛(可変状態や再代入の期待を生む)- 型注釈の構文(型は宣言側スキーマにあり、記述側には現れない)
- モジュール構文(ファイル構造で決まる)
帰結
- 式は純粋かつ全域。副作用なし、束縛なし、反復は内包表記のみ、再帰なし。 これにより停止性を言語仕様として保証し、言語サーバが常に応答することを担保する
dowel.buildは TOML に見えて TOML ではないため、既存 TOML ツールが値の位置で失敗する。 拡張子を.tomlにせず、診断で明示し、補完・強調は自前の言語サーバで提供するwhenは Rust に対応物がないため独自。後置とすることで配列要素とキーの双方に一様に付く
LLM 支援に関する注記
「LLM があるから馴染みのない構文でよい」は成立しない。 LLM は訓練コーパスの分布から生成するため、公開コーパスのない新規構文は最も苦手な領域にあたる。
LLM が強いのは修復ループであり、この事実は構文の自由度ではなく 診断品質への投資を正当化する。詳細は 30-devexp.md 4節。