Lisp 用局部状态理解对象——Scheme
我正在为我的计划期末考试而学习,与当地政府的合作一直是一个棘手的问题 这是我期末考试的一个问题,我需要帮助Lisp 用局部状态理解对象——Scheme,lisp,scheme,mit-scheme,Lisp,Scheme,Mit Scheme,我正在为我的计划期末考试而学习,与当地政府的合作一直是一个棘手的问题 这是我期末考试的一个问题,我需要帮助 (define (make-incrementer n) (let ((old 0) (new 0)) (lambda () (cond ((< new n) (set! old new) (set! new (+ new 1)) old)
(define (make-incrementer n)
(let ((old 0)
(new 0))
(lambda ()
(cond ((< new n)
(set! old new)
(set! new (+ new 1))
old)
(else
(set! old 0)
(set! new 1)
old)))))
(define a (make-incrementer 3))
(define b (make-incrementer 3))
(define c a)
; 1) (a)
; 2) (a)
(定义(使增量为n)
(let((旧0)
(新的(0))
(lambda()
(cond(
为什么
a
在第二次调用时返回1?我在看代码,我们给出的n
总是3。那么,它不总是做其他的
案例吗?欢迎来到闭包的奇妙世界!这是Scheme中闭包工作原理的教科书示例
因此,make counter
返回一个函数,该函数包含从其封闭环境捕获的3个变量:n
,old
,new
。在本例中,启动环境如下所示
_name_|_value_
n | 3
old | 0
new | 1
每次调用时,它都会递增old
和new
,如果它们大于n
,则将它们环绕。因为它正在使用set代码>,此递增操作会使lambda环境中的变量发生变化,但由于这些变量是从周围环境捕获的,因此在将来的所有调用中也会更改这些变量
这就是为什么即使输入相同,也会得到不同的回报
如果这看起来像巫术,你可以把它想象成更普通语言中的物体:
例如Python:
class Foo():
def __init__(self, n, m):
self.n = n
self.m = m
def count(self):
self.n += 1
if self.n == self.m:
self.n = 1
return self.n-1
f = Foo(0, 2)
f.count() # 1
f.count() # 0
这是相同的基本思想,除了这里我们更明确地说明了环境的来源,self
。在这个方案中,我们用lambda捕捉周围的变量来模拟这个过程
有关更多信息,请查看以下示例,这些示例可能有助于理解捕获状态的概念:
(define (always x)
(lambda rest x))
(define always-true (always #t))
(always-true #f)
-> #t
(define (add-n n)
(lambda (m)
(+ n m)))
(define add-1 (add-n 1))
(add-1 10)
-> 11
(define (complement predicate)
(lambda (x)
(not (predicate x)))
(define not-positive? (complement positive?))
(not-positive? -1)
-> #t
接下来是一个示例,其中捕获的状态(在本例中为l
)发生突变。这与捕获和修改new
和old
的情况类似
(define (nexting l)
(lambda ()
(if (null? l)
'()
(let ((answer (car l)))
(set! l (cdr l))
answer))))
(define next-user (nexting '(Alice Bob David)))
(next-user)
-> Alice
(next-user)
-> Bob
(next-user)
-> David
(next-user)
'()
有时,代码布局有助于理解,因为这使不同名称的范围显而易见。@GoZoner的确,感谢上帝在发布到SOim时使用了emacs中的C-M-\in和'M-x untabify',不幸的是,我没有emacs。@user2036503:GNU emacs可用于windows,我最后一次看了一下。我不明白的主要问题是,旧的和新的不一定要大于3才能使递增集起作用吗?@user2036503是的,但它们正在递增,(set!new(+1 new))
我可能遗漏了一些非常明显的东西。对不起。但是,要使增量起作用,不必大于n。但是n等于3,初始的新值等于1,所以它从不递增。不用担心,它开始有意义了吗?也许我输入(a)和(a)的方式有点问题。但它不应该返回0,然后返回0。还是我错了?