在過去的幾天裏,我一直在玩弄計劃(特別是詭計)的延續,並且對於某些函數的結果感到有點困惑並且想知道是否任何人都可以解釋到底發生了什麼。計劃:如何使用call/cc進行回溯
有一個名爲(get-token)
將在一個給定的文件檢索發現旁邊標記功能。例如,如果接下來的3個標記是「a」,「b」和「c」,調用(get-token)將在第一次調用時返回「a」,第二次調用時返回「b」和「c」第三次被稱爲。
我想要做的是有一個函數(peek-token)
,將調用(get-token)
,返回令牌,然後返回到調用(get-token)
函數之前的狀態。我嘗試了許多不同的方法來實現這一結果,和我目前擁有的是:
;; make things a little easier to write
(define-syntax bind/cc
(syntax-rules()
((bind/cc var . body)
(call/cc (lambda (var) . body)))))
;; function should return next token and then
;; revert to previous state
(define (peek-token)
(bind/cc return
(let ((token (get-token)))
(return token))))
我現在如何的理解,bind/cc
將在第一return
保存的延續,然後執行以下代碼塊。然後當return
再次被擊中時,程序跳回到連續被綁定的位置,並且結果給出token
值。
然而,當我運行上面的函數的結果是完全一樣的原始(get-token)
功能。
我會很感激,如果任何人都可以解釋我要去的地方錯了,或者表達一種更好的方法來獲得相同的結果(我知道有些人討厭去呼叫/立方厘米的方式)。
非常感謝你的幫助。我最終將'(peek-token)'函數放在我的掃描器文件中,並且只是跟蹤文件指針,以便我可以從中重新讀取令牌。出於好奇,你是否知道一種方法來捕獲任一方案或CL中的實際程序狀態?或者從來沒有真正需要這個? – vikingsheepman
除非我弄錯了形式'(call-cc(lambda(k)...(k x)))'與'(begin ... x)'完全相同的任何形式。 – jozefg
@jozefg非常多,假設這是繼續使用的唯一地方。 –