Предотвращает ли JVM оптимизацию хвостовых вызовов?

90

Я видел эту цитату на вопрос: Какой хороший функциональный язык для создания веб-сервиса?

Scala, в частности, не поддерживает исключение хвостового вызова, кроме саморекурсивных функций, что ограничивает виды композиции, которые вы можете сделать (это фундаментальное ограничение JVM).

Это правда? Если да, то что это такое о JVM, которая создает это фундаментальное ограничение?

Теги:
jvm
tail-recursion

5 ответов

72
Лучший ответ

Это сообщение: Рекурсия или Итерация? может помочь.

Короче говоря, оптимизация хвостовых вызовов трудно сделать в JVM из-за модели безопасности и необходимость всегда иметь трассировку стека. Эти требования могут быть теоретически поддержаны, но для этого, вероятно, потребуется новый байт-код (см. неофициальное предложение John Rose).

В разделе всплывает ошибка Sun # 4726340, где заканчивается оценка (с 2002 года):

Я считаю, что это можно сделать, тем не менее, но это не маленькая задача.

В настоящее время в проекте Da Vinci Machine происходит некоторая работа. Статус подпроекта хвостового вызова указан как "proto 80%"; он вряд ли превратится в Java 7, но я думаю, что у него очень хороший шанс на Java 8.

  • 0
    Я не совсем следовал объяснениям. Я думал, что оптимизация хвостового вызова была осуществлена компилятором. Предполагая, что у вас есть функция, которую компилятор может оптимизировать с помощью хвостового вызова, вы также можете иметь эквивалентную нерекурсивную функцию, которая реализует ту же функциональность с использованием цикла, верно? Если это так, то не может это сделать компилятор. Я не в состоянии следить за зависимостью от JVM. Как это соотносится с компилятором Scheme, который генерировал собственный код i386?
  • 0
    Хорошо, только что видел ответ Джона ниже. Таким образом, дело не в том, что его нельзя реализовать, а в том, что его нельзя реализовать при надлежащей поддержке отладчика.
Показать ещё 5 комментариев
28

Основным ограничением является просто то, что JVM не предоставляет хвостовые вызовы в своем байтовом коде и, следовательно, нет прямого способа для языка, построенного на JVM, для предоставления самих вызовов вызовов. Есть обходные пути, которые могут достичь аналогичного эффекта (например, батут), но они приходят к серьезной стоимости ужасной производительности и запутыванию созданного промежуточного кода, что делает отладчик бесполезным.

Таким образом, JVM не может поддерживать языки функционального программирования производственного качества, пока Sun не реализует хвостовые вызовы в самом JVM. Они обсуждают это в течение многих лет, но я сомневаюсь, что они когда-либо будут реализовывать хвостовые звонки: это будет очень сложно, потому что они преждевременно оптимизировали свою виртуальную машину до внедрения таких базовых функций, а усилия Sun сильно ориентированы на динамические языки, а не на функциональные языки.

Следовательно, существует очень сильный аргумент в пользу того, что Scala не является реальным функциональным языком программирования: эти языки рассматривают хвостовые вызовы как важную функцию, поскольку схема была впервые введена более 30 лет назад.

  • 4
    Hence there is a very strong argument that Scala is not a real functional programming language - аргумент на самом деле довольно слабый. Конечно, tail calls [as] an essential feature , и хорошо, если базовое оборудование (или виртуальный компьютер) поддерживает его напрямую. Но это детали реализации.
  • 8
    @Ingo: только если вы не считаете, что переполнение стека в вашей программе во время выполнения замечено пользователем как серьезная проблема. Согласно его трекеру ошибок, даже сам компилятор Scala страдает от переполнения стека. Так что даже самые опытные разработчики Scala все еще ошибаются ...
Показать ещё 8 комментариев
20

Scala 2.7.x поддерживает оптимизацию хвостового вызова для саморекурсии (функция, вызывающая себя) конечных методов и локальных функций.

Scala 2.8 может поставляться с поддержкой библиотеки для батута, что является методом оптимизации взаимно-рекурсивных функций.

Много информации о состоянии рекурсии Scala можно найти в блоге Rich Dougherty.

  • 0
    Не могли бы вы обновить вопрос о текущем статусе scala?
  • 0
    @ om-nom-nom AFAIK, ничего не изменилось, ни на стороне Scala, ни на стороне JVM.
8

В дополнение к бумаге, связанной в Lambda The Ultimate (из ссылки, представленной выше), Джон Роуз из Sun еще несколько говорит о оптимизации хвостового вызова.

http://blogs.oracle.com/jrose/entry/tail_calls_in_the_vm

Я слышал, что он может быть реализован на JVM когда-нибудь. Поддержка Tail call, среди прочего, рассматривается на машине Da Vinci.

http://openjdk.java.net/projects/mlvm/

0

Все источники указывают на невозможность оптимизации JVM в случае хвостовой рекурсии, но при чтении Настройка производительности Java (2003, O ' reilly) Я нашел автора, утверждающего, что он может добиться большей производительности рекурсии за счет реализации хвостовой рекурсии.

Вы можете найти его заявку на стр. 212 (поиск "хвостовой рекурсии" должен быть вторым результатом). Что дает?

  • 0
    IBM поддерживает некоторую форму TCO в своей реализации JVM (в качестве оптимизации, поэтому никаких гарантий). Возможно, авторы настройки производительности Java думали, что эта функция будет в конечном итоге реализована всеми JVM. ibm.com/developerworks/java/library/j-diag8.html

Ещё вопросы

Сообщество Overcoder
Наверх
Меню