惰性計算

專業術語

惰性計算,專業術語,作名詞,又稱懶惰計算、懶漢計算,是一個計算機編程中的一個概念,它的目的是要最小化計算機要做的工作。

簡介


它有兩個相關而又有區別的含意,可以表示為“延遲計算”和“短路求值”,本條目專註前者,後者請參見短路求值條目。除可以得到性能的提升外,惰性計算的最重要的好處是它可以構造一個無限的數據類型。
惰性計算的相反是熱情計算,也叫做 嚴格計算。這是一個大多數編程語言所擁有的普通計算方式。

延遲求值


延遲求值特別用於函數式編程語言中。在使用延遲求值的時候,表達式不在它被綁定到變數之後就立即求值,而是在該值被取用的時候求值,也就是說,語句如x:=expression; (把一個表達式的結果賦值給一個變數)明顯的調用這個表達式被計算並把結果放置到x 中,但是先不管實際在x 中的是什麼,直到通過後面的表達式中到x 的引用而有了對它的值的需求的時候,而後面表達式自身的求值也可以被延遲,最終為了生成讓外界看到的某個符號而計算這個快速增長的依賴樹。
某些編程語言預設延遲表達式的求值,另一些提供函數或特殊語法來延遲求值。在 MirandaHaskell 中,預設延遲函數實際參數的求值。在很多其他語言中,可以使用特殊語法明確懸置計算來延遲求值(比如 Scheme 的 "delay" 或 "force"),更一般的通過把一個表達式包裝在 thunk 中。表示這種明確延遲求值的對象叫做預期或承諾。
延遲求值的一個好處是能夠建立可計算的無限列表而沒有妨礙計算的無限循環或大小問題。例如,可以建立生成無限斐波那契數列表的的函數(經常叫做“流”)。第n 個斐波那契數的計算僅是從這個無限列表上提取出這個元素,它只強迫這個列表的前 n 個成員的計算。
例如,在 Haskell 中,斐波納契數的列表可以寫為
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
在 Haskell 語法中,":" 預備一個元素給列表,tail 返回去掉第一個元素的一個列表,而 zipWith 使用一個特殊函數(這裡是加法)來組合兩個列表的對應元素生成第三個列表。
假定編程者是仔細的,只有生成特定結果所需要的值才被求值。但是特定計算可能導致程序嘗試求值無限數目個元素;例如,要求列表的長度或使用fold運算總和這個列表的元素將導致程序不能終止或耗盡內存。