lambda函数与scheme中的内存
我不明白为什么我要写信lambda函数与scheme中的内存,scheme,lisp,racket,lambda,Scheme,Lisp,Racket,Lambda,我不明白为什么我要写信 (define (iter-list lst) (let ((cur lst)) (lambda () (if (null? cur) '<<end>> (let ((v (car cur))) (set! cur (cdr cur)) v))))) (define il2 (iter-list '(1 2))) (定义(iter清单
(define (iter-list lst)
(let ((cur lst))
(lambda ()
(if (null? cur)
'<<end>>
(let ((v (car cur)))
(set! cur (cdr cur))
v)))))
(define il2 (iter-list '(1 2)))
(定义(iter清单lst)
(让((当前和当前)
(lambda()
(如果(空?cur)
'
(让((v(car cur)))
(设置!cur(cdr cur))
v) )))
(定义il2(国际热核实验堆清单(1-2)))
打电话(il2)2次,我已经打印了:1次,然后2次
(这就是我想要的结果)
但是如果我不把(lambda()和应用(il2)2次,我得到1
换句话说,为什么将if部分与函数lambda()关联会使它保留我们以前应用函数时所做的操作的内存?当您将if包装在lambda中(并像那样返回它)时,cur let(在if的作用域内)会附加到lambda。这称为闭包
现在,如果你读一点关于闭包的内容,你会发现它们可以用来保持状态(就像你在这里做的那样)。这对于创建不断递增的计数器或对象系统非常有用(闭包可以用作一种由内而外的对象).这就是正在发生的事情。首先,当你写这篇文章时,重要的是你要明白:
(define (iter-list lst)
(let ((cur lst))
(lambda ()
...)))
它被转换为这种等价形式:
(define iter-list
(lambda (lst)
(let ((cur lst))
(lambda ()
...))))
您可以看到,另一个lambda
首先存在。现在,最外层的lambda
将定义一个局部变量,cur
,它将“记住”列表的值,然后返回最内层的lambda作为结果,最内层的lambda
将“捕获”、“封闭”上面在a中定义的cur
变量。换句话说:iter list
是一个返回函数结果的函数,但在执行此操作之前,它将“记住”cur值。这就是为什么您这样称呼它:
(define il2 (iter-list '(1 2))) ; iter-list returns a function
(il2) ; here we're calling the returned function
(define il2 (iter-list '(1 2))) ; iter-list returns a number
(il2) ; this won't work: il2 is just a number!
il2 ; this works, and returns 1
将其与此处发生的情况进行比较:
(define (iter-list lst)
(let ((cur lst))
...))
上述内容相当于:
(define iter-list
(lambda (lst)
(let ((cur lst))
...)))
在上面的例子中,iter list
只是一个函数,调用时会返回一个值(不是像以前那样的另一个函数!),这个函数不“记住”总之,第一个示例创建一个闭包并记住值,因为它返回一个函数,而第二个示例只返回一个数字,并按如下方式调用:
(define il2 (iter-list '(1 2))) ; iter-list returns a function
(il2) ; here we're calling the returned function
(define il2 (iter-list '(1 2))) ; iter-list returns a number
(il2) ; this won't work: il2 is just a number!
il2 ; this works, and returns 1
请注意,在原始代码中,您将
lst
重命名为cur
。您实际上不需要这样做。内部lambda(即将关闭的)可以直接捕获lst
参数。因此,这将产生相同的结果:
(define (iter-list lst)
(lambda ()
...)) ; your code, replace 'cur' with 'lst'
以下是捕获变量的其他闭包生成函数的一些示例:
(define (always n)
(lambda () n))
(define (n-adder n)
(lambda (m) (+ n m)))
(define (count-from n)
(lambda ()
(let ((result n))
(set! n (+ n 1))
result)))