11

爲什麼懶惰的函數式編程語言需要是純粹的,這是相當明顯的。我正在研究一個相反的問題:如果一種語言想要變得純粹,那麼懶惰是否有很大的優勢? Haskell的一位設計師提出的一個論據是它消除了誘惑;也許,但我試圖衡量更具體的優勢。懶惰作爲內置語言功能的實際用途是什麼?

鑑於您希望進行函數式編程,那麼內置懶惰可以讓您更清楚,簡單或簡潔地表達事物的用例是什麼?

簡單地說:爲什麼懶惰如此重要,以至於你想將它構建到語言中?

(我在尋找對應用程序,而不是一個演示更加註重使用情況 - 我知道你可以做這樣的事情通過過濾自然數的無限列表產生素數的無限名單,但誰寫十倍「前的午餐......)

+0

這是一個很有趣的話題,但是你以一種相當不幸的方式提出這個問題,本質上是要求任何場景中的人物都可以想象懶惰評估是有用的。如果您正在設計一門語言,那麼您最好將注意力放在您嘗試制定的具體決策上,並要求幫助衡量選項,以便您可以做出明智的選擇。 – Shog9

+0

我不知道你是否會在這裏得到很好的答案,這個問題更多的是編程語言設計師,而不是程序員。這是一個問題,一個[關於計算機科學的網站](http://area51.stackexchange.com/proposals/35636/computer-science-non-programming?referrer=4M74nqLafvszXN85c5ibxQ2)會更好地工作。我推薦[在維基百科上引用](http://en.wikipedia.org/wiki/Lazy_evaluation#Further_reading)(而不是WP文章本身)的文章,尤其是「爲什麼FP很重要」。 – Gilles

+0

rwallace:基於@Gilles的編輯,我作了進一步的修改,以強調問題的惰性作爲一個內置的特徵(用例子來說明而不是作爲最終目標的例子),並重新打開這是可以接受的。如果您不同意,請討論。 – Shog9

回答

19

「沒有評估,直到需要在另一個地方」是一個簡化的隱喻,不包括懶惰評估的所有方面(例如,它沒有提到嚴格性現象)。

從理論的角度來看,設計純語言(當然如果它基於某種lambda演算而不是更特殊的評估模型)有三種方法:嚴格,非嚴格和全面。

他們每個人都有其優點和缺點,所以您需要閱讀相應的研究論文。

語言總數是三者中最純的。在另外兩種情況下,非終止可被視爲副作用,因此必須構建嚴格性和總體分析器以保持高效實施。這兩種分析都是不可判定的,所以分析儀永遠不可能完整。

但是,總語言最不具表現力:總語言無法完成圖靈。獲得足夠表現力的一種常用方法是擁有一個內置的有根據的證明系統,用於建立有目的的遞歸,與非全部語言的分析器相比,構建起來並不容易。

從實際角度來看,非嚴格語義允許您更輕鬆地定義控制抽象,因爲控制結構本質上是非嚴格的。用嚴格的語言,你仍然需要一些非嚴格語義的地方。例如。 if構造具有非嚴格的語義,即使在嚴格的語言中也是如此。

所以如果你的語言嚴格,控制結構是一個特例。相反,非嚴格的語言可以是一致的非嚴格的語言 - 它在嚴格的結構中沒有內在的需要。至於「誰在午餐前寫了十次」 - 任何爲他們的項目使用Haskell的人都會這樣做。我認爲用語言開發一個非玩具項目(在你的案例中是一種非嚴格的語言)是掌握它的優點和缺點的最好方法。

下面是由非玩具實施例示出了用於懶惰幾個通用usecases:

  1. 情況下,當控制流是很難預測。在沒有懶惰的情況下考慮屬性語法時,必須對屬性執行拓撲排序來解決依賴關係。每次更改依賴關係圖時重新排列代碼是不實際的。在Haskell中,你可以實現屬性語法形式而不需要明確的排序,並且Hackage上至少有兩個實際的實現。屬性語法在編譯器構建中有廣泛的應用。

  2. 「生成和搜索」的方法來解決許多優化問題。在嚴格的語言中,您必須交叉生成和搜索,在Haskell中,您只需編寫單獨的生成和搜索函數,並且代碼在語法上仍然是模塊化的,但是在運行時交織。考慮旅行商問題(TSP),當您生成所有可能的旅程時,然後使用分支定界算法搜索它們。請注意,分支綁定算法僅檢查遊覽的某些第一個城市,只生成必要的路線部分。 TSP即使在最純粹的配方中也有幾個應用,例如規劃,物流和微芯片的製造。稍作修改,在許多領域,如DNA測序,它似乎都是一個子問題。由於惰性代碼具有非模塊化的控制流,所以單個函數可能有許多可能的控制流,這取決於它執行的環境。這種現象可以看作是某種「控制流多態性」,所以懶控制流程抽象比其嚴格的對象更通用,而高級函數的標準庫在懶惰語言中更有用。想想Python生成器,循環和列表迭代器:在Haskell列表函數中涵蓋了所有三個用例,由於懶惰,控制流程適應不同的使用場景。它不僅限於列表 - 考慮Data.Arrow和迭代,懶惰和嚴格的State monad等版本。還要注意,非模塊化控制流既是優點也是劣勢,因爲它使性能的推理變得更困難。

  3. 懶惰的可能是無限的數據結構超出玩具的例子是有用的。請參閱Conal Elliott關於使用try來記憶高階函數的作品。無限的數據結構顯示爲無限的搜索空間(參見2),無限循環和永不耗盡的Python生成器(請參閱3)。

+0

提到的隱喻的來源似乎是亨德森和莫里斯的「懶惰評估者」,POPL'76 – nponeccop

2

Mac OS X的核心形象是懶惰的評價的一個很好的實際例子。

基本上,Core Image可讓您創建圖像生成器和濾鏡的有向無環圖。在這個過程的最後一步之前,實際上沒有進行評估:物化。當您請求實現核心圖像圖形時,最終圖像幀將通過圖形的變換向後傳播,從而最大限度地減少需要評估的實際像素值的數量。