Skip to content
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

Cross-compilare OCaml a Javascript #10

Open
tajmone opened this issue Jan 16, 2018 · 27 comments
Open

Cross-compilare OCaml a Javascript #10

tajmone opened this issue Jan 16, 2018 · 27 comments

Comments

@tajmone
Copy link
Collaborator

tajmone commented Jan 16, 2018

Ho rispulciato i miei appunti riguardo la cross-compilazione a Javascript. E, indovina un po'? OCaml è supportato.

Questa è la lista di compilatori OCaml 2 Javascript che ho trovato sul Wiki di CoffeeScript:

Name Description
Ocamljs OCaml to JS.
O’Browser OCaml bytecode interpreter in JS.
Js_of_ocaml OCaml bytecode to JS compiler.
Bucklescript OCaml to readable JS

Il potenziale direi che è enorme!

Dato che Polygen non si appoggia a librerie esterne, basterebbero poche modifiche per trasformarlo in una libreria, sia binaria che Javascript.

Una volta compilatolo in Javascript, esistono ulteriori strumenti per poterne fare sia un pacchetto NPM per Node.js (come libreria e come struemnto CLI 100% javascript), sia per renderlo utilizzabile tramite browser:

Questa presentazione a slide è un ottimo punto di partenza:

Che ne pensi?

Io credo che riscrivere tutto da zero sia un mega lavoraccio, perlopiù inutile. La cross-compilazione mi pare più fattibile e consentirebbe di preservare il codice attuale.

@tajmone
Copy link
Collaborator Author

tajmone commented Jan 16, 2018

Sto spulciando i progetti OCaml menzionati nella tabella; alcuni sono veri e propri backend per il compilatore OCaml, altri sono virtual machine che consentono di far girare codice oggetto OCaml nel browser.

Sono davvero progetti fantastici, e sembra potrebbero essere in grado di compilare PolyGen senza ulteriori strumenti.

Javascript è un linguaggio davvero performante, ed è molto più universale che non il Java (a mio avviso). Una volta creata la libreria di PolyGen (libPolyGen?), con una sua API, il resto sarebbe una passeggiata.

Le librerie statiche e dinamiche potrebbero essere incorporate in applicazioni di vario tipo, il che consentirebbe anche di implementare una nuova interfaccia da riga di comando in qualsiasi linguaggio (che so, per aggiungere nuove opzioni e funzionalità, filtri, ecc.).

La libreria in Javascript consentirebbe di utilizzare Polygen direttamente nel browser, buttando il carico di lavoro sul client e scavalcando la necessità di un server, interfacciamenti CGI, PHP, ecc. La pagina web si limiterebbe a fornire il sorgente javascript, ma siccome le risorse di calcolo passano al client, anche se 10.000 utenti in contemporanea continuassero a generare testo il server non consumerebbe alcuna risorsa.

@alvisespano
Copy link
Owner

alvisespano commented Jan 16, 2018 via email

@alvisespano
Copy link
Owner

alvisespano commented Jan 16, 2018 via email

@tajmone
Copy link
Collaborator Author

tajmone commented Jan 16, 2018

Di riscriverlo in javascript non ci penso neanche

scusa, devo essermi espresso male. Intendevo solo la cross compilazione di PolyGen come libreria accessible tramite API.

Il problema è che la cross-compilazione è una bestia strana: bisogna
scoprire COSA cross-compila e cosa produce in output. Se è in grado di
tradurre i binding a top level di un modulo ML in binding a top level js
allora direi che è meglio prima scrivere la libreria in OCaml (così il
refactoring ed il testing è fatto in linguaggio migliore) e poi la
tradurla;

Da quel che ho visto vi sono vari approcci e opzioni in merito. Credo che la libreria OCaml sia comunque la strada migliore, e forse la più facile. Purtoppo OCaml fa parte di una categoria di linguaggi che non conosco, e non posso esserti d'aiuto, se no mi ci sarei buttato. Presumo che, come nella maggior parte dei linguagi high level, si tratti solo di separare il codice che interfaccia alla riga di comando (opzioni, e varie) dal "motore" vero e proprio (lexer, parser, etc) così da rendere accessibili le funzioni di quest'ultimo tramite una API pubblica.

Infine, vorrei pensare ad ultimo aspetto: la mantenibilità ... se invece prediamo un'altra strada: continuiamo a mantenere ed upgradare polygen in OCaml ed introduciamo la cross-compilazione nel processo di building. In altre
parole: il programma (o libreria, o entrambi) rimane bello e pulito,
scritto in OCaml, e la versione js la generiamo a build time ogni volta.

Concordo, questa strada è l'unica che ha senso (e che avevo in mente). Inoltre, il gioco vale la candela solo questa cross compilazione è davvero un processo che si riduce a creare un makefile e che di tutto il resto si occupino i tool delegati al compito (se così non fosse, la mantenibilità andrebber a farsi friggere).

Per poter imboccare questa strada però occorre sapere come funziona la
cross compilazione ml-to-js. E quindi ritorniamo al punto di prima.

Su questo posso documentarmi, ma non conscendo OCaml al primo intoppo entrerò nel panico. Comunque, posso installare il tutto su Linux e sperimentare. Di sicuro la docuemntazione non manca per questi progetti, che sono poi solo tre dato che uno dei quattro linkati è fermo da otto anni.

C'è anche un'altra alternativa, sebbene meno realistica: potrei riscrivere
Polygen in Haskell

Haskell sta andando alla grande. Ma vale la pena riscrivere ciò che già funziona bene? Voglio dire, ok OCaml è un po' stagnante come linguaggio al momento, ma ho visto che è comunque mantenuto attivamente in alcune sue versioni, e su Linux sarà comunque disponibile senza problemi.

Si tratta però di lavoro più profondo ed intenso di quel "consolidamento"
che avevo/avevamo in mente: per quanto polygen sia già scritto, tradurlo a
mano significa riscriverlo secondo le convenzioni, gli standard e gli stili
imposti dal linguaggio target. E non possiamo scendere a compromessi di
qualità, altrimenti viene meno l'obiettivo primario del porting, ovvero la
mantenibilità.
Sì, insomma, è un lavoraccio pure questo alla fine della festa, e non sono
sicuro di aver voglia :P

Direi che è uno sbattone troppo grosso. Un conto è se tu avessi voglia di scrivere una nuova versione da zero, finalizzata al supporto Unicode e altre cose — fregandotene della retrocompatibiltà con le gramamtiche attuali. Ma se è solo per far girare le grammatich odierne, non ne vale la pena. In fondo si trova sempre il modo di farlo funzionare anche su Windows (che su Linux il problema neanche si pone). Secondo me anche fra 10 anni lo si potrà eseguire su un PC, d'altronde esistono emulatori MS-DOS, ZX-81, C-64, e via dicendo.

Però, se la cross compilazione fosse davvero roba da un click e vai ... allora sarebbe una manna dal cielo. E, poter far girare PolyGen nel browser sarebbe fico, e non credo che l'utente medio (con 8 o più Core a 64 bit) noterebbe problemi o differenze di performance.

javascript è anche il peggior linguaggio della storia
dell'umanità ... un linguaggio unsound.

Oltre ad essere brutto javascript è anche lento, non è vero che è
performante se paragonato ai linguaggi con un compilatore di qualità (come
C per esempio, o lo stesso OCaml).

Allo stato attuale, un sorgente Java o C# cross-compilato in Javascript girà a metà delle velocità rispetto a programma nel linguaggio originale. Direi che non è male. Però paragonare il linguaggio di scripting a uno studiato per la compilazione binaria non ha molto senso. Python è 13 volte più lento di un programma in C compilato, ma è normale che sia così dato che è un programma di scripting no?

Tuttavia - forse tu intendi - è performante in senso relativo, cioè, per
essere un pastrocchio interpretato che gira su un browser, javascript non è
male;

Io non uso Javascript nel browser, lo uso sul PC tramite Node.js, quindi senza limiti di sand-boxing. La cattiva reputazione di Javascript è dovuta al fatto che molti l'associano alla sandbox Javascript dei browser (e all'orribile periodo delle "guerre dei browser" e le scadenti implementazioni di Javascript).

Fuori dal browser, Javascript è performante per via delle funzioni asincrone. Chiaramente, come ogni linguaggio, vi sono settori in cui spicca di più e quelli in cui spicca di meno. Però un pastrocchio?

@alvisespano
Copy link
Owner

alvisespano commented Jan 17, 2018

Quando dico che Javascript è un brutto linguaggio non intendo dire che non sia utile o usabile - ogni giorno lo usano milioni di persone e mezzo web è scritto in javascript.
Quello che intendo è questo: ci sono linguaggi inventati da linguaggisti, con l'avvallo della comunità scientifica, che implementano o inventano feature avanzate studiate in letteratura; altri invece non sono così.
Non è una forma di snobismo: la scienza dei linguaggi esiste, come esista la fisica delle particelle o la chimica organica, e ha raggiunto dei traguardi nel corso dei decenni. I linguaggi che sono figli di questa scienza hanno delle proprietà matematiche importanti, come ad esempio la soundness, che garantisce che un programma che compila allora funziona per forza - nel senso che non può fallire a runtime, non nel senso che fa quello che il programmatore aveva in mente.
Tutti gli ML sono di questa categoria: sono linguaggi "d'autore", nel senso che sono fatti da scienziati (informatici) che hanno dedicato la vita allo studio ed all'approfondimento della materia.
Haskell è il top in questo: creato a mantenuto sostanzialmente dalla comunità scientifica dei linguaggi.
Idem per OCaml, Scala, Clojure ed altri (anche Lw, che ho creato io nel mio piccolo, appartiene a questa famiglia).

E poi ci sono i linguaggi cosiddetti industriali: C, C++, Java, C#, PHP, Python, Javascript, Go, Rush, Ruby e moltissimi altri, impossibili da elencare tutti.
Sono linguaggi più semplici, fatti da persone in gamba naturalmente, ma non sono conosciuti per le loro feature ground-breaking o per aver portato avanti il carretto della scienza dei linguaggi.
Sono linguaggi pratici, utili, usatissimi - che io stesso conosco molto bene e che uso regolarmente - ma non sono "il top possibile ad oggi" perché ignorano tutta una serie di traguardi formali raggiunti in letteratura e propongono feature arcinote.

Non c'è nessuna forma di aristocrazia in ciò che dico: è un dato di fatto riconosciuto da chi si occupa di linguaggi. Rispetto moltissimo l'autore di Python, per esempio, ma Python è un linguaggio che non ha inventato niente - solamente fa bene cose note da 40 anni. Ci sono dei meriti anche in questo, non fraintendermi! Ma OCaml o Haskell sono tutto un altro livello: è come paragonare una Lamborghini con una Golf.

Fatta questa doverosa premessa, Javascript è un linguaggetto creato da "mestieranti", non da esperti di linguaggi, che è diventato standard globale suo malgrado. Spesso accade che diventino mainstream cose che non dovrebbero diventarlo, dal punto di vista qualitativo. In particolare Javascript è un pasticcio di linguaggio: è totalmente unsound ed è molto facile scrivere programmi che non funzionano perché le scelte di design sono orientate allo scrivere poco ed al deploy facile, non alla robustezza, alla sicurezza del codice ed al riuso.

@iacopy
Copy link

iacopy commented Jan 21, 2018

E vai di Haskell allora :)

@pdonadeo
Copy link
Contributor

Forse potreste essere interessati al mio fork di Polygen: gira nel browser come libreria che, per ora, espone solo una funzione di generazione.

https://github.com/pdonadeo/Polygen

@tajmone
Copy link
Collaborator Author

tajmone commented Feb 15, 2021

@pdonadeo:

Forse potreste essere interessati al mio fork di Polygen: gira nel browser come libreria che, per ora, espone solo una funzione di generazione.

Grazie del link! Cercherò di aggiornare i vari Wiki per linkarlo, appena trovo il tempo.

@alvisespano
Copy link
Owner

alvisespano commented Feb 15, 2021

Grazie! Molto carino! Funziona come una unica funzione con una grammatica come unico argomento?
Ricordo che tanti anni fa l'aveva fatta anche Zeff (l'amico che fece il sito polygen.org originale) tipo nel 2003, poi nel 2007, poi nel 2010 e di nuovo nel 2011, finché si è rotto i coglioni perché ogni anno cambiavano le tecnologie web e bisognava rifare il wrapper da capo :D
Cmq apprezzo molto! Me ne intendo poco, ma credo che oggi le tecnologie web siano un pochino più stabili e di vita semi-lunga, speriamo :)

@pdonadeo
Copy link
Contributor

Sì è una unica funzione, esportata come Polygen.generate che ha come unico argomento una stringa con la grammatica.

Se interessa posso scrivere un minimo di documentazione su come compilare il progetto con un ambiente OCaml moderno. Penso che Polygen nel browser apra infinite possibilità :D

Questa è una micro demo.

cast-2021-02-13_14.59.15.mp4

@alvisespano
Copy link
Owner

Assolutamente Paolo! E' carinissimo e apre la porta, come dici tu, a infinite possibilità. Se hai voglia di scrivere un po' di doc, magari con la consulenza di @tajmone, sarebbe perfetto. Potremmo anche pensare di integrare il tuo wrapper web al polygen ufficiale, per esempio linkandolo ufficialmente e/o menzionandolo.

@tajmone
Copy link
Collaborator Author

tajmone commented Feb 15, 2021

Se hai voglia di scrivere un po' di doc, magari con la consulenza di @tajmone, sarebbe perfetto.

Concordo, la documentazione non è mai abbastanza né di intralcio, e sono disponibile.

Potremmo anche pensare di integrare il tuo wrapper web al polygen ufficiale, per esempio linkandolo ufficialmente e/o menzionandolo.

Non ho avuto modo di sbirciare ai sorgenti, quindi volevo capire: si tratta di una cross-compilazione da OCaml a JavaScript (WebASM, o simili)? In quel caso, si potrebbe pensare di aggiungerlo alla toolchain ufficiale, così le due applicazioni si aggiornano di pari passo.

Ma, anche se non fosse un caso di cross-compilazione, si potrebbe pensare di integrare la demo HTML (e quanto serve) nel repository ufficiale stesso, come esempio di utilizzo (specie, appunto, se buttiamo giù della documentazione).

Tra gli ovvi vantaggi, l'automazione dei test tramite servizi CI (GitHub Actions, Travis CI, Cilcle CI, o quant'altro) che potremmo eseguire a nostra discrezione ad ogni commit/PR, o prima di creare una nuova tagged release.

@tajmone tajmone reopened this Feb 15, 2021
@pdonadeo
Copy link
Contributor

Non ho avuto modo di sbirciare ai sorgenti, quindi volevo capire: si tratta di una cross-compilazione da OCaml a JavaScript (WebASM, o simili)? In quel caso, si potrebbe pensare di aggiungerlo alla toolchain ufficiale, così le due applicazioni si aggiornano di pari passo.

Si tratta di una cross compilazione ma i sorgenti non sono identici perché l'ultima release non compilava con la toolchain "ufficiale" OCaml, che non è basata su make ma usa dune.

Però concordo al 100% che sarebbe interessante includere tutto nello stesso repository. Ma dune è incompatibile con make nel senso che mette tutti gli artefatti (cm*) nella directory _build che gestisce per i fatti suoi. Il problema è che se trova degli artefatti fuori da _build si arrabbia e va in errore.

Ad ogni modo potrei:

  1. eliminare il makefile e gli altri file della toolchain classica;
  2. aggiungere un nuovo "main" solo per Javascript: deve essere per forza diverso dal main di Polygen perché questo è un programma, con una sua command line, che esegue una generazione mentre quella Javascript è una libreria che espone delle funzioni (in questo momento solo una), ma non fa niente. Il vero "main" lo deve scrivere il programmatore Javascript. A questo proposito La Cosa Giusta Da Fare ©® è estrarre da main tutto quello che si può fattorizzare per tenerlo identico tra programma e libreria e minimizzare le differenze.
  3. impostare la toolchain con dune che a quel punto può essere "istruito" per compilare sia il programma nativo sia la libreria JS.

Se questa strada vi sembra quella giusta nel fine settimana ci lavoro: cancello il mio repo attuale, che è un po' un pasticcio, faccio un nuovo fork, includo queste modifiche e faccio una regolare pull request.

@pdonadeo
Copy link
Contributor

pdonadeo commented Feb 15, 2021

Dimenticavo un "piccolo dettaglio": non ho la più pallida idea di come compilare Polygen sotto Windows né di come compilare qualsiasi cosa sotto Windows. Non uso Windows da tipo 20 anni. Io inizio con Linux, poi vediamo.

@lapo-luchini
Copy link

Se poi vogliamo aggiornare il sito per togliere la chiamata al binario* e lasciarla fare direttamente al client, fatemi un fischio. 😇

*: l'ho messo in una jail e non ho bisogno di compilarlo da quando il sito è su, ma se si può evitare una chiamata ad un binario da parte di PHP (che tra l'altro sembra non girare con la 7.0 e ho dovuto lasciare per ora alla 5.6), potrebbe essere una buona idea a prescindere… (o forse no: squadra vincente non si cambia?)

@tajmone
Copy link
Collaborator Author

tajmone commented Feb 16, 2021

@pdonadeo:

Si tratta di una cross compilazione ma i sorgenti non sono identici perché l'ultima release non compilava con la toolchain "ufficiale" OCaml, che non è basata su make ma usa dune.

Però concordo al 100% che sarebbe interessante includere tutto nello stesso repository. Ma dune è incompatibile con make nel senso che mette tutti gli artefatti (cm*) nella directory _build che gestisce per i fatti suoi. Il problema è che se trova degli artefatti fuori da _build si arrabbia e va in errore.

Se ci fosse un modo per far convivere le due build nello stesso repository sarebbe l'ideale.

Da una rapidissima scorsa, mi pare di capire che Dune potrebbe tranquillamente sostituire Make nel repository ufficiale, ed essere utilizzato per compilare sia i binari "classici" che per la cross-compilazione a JavaScript.

Ti risulta possibile farlo @pdonadeo?

Inoltre, sembra offrire funzionalità superiori a Make (non che io sia un fan di Make, anzi...), e sul sito ufficiale leggo inoltre:

About 40% of OPAM packages are built using Dune.

Ovviamente, sta ad Alvise decidere, ma secondo me sarebbe una buona mossa raggruppare più sottoprogetti Polygen possibili in un solo repository, anziché disperderli e diluirli. In fondo, la comunità di sviluppo di Polygen non è enorme, quindi ha senso unire gli sforzi. In questo caso specifico, dato che la base del codice condivisa è la medesima, ha ancora più senso e consentirebbe di unire gli sforzi manutentivi sotto un unico tetto.

  • aggiungere un nuovo "main" solo per Javascript: deve essere per forza diverso dal main di Polygen perché questo è un programma, con una sua command line, che esegue una generazione mentre quella Javascript è una libreria che espone delle funzioni (in questo momento solo una), ma non fa niente. Il vero "main" lo deve scrivere il programmatore Javascript. A questo proposito La Cosa Giusta Da Fare ©® è estrarre da main tutto quello che si può fattorizzare per tenerlo identico tra programma e libreria e minimizzare le differenze.

Questa operazione sarebbe utile in generale, non solo per la version JavaScript, dato che consentirebbe di usare Polygen come libreria (statica o dinamica) direttamente da altre applicazioni. Se si riuscisse ad aggiungere alle build la creazione di una libreria dinamica, risulterebbe estremamente facile integrarla in altri programmi, a prescindere dal linguaggio in cui sono scritti — specie su Windows, dove risulta particolarmente rognoso integrare librerie statiche creati in altri linguaggi, a causa dei disastri storici dei compilatori C della MS, incompatibilità delle ABI nel corso del tempo, ecc.

Ma quest'ultima operazione potrebbe richiedere un bel po' di lavoro di refactoring, e io non sono in grado di aiutare molto dato che non conosco OCaml, e quando venne creato il repository non riuscì neanche a trovare una versione del compilatore OCaml richiesta che funzionasse su Win 10.

@alvisespano, che ne pensi di queste proposte?

Da quando abbiamo creato i vari repository Polygen su GitHub qualche cosa si è mossa. Abbiamo ripubblicato e completato la documentazione ufficiale, tu hai ripulito i sorgenti per renderli utilizzabili con l'ultima versione OCaml, e non sono mancati vari progetti open source legati a Polygen.

Sono tutti segnali positivi che indicano che l'interesse per Polygen è ancora vivo. La creazione di una "libPolygen" sarebbe un ottimo passo avanti per l'integrazione di Polygen in vari applicativi, oltre che per poter cross-compilare la versione JavaScript.

@pdonadeo
Copy link
Contributor

Se ci fosse un modo per far convivere le due build nello stesso repository sarebbe l'ideale.

Temo sia impossibile. Ad ogni modo nel mio fork c'è già il nuovo build system che compila, per ora, solo il classico polygen e lo installa.

Step:

  1. installare opam: https://opam.ocaml.org/doc/Install.html
  2. clonare il mio repo: git clone --recursive [email protected]:pdonadeo/Polygen.git
  3. $ cd Polygen; opam install .

Questo funziona certamente sotto Linux con un ambiente "standard" di OCaml, ovvero installato con opam. Potrei scommettere che funziona anche su OSX senza nessuna modifica. Sotto Windows, come detto, non ne ho la minima idea 😅

Per quanto riguarda l'estrarre una libreria mi sembra un'ottima idea ma qualcuno (Alvise?) mi deve dare una mano perché non ho la minima idea di quali funzioni esporre.

@tajmone
Copy link
Collaborator Author

tajmone commented Feb 16, 2021

Se ci fosse un modo per far convivere le due build nello stesso repository sarebbe l'ideale.

Temo sia impossibile. Ad ogni modo nel mio fork c'è già il nuovo build system che compila, per ora, solo il classico polygen e lo installa.

Anche qualora il core di Polygen fosse spostato in un modulo independente? Nella maggior parte dei linguaggi questa operazione è fattibile, non capisco perché OCaml o i suoi strumenti dovrebbero impedirlo (ma, come già detto, non conosco OCaml).

Questo funziona certamente sotto Linux con un ambiente "standard" di OCaml, ovvero installato con opam. Potrei scommettere che funziona anche su OSX senza nessuna modifica. Sotto Windows, come detto, non ne ho la minima idea

Stando alla documentazione ufficiale di dune, il supporto cross-platform dovrebbe essere semplificato da dune stesso:

cross-platform: as long as your code is portable, dune will be able to cross-compile it (note that dune is designed internally to make this easy but the actual support is not implemented yet)

Però, visti tutti i problemi che riscontrammo all'epoca per imbastire una toolchain OCaml che funzionasse su Windows, non ci farei affidamento. Ad ogni modo, su Windows 10 si può sempre ripiegare su WSL che consente di eseguire un'istanza del Kernel Linux in sottofondo, e quindi cross-compilare per Windows mischiando strumenti puramente Linux e applicativi Windows (grazie al bridge tra Windows a WSL). Se ben ricordo, all'epoca dovemmo ricorrere a WSL per alcuni applicativi OCaml richiesti dagli editor (ma allora WSL era ancora agli albori, e pieno di bachi, mentre oggi WSL2 dispone di un vero e proprio Kernel Linux).


PS: @pdonadeo, ho aggiunto il link al tuo repository in entrambi i Wiki Polygen:

se dovessi mai chiudere il repository segnalamelo, o magari aggiorna le pagine dei Wiki tu stesso (dovrebbero essere editabili da chiunque).

@pdonadeo
Copy link
Contributor

pdonadeo commented Mar 7, 2021

Credo di essere ad un punto stabile. Quello che ho fatto è questo:

  1. prendere l'ultima versione stabile (1.0.6) di Polygen;
  2. disaccoppiare la libreria dall'eseguibile: la libreria Polygen_lib non è altro che l'insieme di tutti i moduli presenti (Prelude, Absyn, Check, eccetera) più 3 funzioni che ho estratto perché sono usate dal programma polygen. Ho dovuto fare qualche piccolissima modifica qua e là per sostituire le funzioni deprecate ed eliminare qualche warning, ma nulla di che;
  3. Esportare in Javascript 2 funzioni. Sono: pRNG_init (esportata come pRngInit) e generate (esportata con lo stesso nome). Tutto il resto della Polygen_lib non è accessibile in questo momento da Javascript, la cosa richiederebbe un lavoro lungo e noioso che non farò, ve lo dico subito.

L'effetto netto è questo: compilando ed installando il mio fork uno si trova installato il caro vecchio polygen, il programma, identico a com'era. Inoltre può scrivere un altro programma usando Polygen_lib.

Caricando il file .js ci si trova nel browser un oggetto Polygen con dentro la funzione per inizializzare la sequenza casuale e generate che ha due parametri: una grammatica ed un oggetto di configurazione contenente start e lbs, eventualmente vuoti.

const grammatica = "...";
let frase = Polygen.generate(grammatica, {});

Dentro frase c'è una stringa JS che può essere infilata nel Dom.

Se avete voglia di provare e vedere se vi piace queste sono le istruzioni:

  1. installare opam: questo è importante, opam è un componente imprescindibile nell'ecosistema OCaml di oggi
  2. git clone --recursive https://github.com/pdonadeo/Polygen.git
  3. cd Polygen/
  4. opam switch create ./ 4.11.2

L'ultimo step crea uno switch locale di opam, installa la versione 4.11.2 del compilatore, tutte le dipendeze di polygen e polygen stesso. Dopo che ha finito dovreste poter scrivere polygen ed ottenere:

$ polygen
Polygen (type 2) v1.0.6 build 20180122 - http://www.polygen.org
Manta/Spinning Kids alias Alvise Spano' anno MMII ac insequenti fecit.

usage: polygen [OPTION]... SOURCES...

 SOURCE     source file(s) providing grammar definition

 OPTION
  -eof STR  use string STR as end-of-file (default: STR = "\n")
  -help     display this help message
  -info     alias for '-S I'
  -l LABEL  add LABEL to initial active label environment
  -o DEST   output to DEST file
  -pedantic set warning level to maximum
  -pre      output preprocessed source grammar
  -seed N   pass unsigned integer N as random seed
  -S SYM    use SYM as starting non-terminal symbol (default: SYM = S)
  -t        check source grammar and output inferred global label groups
  -v        be verbose
  -X N      iterate generation for N times (default: N = 1)
  -W N      set warning pedantry at level N (default: N = 1)
  --help  Display this list of options

Se vi piace modifico il README con le istruzioni e faccio pull request.

@tassoman
Copy link

tassoman commented Aug 9, 2022

Non s'è mergiata poi questa issue? 😢

@pdonadeo
Copy link
Contributor

pdonadeo commented Aug 9, 2022

Non s'è mergiata poi questa issue? cry

Pare di no, e c'è pure una pull request.

@tajmone
Copy link
Collaborator Author

tajmone commented Aug 9, 2022

Non s'è mergiata poi questa issue?

@tassoman, questo Issue conteneva solo una proposta per un'eventuale transpilazione da OCaml a JS, ma nessun codice o implementazione di fatto.

Benché ritengo che la cosa sia fattibile, richiederebbe comunque parecchio lavoro in termini di ritrocchi al codice sorgente e alla toolchain (e un'approfondita conoscenza di OCaml, linguaggio che personalmente non conosco affatto).

@pdonadeo
Copy link
Contributor

pdonadeo commented Aug 9, 2022

@tajmone scusa ma ti sbagli: la patch è un porting completo di Polygen all'interno di un ecosistema relativamente recente di OCaml (4.11.2) con build system aggiornato, modifiche a tutti i sorgenti per adattamento alle nuove interfacce, eccetera.

E in più c'è la transpilazione in Javascript, perfettamente funzionante.

@tassoman
Copy link

tassoman commented Aug 9, 2022

Stavo pensando che forse, anziché andare a stravolgere tutto, si potrebbe comporre un micro servizio in un container che fa la stessa cosa (polygen.generate) tramite chiamata asincrona via http.

Stamattina ho scritto qualcosa, per ora è un obbrobrio... ma funziona. Il «trucco» sarebbe comporre da l'immagine ubuntu, che contiene il poly 1.0.6 nel repository ufficiale, senza stare a compilare da zero.
Di conseguenza servire tramite Python, che manda una chiamata di sistema al binario e restituisce l'output tramite apiflask

Però le due cose non si escludono, la libreria js potrebbe essere integrata direttamente nei progetti tramite node

@tajmone
Copy link
Collaborator Author

tajmone commented Aug 9, 2022

@tajmone scusa ma ti sbagli: la patch

Mi riferivo al fatto che si menzionava il merge di questo Issue:

Non s'è mergiata poi questa issue?

Questo Issue non può essere mergiato poiché non è un pull-request né contiene modifiche al codice.

Credo che la patch in questione sia il pull-request #22, e che quindi convenga sollecitare nei commenti della PR anziché qui per quanto riguarda la patch (autori diversi per l'uno e per l'altra) .

@pdonadeo
Copy link
Contributor

pdonadeo commented Aug 9, 2022

Stavo pensando che forse, anziché andare a stravolgere tutto, si potrebbe comporre un micro servizio in un container che fa la stessa cosa (polygen.generate) tramite chiamata asincrona via http.

Comunque sia la PR #22 non "sconvolge" niente: Polygen — allo stato attuale di questo repository — non compila nemmeno.

@tajmone
Copy link
Collaborator Author

tajmone commented Aug 9, 2022

Comunque sia la PR #22 non "sconvolge" niente: Polygen — allo stato attuale di questo repository — non compila nemmeno.

Sì, è un peccato che il progetto sia in stallo, e che la tua PR non sia stata integrata (un sacco di lavoro rimasto in sospeso).

Credo che allo stato attuale la cosa migliore sia spostare la discussione sulla PR #22 al fine di spronarne il merge — anche se Polygen non compila, la tua variante in JS compila, quindi integrare la PR mi sembra la cosa sensata.

Non ho la minima idea del perché quella PR non sia stata ancora integrata in oltre un anno, ma non risultano conflitti né impedimenti.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants