Refocus manual on public language usage
This commit is contained in:
@@ -1,51 +1,35 @@
|
||||
# 遅延評価
|
||||
|
||||
この言語はフィールド単位で遅延評価する。
|
||||
Decodal は値を必要になった時点で評価する。
|
||||
|
||||
## 基本方針
|
||||
## 遅延評価される値
|
||||
|
||||
次の値は参照または materialize されるまで評価されない。
|
||||
|
||||
- module の root と top-level field
|
||||
- object field
|
||||
- `let` binding
|
||||
- function argument
|
||||
- `default` expression
|
||||
- import 先の値
|
||||
|
||||
同じ binding を複数回参照した場合、その評価結果は再利用される。
|
||||
このため、未参照の field や function argument にある失敗は、値が必要になるまで発生しない。
|
||||
|
||||
```dcdl
|
||||
{
|
||||
schema = {
|
||||
hoge = String;
|
||||
};
|
||||
|
||||
result = expensive(schema);
|
||||
}
|
||||
let
|
||||
safe = 42;
|
||||
unused = missing_name;
|
||||
in
|
||||
safe
|
||||
```
|
||||
|
||||
`schema` のみが必要な場合、`result` は評価されない。
|
||||
|
||||
## thunk
|
||||
|
||||
各フィールドや let 束縛は thunk として保持できる。
|
||||
|
||||
```text
|
||||
Thunk {
|
||||
expr: ExprId
|
||||
env: EnvRef
|
||||
state: Unevaluated | Evaluating | Evaluated(Value) | Error
|
||||
}
|
||||
```
|
||||
|
||||
評価済み thunk は memoize する。
|
||||
同じフィールドを複数回参照しても、評価は一度だけでよい。
|
||||
|
||||
## 評価状態
|
||||
|
||||
thunk は以下の状態を持つ。
|
||||
|
||||
```text
|
||||
Unevaluated 未評価
|
||||
Evaluating 評価中
|
||||
Evaluated 評価済み
|
||||
Error 評価失敗
|
||||
```
|
||||
|
||||
`Evaluating` の thunk を再度評価しようとした場合、循環依存として扱う。
|
||||
この式は `unused` を参照しないため `42` になる。
|
||||
|
||||
## 循環検出
|
||||
|
||||
評価中の値が自身へ再び依存した場合は cycle diagnostic になる。
|
||||
|
||||
```dcdl
|
||||
{
|
||||
a = b + 1;
|
||||
@@ -53,26 +37,12 @@ Error 評価失敗
|
||||
}
|
||||
```
|
||||
|
||||
この場合、`a` または `b` を評価すると循環エラーになる。
|
||||
module や import の参照関係自体が循環していても、実際に評価される field の依存関係が循環していなければ評価できる。
|
||||
|
||||
一方、同じモジュール内または import 間に循環があっても、評価対象のフィールドが循環していなければ成功する。
|
||||
## 評価と materialize
|
||||
|
||||
## 評価と materialize の分離
|
||||
通常の評価結果には、constraint、`Unknown`、`default`、function などの abstract value が残り得る。
|
||||
外部へ concrete data として取り出すときに materialize を行う。
|
||||
|
||||
通常の評価では、制約や default を含む中間値が残ることがある。
|
||||
外部へデータとして出力する段階で materialize を行う。
|
||||
|
||||
この分離により、以下が可能になる。
|
||||
|
||||
- スキーマを値として扱う。
|
||||
- default を必要になるまで評価しない。
|
||||
- import されたモジュールの未使用フィールドを評価しない。
|
||||
- 制約だけのフィールドを中間状態として保持する。
|
||||
|
||||
## 関数呼び出しとの関係
|
||||
|
||||
関数引数は thunk として渡せる。
|
||||
関数本体内で引数が参照されたときに評価する。
|
||||
|
||||
関数呼び出し結果そのものはグローバルには memoize しない。
|
||||
ただし、フィールドに束縛された呼び出し結果は、そのフィールド thunk の評価結果として memoize される。
|
||||
この分離により、schema を値として合成し、必要な field だけを評価し、`default` の選択を出力時まで遅らせられる。
|
||||
詳細は [materialize とエラー](./materialization-and-errors.md) を参照する。
|
||||
|
||||
Reference in New Issue
Block a user