Non l'ho usato ma un message on the Caml Groups la settimana scorsa menziona Mascot. Sembra essere quello che stai cercando. Non sono sicuro dei criteri di ricorsione della coda; l'autore del progetto sopra non ne parla, ma menziona le funzionalità del plugin.
In alternativa, la compilazione con -dlinear
(per ocamlopt[.opt]
) produce un codice linearizzato che indica se la funzione è una coda. -annot
produce anche informazioni di coda, ma non riesco a trovare un riferimento a parte lo changelog (è stato aggiunto in 3.11.0). In che modo viene codificato il tail-call, non fa il contrario, tagga le chiamate non tail (o forse c'è un modo?). Di seguito è riportato un esempio di output per una funzione chiamata sum
,
let rec sum a = function
| x when x = 0 -> a
| x -> sum (a+1) (x-1)
produce (tra molto di più in uscita),
*** 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]
penso che l'esperienza sta per essere la soluzione migliore però. Guarda attraverso alcuni progetti popolari (Batteries, ad esempio) per avere un'idea dello stile e delle convenzioni tipiche. Non credo che un plugin possa aiutarti a chiamare le variabili dell'accumulatore acc
o le continuazioni cont
.