Ruby 是否执行尾调用优化? [英] Does Ruby perform Tail Call Optimization?

查看:21
本文介绍了Ruby 是否执行尾调用优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

函数式语言导致使用递归来解决很多问题,因此其中许多执行尾调用优化 (TCO).TCO 导致从另一个函数(或它本身,在这种情况下,此功能也称为尾递归消除,它是 TCO 的子集)调用函数,作为该函数的最后一步,不需要新的堆栈帧,从而减少开销和内存使用.

Functional languages lead to use of recursion to solve a lot of problems, and therefore many of them perform Tail Call Optimization (TCO). TCO causes calls to a function from another function (or itself, in which case this feature is also known as Tail Recursion Elimination, which is a subset of TCO), as the last step of that function, to not need a new stack frame, which decreases overhead and memory usage.

Ruby 显然从函数式语言(lambda、map 等函数等)借用"了许多概念,这让我很好奇:Ruby 是否执行尾调用优化?

Ruby obviously has "borrowed" a number of concepts from functional languages (lambdas, functions like map and so forth, etc.), which makes me curious: Does Ruby perform tail call optimization?

推荐答案

不,Ruby 不执行 TCO.但是,它也不会执行 TCO.

No, Ruby doesn't perform TCO. However, it also doesn't not perform TCO.

Ruby 语言规范没有提及 TCO.这并不是说您必须这样做,但也不表示您不能这样做.你不能依赖它.

The Ruby Language Specification doesn't say anything about TCO. It doesn't say you have to do it, but it also doesn't say you can't do it. You just can't rely on it.

这与 Scheme 不同,其中语言规范要求所有实现必须执行 TCO.但它也与 Python 不同,Guido van Rossum 在多个场合(最后一次就在几天前)明确表示 Python 实现不应执行 TCO.

This is unlike Scheme, where the Language Specification requires that all Implementations must perform TCO. But it is also unlike Python, where Guido van Rossum has made it very clear on multiple occasions (the last time just a couple of days ago) that Python Implementations should not perform TCO.

Yukihiro Matsumoto 对 TCO 表示同情,他只是不想强制所有实现来支持它.不幸的是,这意味着您不能依赖 TCO,否则,您的代码将无法再移植到其他 Ruby 实现.

Yukihiro Matsumoto is sympathetic to TCO, he just doesn't want to force all Implementations to support it. Unfortunately, this means that you cannot rely on TCO, or if you do, your code will no longer be portable to other Ruby Implementations.

因此,一些 Ruby 实现会执行 TCO,但大多数不会.例如,YARV 支持 TCO,尽管(目前)您必须明确取消对源代码中的一行的注释并重新编译 VM,以激活 TCO – 在未来的版本中它将默认启用,在实施证明后稳定的.Parrot 虚拟机本身支持 TCO,因此 Cardinal 也可以很容易地支持它.CLR 对 TCO 有一些支持,这意味着 IronRuby 和 Ruby.NET 可能会做到这一点.Rubinius 或许也能做到.

So, some Ruby Implementations perform TCO, but most don't. YARV, for example, supports TCO, although (for the moment) you have to explicitly uncomment a line in the source code and recompile the VM, to activate TCO – in future versions it is going to be on by default, after the implementation proves stable. The Parrot Virtual Machine supports TCO natively, therefore Cardinal could quite easily support it, too. The CLR has some support for TCO, which means that IronRuby and Ruby.NET could probably do it. Rubinius could probably do it, too.

但 JRuby 和 XRuby 不支持 TCO,而且它们可能不会,除非 JVM 本身获得对 TCO 的支持.问题是这样的:如果你想要一个快速的实现,并且与 Java 快速无缝地集成,那么你应该与 Java 堆栈兼容,并尽可能地使用 JVM 的堆栈.您可以很容易地使用蹦床或显式连续传递样式来实现 TCO,但是您不再使用 JVM 堆栈,这意味着每次您想要调用 Java 或从 Java 调用到 Ruby 时,您都必须执行某种转换,这很慢.因此,XRuby 和 JRuby 选择了速度和 Java 集成,而不是 TCO 和延续(基本上存在相同的问题).

But JRuby and XRuby don't support TCO, and they probably won't, unless the JVM itself gains support for TCO. The problem is this: if you want to have a fast implementation, and fast and seamless integration with Java, then you should be stack-compatible with Java and use the JVM's stack as much as possible. You can quite easily implement TCO with trampolines or explicit continuation-passing style, but then you are no longer using the JVM stack, which means that everytime you want to call into Java or call from Java into Ruby, you have to perform some kind of conversion, which is slow. So, XRuby and JRuby chose to go with speed and Java integration over TCO and continuations (which basically have the same problem).

这适用于所有想要与某些本机不支持 TCO 的主机平台紧密集成的 Ruby 实现.例如,我猜 MacRuby 也会遇到同样的问题.

This applies to all implementations of Ruby that want to tightly integrate with some host platform that doesn't support TCO natively. For example, I guess MacRuby is going to have the same problem.

这篇关于Ruby 是否执行尾调用优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆