关于"集!"和"让"表达式

时间:2017-06-21 16:12:28

标签: scheme lisp

我在文件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是一个自由变量'在它的身体内(而不是像'变量没有约束'或其他东西那样返回错误?)

感谢。

3 个答案:

答案 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!'。如果您重新加载新文件,则应重置此绑定。是吗?

是的......有人说CHICKEN吗?