dowel

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節。