Stream 为什么在球拍中使用这种lambda风格?

Stream 为什么在球拍中使用这种lambda风格?,stream,racket,Stream,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 (

我正在复习我的低水平知识,并偶然发现了这篇优秀的文章。我的问题是关于这个剪报:

(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)))
我做了实验,没有发现任何区别。我的问题是,这是否只是一个风格问题,或者是否有某种原因认为前者更可取

(define (name arg)
   arg)
这是写作的简短形式:

(define name 
   (lambda (arg)
      arg))
因此,第一个示例中发生的情况是,letrect立即发生,并且返回的函数将是
(lambda()(f2))
,其闭包中包含
f

第二个生成一个名为
powers of two
的过程,当应用
(powers of two)
时,该过程将返回与第一个
powers of two
相同的值。。将其视为两台发电机的功率

因此:

你看到区别了吗

这是写作的简短形式:

(define name 
   (lambda (arg)
      arg))
因此,第一个示例中发生的情况是,letrect立即发生,并且返回的函数将是
(lambda()(f2))
,其闭包中包含
f

第二个生成一个名为
powers of two
的过程,当应用
(powers of two)
时,该过程将返回与第一个
powers of two
相同的值。。将其视为两台发电机的功率

因此:


你看到区别了吗?

没有区别。由于第二个示例中的
f
没有关闭任何东西,因此可以将其提升到两个
函数的
幂之外,这与第一个示例相同

第一种可能更可取的一个原因是,只需要创建一个
f
函数。对于第二个函数,每当有人调用
(二的幂)
时,就会创建一个新的
f
函数


虽然我尝试了两种方法,但两种方法都没有明显快于另一种方法。

没有区别。由于第二个示例中的
f
没有关闭任何东西,因此可以将其提升到两个
函数的
幂之外,这与第一个示例相同

第一种可能更可取的一个原因是,只需要创建一个
f
函数。对于第二个函数,每当有人调用
(二的幂)
时,就会创建一个新的
f
函数


虽然我尝试了两种方法,但两种方法都没有明显比另一种快。

很好的解释。谢谢你花时间。西尔维斯特,这不是我在评估你的例子时得到的。我得到的是
(二次幂)
->
(2.#)
和你一样,但是调用
(二次幂)
给我的是
(2.#)
,而不是
。因此,
powers-of-two-2
不是一个函数,调用时会产生错误。@AlexKnauth您是对的。查看文本,我似乎假设lambda表达式与
letrec
的主体相同,即使它不是。正如你的回答所暗示的,这只是一个优化。有些实现可能会将这些常量折叠,以便将它们转换为完全相同的代码。我明天会更新你的答案并删除这个。很好的解释。谢谢你花时间。西尔维斯特,这不是我在评估你的例子时得到的。我得到的是
(二次幂)
->
(2.#)
和你一样,但是调用
(二次幂)
给我的是
(2.#)
,而不是
。因此,
powers-of-two-2
不是一个函数,调用时会产生错误。@AlexKnauth您是对的。查看文本,我似乎假设lambda表达式与
letrec
的主体相同,即使它不是。正如你的回答所暗示的,这只是一个优化。有些实现可能会将这些常量折叠,以便将它们转换为完全相同的代码。我明天会更新你的答案并删除它。