2017-06-21 34 views
0

我有一個文件a.scm定義這個小程序:關於「set!」和「讓」表情

(define f 
    (let ((x 0)) 
    (lambda() 
     (set! x (+ 1 x)) 
     x))) 

當打電話f反覆,結果不斷增加:

CHICKEN 
(c) 2008-2016, The CHICKEN Team 
(c) 2000-2007, Felix L. Winkelmann 
Version 4.11.0 
linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables ] 
compiled 2016-08-23 on buildvm-13.phx2.fedoraproject.org 

#;1> (load "a.scm") 
; loading a.scm ... 
#;2> (f) 
1 
#;3> (f) 
2 
#;4> (f) 
3 
#;5> 

可能有人請扔一些輕至於爲什麼x綁定到0只有第一次f被調用?我預計每次調用f時,都應執行let綁定。

另外,如果反覆調用,x不綁定到0那麼如何lambda表達式去知道x是它的身體內的「自由變量」(而不是返回像「變量錯誤不bound`或東西)?

謝謝。

回答

0

我將set!理解爲'直接在常量環境中將值綁定到符號',這意味着符號(此處爲x)不再可用於綁定(例如let或函數參數)。

可以覆蓋此'綁定到符號'的唯一過程是另一個set!。所以,當你一遍又一遍地調用你的函數時,它會查找符號x並執行一個新的「set!」。如果你重新加載你的文件,這個綁定應該被重置。可以?

btw ...有人說雞肉?

+0

'set!'不會綁定任何東西:它會改變現有的綁定。如果沒有現有的綁定,那麼它的行爲就沒有定義(事實上,很可能是一個錯誤:我對Scheme標準不太熟悉)。在CL中濫用'set!'或'setf' /'setq''來創建綁定通常是Python引發的braindamage的症狀。 – tfb

+0

你說得對 - 我的確在想別的東西。不是Python。 – hyperlinq

2

Could someone please throw some light as to why x is bound to 0 only the first time f is invoked?

x勢必0 f調用,但是當它是創建

讓我重寫你的函數Common Lisp中:

(let ((x 0)) 
    (defun f() 
    (incf x))) 
(f) 
==> 1 
(f) 
==> 2 
(f) 
==> 3 
(f) 
==> 4 

f是在可變x封閉。

IOW,創建f時,x勢必0和f提供 - 和只在f

1

let不在函數體內;當f被定義,而不是被調用時,let被評估。

該函數的主體是(set! x (+ 1 x)) x),其中x指的是由let定義的變量。
或換句話說,f未綁定到let,而是綁定到lambda

同樣,

(define x (let ((y 12)) y)) 

結合x12,不(let ((y 12)) y)