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
的主体相同,即使它不是。正如你的回答所暗示的,这只是一个优化。有些实现可能会将这些常量折叠,以便将它们转换为完全相同的代码。我明天会更新你的答案并删除它。