# モジュールと import `import` は外部ファイルを読み込み、そのファイルの評価結果を返す。 ## 構文 ```dcdl import ./config.n import "./config.n" ``` パス表記の詳細は未確定である。 パスリテラルと文字列リテラルの両方を許可するか、どちらかに統一するかは今後決める。 ## モジュール import 先はモジュール単位で読み込まれる。 ただし、モジュール全体を即時評価する必要はない。 各フィールドは thunk として保持され、必要になったときだけ評価される。 ## 循環 import モジュール間に循環参照があっても、必要なフィールドの依存関係が循環していなければ評価できる。 例: ```dcdl # main.n { schema = { hoge = String; }; result = (import ./func.n)(schema); } ``` ```dcdl # func.n (input: (import ./main.n).schema) => { # ... } ``` `func.n` は `main.n` を import しているが、参照しているのは `main.schema` である。 `main.schema` が `main.result` に依存していなければ、この循環 import は成立する。 ## import の評価単位 実装上は、以下の単位で管理するのが自然である。 ```text Module main schema -> thunk result -> thunk Module func root -> thunk ``` 各 thunk は一度だけ評価して memoize する。 評価中に同じ thunk へ戻った場合は循環依存としてエラーにする。 ## import 失敗 以下は import 失敗として扱う。 - ファイルが存在しない。 - ファイルが読めない。 - import 先の構文解析に失敗する。 - import 先の評価で必要な値がエラーになる。 - 実装が禁止する import 循環に該当する。