No, Ruby no realiza TCO. Sin embargo, tampoco no realiza TCO.
La especificación de lenguaje Ruby no dice nada sobre TCO. No dice que tiene que hacerlo, pero tampoco dice que no puede hacerlo. Simplemente no puede confiar en él.
Esto es a diferencia esquema, donde el Lenguaje de Especificación de requiere que todos los Implementaciones debe realizar el TCO. Pero también es diferente a Python, donde Guido van Rossum dejó muy claro en múltiples ocasiones (la última vez hace apenas un par de días) que las implementaciones de Python no deberían realizar TCO.
Yukihiro Matsumoto simpatiza con TCO, simplemente no quiere forzar todos Implementaciones para apoyarlo. Desafortunadamente, esto significa que no puede confiar en TCO, o si lo hace, su código ya no será transferible a otras Implementaciones de Ruby.
Por lo tanto, algunas implementaciones de Ruby realizan TCO, pero la mayoría no. YARV, por ejemplo, admite TCO, aunque (por el momento) tiene que descomentar explícitamente una línea en el código fuente y recompilar la máquina virtual, para activar el TCO; en versiones futuras estará activado por defecto, después de que la implementación pruebe estable. La máquina virtual Parrot admite TCO de forma nativa, por lo tanto, Cardinal también podría soportarla fácilmente. El CLR tiene algo de apoyo para TCO, lo que significa que IronRuby y Ruby.NET podrían hacerlo. Rubinius probablemente podría hacerlo también.
Pero JRuby y XRuby no son compatibles con TCO, y probablemente no lo hagan, a menos que la JVM en sí obtenga soporte para TCO. El problema es el siguiente: si desea una implementación rápida y una integración rápida y sin problemas con Java, entonces debe ser compatible con la pila con Java y usar la pila de la JVM tanto como sea posible. Puede implementar fácilmente TCO con trampolines o estilo de continuación de paso explícito, pero ya no está utilizando la pila JVM, lo que significa que cada vez que desea llamar a Java o llamar desde Java a Ruby, debe realizar algún tipo de conversión, que es lenta Entonces, XRuby y JRuby eligieron ir con velocidad e integración de Java sobre TCO y continuaciones (que básicamente tienen el mismo problema).
Esto se aplica a todas las implementaciones de Ruby que desean integrarse estrechamente con alguna plataforma host que no admita TCO de forma nativa. Por ejemplo, supongo que MacRuby tendrá el mismo problema.
Podría estar equivocado (por favor infórmeme si es así), pero dudo que TCO tenga algún sentido en los verdaderos lenguajes OO, ya que la llamada final debe ser capaz de reutilizar el marco de la pila de llamadas. Dado que con la vinculación tardía, no se conoce en tiempo de compilación qué método será invocado por el envío de un mensaje, parece difícil garantizarlo (tal vez con un JIT de retroalimentación de tipo u obligando a todos los implementadores de un mensaje a utilizar marcos de pila del mismo tamaño, o al restringir el TCO a autoenvíos del mismo mensaje ...). –
Esa es una gran respuesta. Esa información no se encuentra fácilmente a través de Google. Es interesante que yarv lo apoye. –
Damien, resulta que * TCO es realmente * * requerido para los verdaderos lenguajes OO: ver http://projectfortress.sun.com/Projects/Community/blog/ObjectOrientedTailRecursion. No se preocupe demasiado por las cosas del marco de pila: es perfectamente posible diseñar marcos de pila de manera sensata para que funcionen bien con TCO. –