Decodal/doc/manual/souce/language/functions.md

1.5 KiB

関数

関数は構造を受け取り、構造を返す式として扱う。

構文

(value: Int) => value + 1

関数呼び出しは通常の呼び出し構文で行う。

let
    increment = (value: Int) => value + 1;
in
    increment(41)

複数引数も指定できる。

(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 になる。

関数値の内部モデル例:

Function {
  params: Vec<Param>
  body: ExprId
  env: EnvRef
}