La definizione di un combinatore Y in F # è
let rec y f x = f (y f) x
f prevede di avere come primo argomento un seguito per i sottoproblemi ricorsivi. Usando yf come continuazione, vediamo che f verrà applicato alle chiamate successive mentre possiamo svilupparci
let y f x = f (y f) x = f (f (y f)) x = f (f (f (y f))) x etc...
Il problema è che, a priori, questo schema preclude l'uso di qualsiasi ottimizzazione di coda: in effetti, potrebbe esserci qualche operazione in sospeso nelle f, nel qual caso non possiamo semplicemente mutare il frame dello stack locale associato a f.
Così :
- da un lato, l'uso del combinatore Y richiede una continuazione esplicita diversa rispetto alla funzione stessa.
- sull'altro per applicare il TCO, vorremmo non avere alcuna operazione in sospeso in f e chiamare solo f stesso.
Conosci un modo per riconciliare quei due? Come una Y con trucco accumulatore o una Y con trucco CPS? O un argomento che dimostra che non è possibile farlo?
f. Possiamo vedere che ypotrebbe richiamare fcon un thunk (y f), ma come dici tu fpotresti avere qualche operazione in sospeso. Penso che sarebbe interessante sapere se esiste un combinatore separato che è più amichevole per le code. Mi chiedo se questa domanda attirerebbe maggiormente l'attenzione sul sito CS Stackexchange?