我有點了解如何將基本功能(如運算法則)轉換爲Scheme中的延續傳球風格。 但是,如果函數涉及遞歸呢? 例如,計劃 - 轉換爲延續傳球風格
(define funname
(lambda (arg0 arg1)
(and (some procedure)
(funname (- arg0 1) arg1))))
請給我意見。 預先感謝您。
我有點了解如何將基本功能(如運算法則)轉換爲Scheme中的延續傳球風格。 但是,如果函數涉及遞歸呢? 例如,計劃 - 轉換爲延續傳球風格
(define funname
(lambda (arg0 arg1)
(and (some procedure)
(funname (- arg0 1) arg1))))
請給我意見。 預先感謝您。
(define (func x y k)
(some-procedure
(lambda (ret)
(if ret
(- x 1
(lambda (ret)
(func ret y k)))
(k #f))))
你所缺乏的基本情況,這就是爲什麼要延續的唯一顯式調用是(k #f)
。如果你有一個基本情況,那麼你也可以將基本情況返回值傳遞給繼續。例如:
(define (func x y k)
(zero? x
(lambda (ret)
(if ret
(k y)
(some-procedure
(lambda (ret)
(if ret
(- x 1
(lambda (ret)
(func ret y k)))
(k #f))))))))
一個地方。相關部分(VII)不依賴於書籍的其他部分,因此您可以在此處跳到其他部分。特別是一個將代碼手動轉換爲CPS並解決遞歸函數的擴展示例(第17章的第一部分)。
此外,我爲我的班級寫了一篇extended version的文章,其中有更多的例子和關於這個主題的更多細節 - 你也許會覺得這很有用。除PLAI文本之外,我還介紹了一些常見的延續實現,比如實現生成器,模糊運算符等等。 (但請注意,PLAI繼續討論實施策略,這是我的文本未涉及的部分。)
這部分重複Chris Jester-Young的回答,但是,我希望我能更好地解釋它:-)。
在CPS,你正在尋找不同的是這兩件事情(大約)之間:
後者就是克里斯例子中的lambda表達式。基本上,評估一個lambda創建一個閉包 - 這些閉包用於執行堆棧框架在執行直接樣式程序時所做的相同工作。代替棧幀中的返回地址,閉包包含一個連續函數的綁定,閉包的代碼調用它。