Я не использовал его, а message on the Caml Groups на прошлой неделе упоминает Mascot. Это похоже на то, что вам нужно. Я не уверен в критериях хвостовой рекурсии; автор вышеупомянутого проекта не упоминает их, но упоминает возможности плагина.
В качестве альтернативы, скомпилирование с -dlinear
(для ocamlopt[.opt]
) приведет к линеаризованному коду, который упоминает, является ли функция хвостовым вызовом. -annot
также дает информацию о вызове хвоста, но я не могу найти ссылку в стороне от changelog (он был добавлен в 3.11.0). Каким образом он выполняет теги tail-calls, он не выполняет обратные теги non-tail (или, может быть, есть способ?). Ниже приведен пример вывода для вызова функции sum
,
let rec sum a = function
| x when x = 0 -> a
| x -> sum (a+1) (x-1)
производит (среди гораздо большей производительности),
*** Linearized code
camlTail__sum_58:
if x/30[%rbx] !=s 1 goto L100
return R/0[%rax]
L100:
I/31[%rbx] := I/31[%rbx] + -2
I/32[%rax] := I/32[%rax] + 2
tailcall "camlTail__sum_58" R/0[%rax] R/1[%rbx]
Я думаю, что опыт будет вашим лучшим выбором, хотя. Просмотрите некоторые популярные проекты (например, Batteries), чтобы почувствовать стиль и типичные соглашения. Я не думаю, что плагин поможет вам назвать ваши переменные аккумулятора acc
или продолжениями cont
.