为什么在Racket中使用这种lambda?

时间:2013-10-30 21:23:03

标签: stream racket

我正在刷新我的低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)))

我进行了实验,没有看到任何区别。我的问题是,这只是一个风格问题,还是有一些理由让前者更可取。

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)

你看到了区别吗?