我在文件a.scm
中定义了这个小程序:
(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
是一个自由变量'在它的身体内(而不是像'变量没有约束'或其他东西那样返回错误?)
感谢。
答案 0 :(得分:2)
当有人可以请问为什么x只在第一次调用f时才绑定为0?
x
被调用时, f
绑定为0 ,但当 时创建
让我在Common Lisp中重写你的函数:
(let ((x 0))
(defun f ()
(incf x)))
(f)
==> 1
(f)
==> 2
(f)
==> 3
(f)
==> 4
f
是变量x
的闭包。
IOW,创建f
时,x
绑定为0并在f
中提供,而<{1}}中只有 。< / p>
答案 1 :(得分:1)
let
不在函数体内;定义let
时评估f
,而不是在调用(set! x (+ 1 x)) x)
时评估x
。
函数正文为let
,其中f
表示由let
定义的变量。
或者换句话说,lambda
未绑定到(define x (let ((y 12)) y))
,而是绑定到x
。
类似地,
12
将(let ((y 12)) y)
绑定到php yii db/up
,而不是new\vendor\namespace\DbController@actionup
。
答案 2 :(得分:0)
我将set!
理解为“在常量环境中直接将值绑定到符号”,这意味着符号(此处为x
)不可用于绑定(例如let或a函数参数)。
唯一可以覆盖此“绑定到符号”的过程是另一个set!
。所以,当你一遍又一遍地调用你的函数时,它会查找符号x
并执行一个新的'set!'。如果您重新加载新文件,则应重置此绑定。是吗?