【问题标题】:Why use this style of lambda in Racket?为什么在 Racket 中使用这种风格的 lambda?
【发布时间】:2013-11-10 17:21:23
【问题描述】:

我正在复习我的球拍知识,并遇到了这个streams in racket 出色的帖子。我的问题是关于这个片段:

(define powers-of-two
    (letrec ([f (lambda (x) (cons x (lambda () (f (* x 2)))))])
        (lambda () (f 2))))

我理解“内部 lambdas”的原因,但为什么 OP 对整个函数使用 lambda?难道不能像这样有效地完成吗?

(define (powers-of-two)
    (letrec ([f (lambda (x) (cons x (lambda () (f (* x 2)))))])
       (f 2)))

我进行了实验,没有发现任何区别。我的问题是,这只是风格问题,还是出于某种原因,前者更可取。

【问题讨论】:

    标签: stream racket


    【解决方案1】:

    没有区别。由于第二个示例中的f 不会关闭任何内容,因此可以将其提升到powers-of-two 函数之外,这与第一个示例等效。

    第一个可能更可取的一个原因是只需要创建一个f 函数。对于第二个,每次有人调用(powers-of-two) 时都会创建一个新的f 函数。

    不过,我尝试对它们进行计时,但两者都没有明显比另一个快。

    【讨论】:

      【解决方案2】:
      (define (name arg)
         arg)
      

      这是写作的简写形式:

      (define name 
         (lambda (arg)
            arg))
      

      所以第一个示例发生的情况是 letrect 立即发生,返回的函数将是 (lambda () (f 2))f 在它的闭包中。

      第二个创建了一个名为powers-of-two 的过程,当应用(powers-of-two) 时,将返回与第一个powers-of-two 相同的结果。将其视为powers-of-two-generator

      因此:

      (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)
      

      你看出区别了吗?

      【讨论】:

      • 很好的解释。感谢您抽出宝贵时间。
      • Sylwester,这不是我评估你的例子时得到的。我像你一样得到(powers-of-two) -> '(2 . #<procedure>),但调用(powers-of-two-generator)给我'(2 . #<procedure>),而不是#<procedure>。那么powers-of-two2 不是函数,调用时会报错。
      • @AlexKnauth 你是对的。查看文本,我似乎假设与 letrec 的主体相同的 lambda 表达式,即使它不是。正如您的回答所暗示的,这只是一种优化。一些实现可能会不断地折叠这些,以便它们变成完全相同的代码。我会支持你的答案并明天删除它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      • 2018-02-21
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多