我正在刷新我的低Racket知识并且遇到了这篇streams in racket优秀的帖子。我的问题是关于这个片段:
(define powers-of-two
(letrec ([f (lambda (x) (cons x (lambda () (f (* x 2)))))])
(lambda () (f 2))))
我理解'内部lambda'的原因,但为什么OP使用lambda作为整个函数?难道不能像这样有效地完成吗?
(define (powers-of-two)
(letrec ([f (lambda (x) (cons x (lambda () (f (* x 2)))))])
(f 2)))
我进行了实验,没有看到任何区别。我的问题是,这只是一个风格问题,还是有一些理由让前者更可取。
答案 0 :(得分:3)
没有区别。由于第二个示例中的f
不会关闭任何内容,因此可以将其提升到powers-of-two
函数之外,这与第一个示例相同。
第一个可能更可取的一个原因是,只需要创建一个f
函数。对于第二个函数,每次有人调用f
时都会创建一个新的(powers-of-two)
函数。
我尝试了两种方法,但两者都没有明显快于另一种。
答案 1 :(得分:2)
(define (name arg)
arg)
这是写作的简短形式:
(define name
(lambda (arg)
arg))
所以第一个例子发生的事情就是letright立即发生,返回的函数将是(lambda () (f 2))
,并且f
在它的闭包中。
第二个做了一个名为powers-of-two
的过程,当应用(powers-of-two)
时,它将返回与第一个powers-of-two
相同的过程。将其视为powers-of-two-generator
。< / p>
因此:
(define powers-of-two
(letrec ([f (lambda (x) (cons x (lambda () (f (* x 2)))))])
(lambda () (f 2))))
(define (powers-of-two-generator)
(letrec ([f (lambda (x) (cons x (lambda () (f (* x 2)))))])
(f 2)))
(powers-of-two) ; ==> (2 . procedure)
(define powers-of-two2 (powers-of-two-generator)) ; ==> procedure
(powers-of-two2) ; ==> (2 . procedure)
你看到了区别吗?