59 lines
1.5 KiB
Markdown
59 lines
1.5 KiB
Markdown
# 関数
|
|
|
|
関数は構造を受け取り、構造を返す式として扱う。
|
|
|
|
## 構文
|
|
|
|
```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<Param>
|
|
body: ExprId
|
|
env: EnvRef
|
|
}
|
|
```
|