LINUX.ORG.RU

История изменений

Исправление dave, (текущая версия) :

Часть 13.2. Английский текст про оптимизацию хвостового вызова корректен, но его можно истолковать неверно, что, кажется, и произошло в русском переводе. Есть очень распространенное заблуждение. Многие не понимают простой вещи. Хвостовой вызов действительно можно преобразовать в цикл, как это показано в PAIP, но это не значит, что это должен быть цикл самого языка высокого уровня. Но можно построить абстрактную машину, где любой хвостовой вызов фактически превращается в цикл.

Прямой хвостовой вызов обычно преобразуется в цикл самого языка. Так сделано в Scala и во многих компиляторах Common Lisp. Кажется, даже GCC умеет.

С косвенным хвостовым вызовом все сложнее, когда рекурсивный вызов передается через лямбду. Для F#, например, нужны извраты на уровне виртуальной машины CLR. Но упомянутый мною выше PAIP Питера Норвига показывает, что все могло бы быть гораздо проще, будь другим соглашение о вызовах функций.

Из общелиспов по моим наблюдениям и тестам только SBCL умеет оптимизировать косвенный хвостовой вызов.

Исходная версия dave, :

Часть 13.2. Английский текст про оптимизацию хвостового вызова корректен, но его можно истолковать неверно, что, кажется, и произошло в русском переводе. Есть очень распространенное заблуждение. Многие не понимают простой вещи. Хвостовой вызов действительно можно преобразовать в цикл, как это показано в PAIP, но это не значит, что это должен быть цикл самого языка высокого уровня. Но можно построить абстрактную машину, где любой хвостовой вызов фактически превращается в цикл.

Прямой хвостовой вызов обычно преобразуется в цикл самого языка. Так сделано в Scala и во многих компиляторах Common Lisp. Кажется, даже GCC умеет.

С косвенным хвостовым вызовом все сложнее, когда рекурсивный вызов передается через лямбду. Для F#, например, нужны извраты на уровне виртуальной машины CLR. Но упомянутый мною выше PAIP Питера Норвига показывает, что все могло бы быть гораздо проще, будь другим соглашение о вызовах функций.