-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactoring, updating code to latest OCaml and build system and Javascript cross compiling #22
Conversation
Ho scritto anche un po' di documentazione su come fare la build da zero e come usare la libreria nel browser. |
Ottimo grazie! |
Co-authored-by: Kate <kit.ty.kate@disroot.org>
@alvisespano, c'è qualche ragione per cui questa PR non è stata mergiata nel progetto? Come puoi vedere dalla discussione in #10, l'interesse per la transpilazione a JS è ancora vivo. |
Sto usando la build JS da qualche mese con successo, unica cosa, con una grammatica un po' complessa (ma nulla di esagerato) ogni tanto scoppia in Firefox con un "Internal Error: too much recursion". Ho visto che js_of_ocaml di default gestisce solo alcuni casi "semplici" di tail call optimization (https://ocsigen.org/js_of_ocaml/latest/manual/tailcall), mentre gestisce TCO "completa" con
e in effetti pare risolvere il mio problema. Non ho notato particolari rallentamenti o altri problemi, per cui credo che potrebbe essere cosa buona integrarlo nella MR? |
Done! |
Bravi! Sicuramente un po' di tail recursion diminuisce l'uso dello stack. Il motivo per cui crashava la versione in JS è senz'altro dovuto ad uno stack overflow causato da ricorsioni grosse in caso di produzioni grammaticali complessamente innestate. E' la natura del polygen. Forse in JS si può in qualche modo specificare la grandezza dello stack di un processo; non lo so. Cmq la soluzione della tail recursion è valida ma empirica: potrebbero ancora esserci casi di stack overflow. Pensaci/vedi tu. Ad ogni modo io integrerei la cosa nella MR. @tajmone che dici? |
Sì in realtà poi è saltato fuori che c'era un errore nella mia grammatica: il cambiamento ha spostato il problema un po' più in là, ma comunque in alcuni casi scoppiava (in questo caso con Out of memory invece di Too much recursion chiaremente) 😓 Trovato e sistemato l'errore lato mio, funziona in entrambi i casi. Sarei comunque per tenere il cambiamento, visto che alla fine non sembra far male e in casi di grammatiche complesse dovrebbe dare una mano. In ogni caso, anche al di là di quest'ultima modifica, il lavoro di Paolo direi che funziona benone, secondo me questa MR merita assolutamente di essere integrata. |
Polygen di per sé non dispone di un meccanismo di controllo per evitare uno stack eccessivo? che so, tipo un numero fisso di recursioni massime? Non conosco ML/OCaml, ma avrei dato per scontato che il compilatore ottimizasse le tail-recursion. Cosa intendi esattamente per «integrare la cosa nella M.R.»? — (MR = main release?) |
OCaml ottimizza la tail-recursion, bisogna vedere se Polygen fa chiamate in coda o no 😄
MR = Merge Request. Quasi 3 anni fa ho fatto un po' di lavoro su Polygen e ho mandato una merge request, ovvero la richiesta di includere i miei commit nel repository ufficiale: Non è mai stato fatto il merge. @cvtsi2sd suggeriva di aggiungere alla mia merge request anche l'ultima piccola modifica per svecchiare ulteriormente il progetto, rendendolo compatibile con le ultime versioni dell'ecosistema. Cosa che ho fatto, sperando che prima o poi venga fatto il merge 😄 |
Precisazione: la cosa che avevo letto e riportato prima dalla documentazione di js_of_ocaml è che la sua implementazione di VM OCaml non è in grado di fare tail call optimization in tutti i casi nella modalità di default, e che per avere ottimizzazione completa bisogna impostare il flag che dicevo sopra, che però non è abilitato di default perché apparentemente genera codice meno leggibile (??? è comunque assolutamente illeggibile ???) e leggermente meno performante in alcuni casi. Va detto comunque che appunto il problema che avevo avuto io era ricorsione sostanzialmente infinita nella mia grammatica, e che quindi il cambio di questa impostazione era un palliativo. Da quel che ho visto comunque Polygen non ha check espliciti rispetto a questo problema—se la grammatica è definita con una ricorsione infinita, polygen scoppia per stack overflow anche nella versione compilata in maniera "classica" (non-JS). Oltre al massimo numero di iterazioni (che alla fine risolverebbe il problema all'atto pratico), credo che sarebbe comunque possibile scrivere un check che faccia una verifica formale per fare un detect a priori di questo problema (esplodo tutte le sottoproduzioni, segno come "buone" quelle terminali e le tiro fuori dal pool; poi considero quelle che rimangono, e se hanno almeno una probabilità di risolversi su un terminale, sono buone anche loro e le tiro fuori dal pool; avanti così finché o non rimane più niente, e allora la grammatica in blocco è buona, oppure ho fatto un'iterazione in cui non ho tirato via nulla, e in questo caso vuol dire che c'è possibilità di loop infiniti). In ogni caso, non è questo il tema di questa merge request, che sia inclusa o non inclusa quest'ultima modifica non fa particolare differenza; l'importante è che venga mergiata nel repo ufficiale in modo da poter buildare il Polygen in ambiente "moderno", e da poterlo usare anche in ambito web tramite la versione Javascript che viene generata. |
No, non c'è, però attenzione: c'è un checker (che è una specie di type checker, ma non controlla tipi, controlla altre proprietà statiche della grammatica) che controlla loop infiniti e terminabilità. Quindi i loop davvero infiniti vengono scartati dal checker.
Certo che lo fa. Ma non tutte le ricorsioni sono tail-recursive. Il codice del polygen è pieno di ricorsioni di un sacco di tipi: alcune sono tail, altre no.
Ho visto che gli altri usavano questo acronimo ed ho pensato fosse standard :) Ho intuito che significa main release; ma forse intendono il main branch :) |
Non conosco js_of_ocaml, ma se stiamo parlando della vm di runtime di Ocaml allora il problema è quello.
Sì che ce li ha: ha un checker che agisce PRIMA della riduzione della grammatica ad una stringa e che controlla alcune proprietà di terminabilità. al massimo numero di iterazioni (che alla fine risolverebbe il problema all'atto pratico), credo che sarebbe comunque possibile scrivere un check che faccia una verifica formale per fare un detect a priori di questo problema (esplodo tutte le sottoproduzioni, segno come "buone" quelle terminali e le tiro fuori dal pool; poi considero quelle che rimangono, e se hanno almeno una probabilità di risolversi su un terminale, sono buone anche loro e le tiro fuori dal pool; avanti così finché o non rimane più niente, e allora la grammatica in blocco è buona, oppure ho fatto un'iterazione in cui non ho tirato via nulla, e in questo caso vuol dire che c'è possibilità di loop infiniti). E' esattamente così. Per le grammatiche di tipo 2 la terminazione è decidibile.
Infatti, non è questo il tema. Chiedo scusa per aver ignorato le richieste di merge (mea culpa, non seguo molto e me le sono perse). Se posso chiedere, volendo ricapitolare in poche parole, cosa c'è di nuovo in questa nuova versione che dovremmo mergiare? |
Grazie per le delucidazioni. Io sono favorevole al mege — ma già lo era sin dall'inizio. Credo sia importante che il progetto si evolva, foss'anche "lateralemente", come in questo in caso tramite transpilazione ad altri linguaggi e/o macchine virtuali. Soprattutto, sarebbe importante fare in modo che compilare Polygen in OCaml moderno diventi un'operazione facile — se ben ricordo, al tempo in cui mettemo mano al repository la situazione era abbastanza complicata sul versante MS Windows, e all'epoca WSL era ancora sperimentale — oggi invece WSL2 è stabile, e offre un vero kernel linux su sistemi Windows moderni. |
No description provided.