# 関数 関数は構造を受け取り、構造を返す式として扱う。 ## 構文 ```dcdl (value: Int) => value + 1 ``` 関数呼び出しは通常の呼び出し構文で行う。 ```dcdl let increment = (value: Int) => value + 1; in increment(41) ``` 複数引数も指定できる。 ```dcdl (input_a: { hoge = Int & >= 0; }, input_b: { fuga = Int; }) => { hoge = input_a.hoge; fuga = input_b.fuga; } ``` ## 関数の意味 関数は runtime value として扱えるが、最終データとして materialize することはできない。 未適用の関数値が materialize 対象に残っている場合は diagnostic になる。 関数値は opaque であり、関数値同士の等価性は提供しない。 `&` で関数値同士を合成すると conflict になる。 ## 評価方針 関数は以下の方針で評価する。 - 関数は純粋である。 - 関数はレキシカルスコープを持つ。 - 関数は定義時の環境を参照として保持する。 - 引数は thunk として渡され、必要になるまで評価されない。 - 関数呼び出し結果そのものはグローバルには memoize しない。 - フィールドに束縛された関数呼び出し結果は、そのフィールド thunk の評価結果として memoize される。 - 再帰的な依存は thunk cycle として diagnostic になる。 関数値の内部モデル例: ```text Function { params: Vec body: ExprId env: EnvRef } ```