TL;DR

式の値が必要になるまで評価を遅らせる評価戦略。必要呼び(call-by-need)とも呼ぶ。一度計算した結果は保存し、同じ計算を繰り返さない。反対は正格評価(eager evaluation)で、多くのプログラミング言語は正格評価を使う。

なぜ必要か

Wikipedia によると、遅延評価には次の利点がある。if-then-else や短絡評価の演算子のような制御構造を、組み込みではなく普通の関数として定義できる。フィボナッチ数列のような無限のデータ構造を定義し、実際に要求された要素だけを計算できる。使われない要素がエラーを含んでいても、アクセスしなければ問題にならない。

仕組み

正格評価では、関数を実行する前に引数を評価する。遅延評価では、値が必要になった時点で初めて評価し、結果をキャッシュして再利用する。コンパイラは正格性解析により、必ず必要になる値を見つけて先に評価できる。

例

Haskell は既定で関数の引数の評価を遅らせる。他の言語では、サンク、Scheme の delay と force、OCaml の lazy のような明示的な仕組みで遅延評価を取り入れる。

注意点

評価の順序が予測しにくくなるので、例外処理や入出力のような命令的な機能と組み合わせにくい。評価されていない式がたまると、メモリリークの原因にもなる。理論上は正格評価より少ない手順で済むが、実際には遅くなることがある。

関連

出典