При формулировке ответа на другой вопрос SO я столкнулся с каким-то странным поведением относительно хвостовой рекурсии в Mathematica.
Документация Mathematica указывает, что оптимизация хвостового вызова может быть выполнено. Но мои собственные эксперименты дают противоречивые результаты. Контраст, например, следующие два выражения. Первый сбой ядра 7.0.1, предположительно из-за усталости:
(* warning: crashes the kernel! *)
Module[{f, n = 0},
f[x_] := (n += 1; f[x + 1]);
TimeConstrained[Block[{$RecursionLimit = Infinity}, f[0]], 300, n]
]
Второе завершается, появляется возможность использовать оптимизацию хвостового вызова для возврата значимого результата:
Module[{f, n = 0},
f[x_] := Null /; (n += 1; False);
f[x_] := f[x + 1];
TimeConstrained[Block[{$IterationLimit = Infinity}, f[0]], 300, n]
]
Оба выражения определяют хвостовую рекурсивную функцию f
. В случае первой функции Mathematica, по-видимому, считает наличие составного оператора достаточным, чтобы избежать любых шансов оптимизации хвостового вызова. Также обратите внимание, что первое выражение определяется $RecursionLimit
, а второе - $IterationLimit
- признаком того, что Mathematica обрабатывает два выражения по-разному. (Примечание: ответ SO, на который ссылается выше, имеет менее надуманную функцию, которая успешно использует оптимизацию хвостового вызова).
Итак, вопрос: кто-нибудь знает обстоятельства, при которых Mathematica выполняет оптимизацию хвостовых вызовов рекурсивных функций? Ссылка на окончательное утверждение в документации Mathematica или на другой материал WRI будет идеальной. Спекуляция также приветствуется.