【发布时间】:2016-12-25 17:01:38
【问题描述】:
从 Expanded form of fold in Racket 中定义 foldl ,第一个函数比第二个函数有什么优势:
(define (oldfoldl f init l)
(let loop ([init init] [l l])
(if (null? l) init
(loop (f (car l) init) (cdr l)))))
(define (myfoldl f init l)
(if (null? l) init
(myfoldl f (f (car l) init) (cdr l)) ))
换句话说,使用内部子函数有什么好处吗? 两者都给出相同的结果:
(oldfoldl + 0 '(1 2 3 4))
(myfoldl + 0 '(1 2 3 4))
输出:
10
10
编辑:使用 define 而不是 let 的第三个版本如下。会不会不一样:
(define (myfoldl2 f init l)
(define (loop [init init] [l l])
(if (null? l) init
(loop (f (car l) init) (cdr l)) ))
(loop init l) )
【问题讨论】:
-
不,第二次可能会更快,因为
f不是“免费的”(但可能不会在优化之后)。两者都有 98% 的机会生成相同的优化代码(对于可调试的代码,这将完全不同)。 -
事后我在编辑中添加了另一个版本。
-
@mso:这可能会或可能不会生成相同的代码。一个好的编译器应该很容易内联它。编辑:
define版本扩展为letrec,命名为let也是如此,所以即使是一个糟糕的编译器也应该能够做到。