# materialize とエラー 通常の評価では、制約や default を含む中間値が残ることがある。 外部へデータとして出力する段階では、materialize を行う。 ## materialize の責務 materialize は以下を行う。 - 必要なフィールドを評価する。 - 明示値がない abstract value に default を適用する。 - 採用された値が制約を満たすか検証する。 - default を持たない未解決の abstract value をエラーにする。 - 未適用の関数など、データとして出力できない値をエラーにする。 ## 例 ```dcdl MyConfig = { host = String; port = Int default 8080; }; ``` `MyConfig` を materialize すると、`host` は具体値も default もないためエラーになる。 `port` は `8080` が採用される。 ```dcdl Config = MyConfig & { host = "localhost"; }; ``` `Config` を materialize すると以下になる。 ```dcdl { host = "localhost"; port = 8080; } ``` ## default の適用 `default` は materialize 時にのみ fallback として採用される。 ```text Abstract { constraints: [Int] default: 8080 } ``` この abstract value を materialize すると、`8080` が採用され、`Int` を満たすか検証される。 明示値がある場合、default は採用しない。 明示値は concrete value として表現され、default を保持しない。 ```text Concrete(Int(9000)) ``` この値の最終値は `9000` である。 ## エラー分類 代表的なエラー: - 構文エラー - 未定義識別子 - 型不一致 - 制約違反 - `&` の conflict - `default` の conflict - 循環依存 - import 失敗 - match の非網羅による失敗 - materialize 不能な値の出力 ## match の失敗 `match` に fallback 分岐がなく、どの分岐にも一致しなかった場合はエラーになる。 ```dcdl match value { >= 10: "large"; } ``` `value` が `10` 未満であれば失敗する。 ## エラーは値ではない エラーは runtime value ではなく diagnostic として扱う。 通常の式はエラー内容に基づいて分岐できない。 汎用 `try / catch` は core には含めない。 fallback は `default`、`match`、および将来的な optional import / optional field access のような限定された仕組みで表現する。