2012-09-13 100 views
2

我是Lisp的新手,我正在閱讀有關ANSI Common Lisp第8章中的文本生成器示例。我遵循該示例並在LET變量的作用域中定義了一個函數「see」 「prec」,Common Lisp中的未綁定變量

(let ((prec '|.|)) 
    (defun see (symb) 
    (let ((pair (assoc symb (gethash prev *words*)))) 
     (if (null pair) 
     (push (cons symb 1) (gethash prev *words*)) 
     (incf (cdr pair)))) 
    (setf prev symb))) 

並將其保存到一個lisp文件中。

然後當我回到REPL,並試圖援引看到加載文件的編譯版本之後,出現錯誤:

The variable PREV is unbound. [Condition of type UNBOUND-VARIABLE]

如何調用看正常嗎?什麼是詞彙關閉?我都很困惑。

感謝您的幫助。

回答

4

看起來好像你已經鍵入prec而不是prev在封閉的let窗體中。

詞法關閉是「關閉」詞法環境的一部分(因此名稱)的功能。在lisp中有很多關於閉包的介紹,我不想在這裏重複,但實際上,let是操縱詞彙環境的最常用方式;在這種情況下,您想要添加prev的綁定,該綁定隨後可用於表單正文中的代碼。您的功能see將「關閉」此綁定,因此每個撥打電話see都可以訪問它,即使您進行這些呼叫時,您將不再處於由let表單建立的詞彙環境中。從某種意義上說,你可以說函數的定義是和它綁定的。

由於您似乎錯誤鍵入了prev的名稱,因此您的函數試圖引用尚未在代碼中建立的綁定。

+0

對不起,我以前沒有答覆。現在你已經指出了這個錯誤,我覺得很難發佈這個,甚至沒有注意到它!感謝您的耐心,您對詞彙封閉的闡釋是迄今爲止我見過的最好,最簡潔的一個! – user1667687