簡體   English   中英

使用帶有狀態閉包的處理程序綁定是否有效?

[英]Is using handler-bind with a stateful closure valid?

這是一個符合標准的 Common Lisp 程序嗎?

(handler-bind ((condition (let ((x 0))
                            (lambda (c)
                              (declare (ignore c))
                              (print (incf x))))))
  (signal 'condition)
  (signal 'condition))

帶有 SBCL (2.0.5.37) 的 output 是:

1
1

帶 ABCL/CCL/ECL 的 output 是:

1
2

Common Lisp 標准定義了哪種行為?


結語

這是 SBCL 中的一個錯誤, 現在已修復

這並不完全清楚。 規范說:

在指示的處理程序綁定生效的動態環境中執行forms

然后說

如果找到合適的類型,則關聯的處理程序將在這些處理程序綁定都不可見的動態環境中運行(以避免遞歸錯誤)。

如果您將“運行”的意思解釋為調用 function,則表明處理程序表達式在進行綁定時被評估一次。 這是 CCL/ABCL/ECL/LispWorks 的實現,所以 state 保持在閉包中。

但 SBCL 似乎將“運行”解釋為“評估和調用”的意思。 因此,每次運行處理程序時都會創建一個新的閉包,並且 state 會丟失。

我懷疑意圖是第一個解釋,因為 CL 沒有其他“惰性”綁定。

如果您將問題中的代碼更改為:

(let ((handler
        (let ((x 0))
          (lambda (c)
            (declare (ignore c))
            (print (incf x))))))
  (handler-bind ((condition handler))
    (signal 'condition)
    (signal 'condition)))

那么 SBCL 的行為方式與其他實現相同。 我認為這很清楚地表明其他實現所采用的解釋是預期的,並且它還提供了一種實用的解決方法,如果該解釋實際上是正確的,那么它是 SBCL 中的一個錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM