Functional programming 除“以外的所有尾部递归函数;rev";需要遍历列表两次吗?
根据我收集的信息,在实现尾部递归调用时,存储在Functional programming 除“以外的所有尾部递归函数;rev";需要遍历列表两次吗?,functional-programming,Functional Programming,根据我收集的信息,在实现尾部递归调用时,存储在acc(accumulator)变量中的结果列表元素实际上会向后显示,因此一般趋势似乎是在从当前函数返回之前将其向后反转 这意味着,如果我没有弄错的话,函数式编程语言中的所有高阶函数(除了rev)调用都会有系统开销,至少它们的命令式调用是如此 我是不是遗漏了什么?这不是很糟糕吗?这只是意味着尾部调用递归并不是函数式编程优化的全部。首先,列表本身就是隐藏的链表,在所有语言中,链表上的算法都有点低效。因此,函数式语言通常提供更接近命令式数组的结构,以满足
acc
(accumulator)变量中的结果列表元素实际上会向后显示,因此一般趋势似乎是在从当前函数返回之前将其向后反转
这意味着,如果我没有弄错的话,函数式编程语言中的所有高阶函数(除了rev
)调用都会有系统开销,至少它们的命令式调用是如此
我是不是遗漏了什么?这不是很糟糕吗?这只是意味着尾部调用递归并不是函数式编程优化的全部。首先,列表本身就是隐藏的链表,在所有语言中,链表上的算法都有点低效。因此,函数式语言通常提供更接近命令式数组的结构,以满足程序员需要高效处理大型线性集合的情况。此外,除了在介绍性练习中,通过显式递归逐个元素建立列表的场景相对较少。相反,像
map
和filter
这样的高阶函数更常用于生产代码中。对于编译器或标准库编写者来说,如何实现这些功能成为一个问题
我曾经非常好奇,以至于我在SML/NJ的标准库中找到了SML/NJ如何实现map
。我希望看到它以您描述的方式通过使用rev
的尾部调用递归实现。相反,他们这样做:
fun map f = let
fun m [] = []
| m [a] = [f a]
| m [a, b] = [f a, f b]
| m [a, b, c] = [f a, f b, f c]
| m (a :: b :: c :: d :: r) = f a :: f b :: f c :: f d :: m r
in
m
end
一个非尾部调用递归版本,将天真递归方法中隐含的函数调用开销减少了4倍。他们可能考虑过使用尾部调用递归方法的想法,但后来拒绝了,因为他们不希望两次传递的性能受到影响
最后一句话,除了C语言之外的每种语言都有一些特性,从效率的角度来看,这些特性让人不禁要问:“这真的很糟糕吗?”。Python——每个对象都有一个给出其类型和大小的头——这不是很糟糕吗?语言需要权衡。总的来说,函数式语言是以牺牲执行时间为代价来优化开发人员时间的语言。现代计算机的速度快得令人眼花缭乱——为什么不利用这种速度来实现一些语言,让您能够在更高的抽象级别上更简洁地编写代码呢?对于核心的数值分析可能不是最好的权衡,但对于许多问题领域来说,这是一个好主意 这只是意味着尾部调用递归不是函数式编程中的全部优化。首先,列表本身就是隐藏的链表,在所有语言中,链表上的算法都有点低效。因此,函数式语言通常提供更接近命令式数组的结构,以满足程序员需要高效处理大型线性集合的情况。此外,除了在介绍性练习中,通过显式递归逐个元素建立列表的场景相对较少。相反,像
map
和filter
这样的高阶函数更常用于生产代码中。对于编译器或标准库编写者来说,如何实现这些功能成为一个问题
我曾经非常好奇,以至于我在SML/NJ的标准库中找到了SML/NJ如何实现map
。我希望看到它以您描述的方式通过使用rev
的尾部调用递归实现。相反,他们这样做:
fun map f = let
fun m [] = []
| m [a] = [f a]
| m [a, b] = [f a, f b]
| m [a, b, c] = [f a, f b, f c]
| m (a :: b :: c :: d :: r) = f a :: f b :: f c :: f d :: m r
in
m
end
一个非尾部调用递归版本,将天真递归方法中隐含的函数调用开销减少了4倍。他们可能考虑过使用尾部调用递归方法的想法,但后来拒绝了,因为他们不希望两次传递的性能受到影响
最后一句话,除了C语言之外的每种语言都有一些特性,从效率的角度来看,这些特性让人不禁要问:“这真的很糟糕吗?”。Python——每个对象都有一个给出其类型和大小的头——这不是很糟糕吗?语言需要权衡。总的来说,函数式语言是以牺牲执行时间为代价来优化开发人员时间的语言。现代计算机的速度快得令人眼花缭乱——为什么不利用这种速度来实现一些语言,让您能够在更高的抽象级别上更简洁地编写代码呢?对于核心的数值分析可能不是最好的权衡,但对于许多问题领域来说,这是一个好主意 这只是意味着尾部调用递归不是函数式编程中的全部优化。首先,列表本身就是隐藏的链表,在所有语言中,链表上的算法都有点低效。因此,函数式语言通常提供更接近命令式数组的结构,以满足程序员需要高效处理大型线性集合的情况。此外,除了在介绍性练习中,通过显式递归逐个元素建立列表的场景相对较少。相反,像
map
和filter
这样的高阶函数更常用于生产代码中。对于编译器或标准库编写者来说,如何实现这些功能成为一个问题
我曾经非常好奇,以至于我在SML/NJ的标准库中找到了SML/NJ如何实现map
。我希望看到它以您描述的方式通过使用rev
的尾部调用递归实现。相反,他们这样做:
fun map f = let
fun m [] = []
| m [a] = [f a]
| m [a, b] = [f a, f b]
| m [a, b, c] = [f a, f b, f c]
| m (a :: b :: c :: d :: r) = f a :: f b :: f c :: f d :: m r
in
m
end
一种非尾部调用递归版本,它将函数-c减少了4倍