La semantica di TeX (come linguaggio di programmazione) è mai stata formalizzata?


21

Mi sembra che il linguaggio macro utilizzato da può forse essere visto come una sorta di sistema di riscrittura dei termini o una sorta di linguaggio di programmazione con ambito call-by-name.TEX

Anche le moderne implementazioni della motore X (ad esempio) interpreta il codice in un modo abbastanza diretto e non sono a conoscenza di alcun tentativo di ottimizzazione dell'esecuzione (come possono fare i moderni interpreti di ottimizzazione). Tuttavia, elaborare passaggi di ottimizzazione corretti per un linguaggio comesarà molto difficile a causa dell '"azione a distanza" che possono avere le ridefinizioni delle macro e della capacità di ridefinire le macro chiamandole per nome.TEXXeTEXTEX

Quindi l'implementazione di un ipotetico interprete di ottimizzazione per suona in pratica un problema molto difficile ma anche molto utile, dato che è usato in matematica e scienze e i tempi di compilazione lenti sono un inconveniente noto del sistema. Si noti che la maggior parte del tempo è dedicata all'interpretazione del codice, non al calcolo della composizione effettiva, specialmente quando vengono utilizzati pacchetti pesanti dal punto di vista computazionale (come ).TEXTEXtikz

Forse una semantica formale per la lingua potrebbe essere un inizio per affrontare il problema. Quindi la semantica del linguaggio di programmazione mai stata formalizzata?TEX



Grazie! Sebbene non sia interessato a formalizzare la sintassi di TeX in una grammatica senza contesto, la risposta è interessante. Comunque penso che confonda un po 'i livelli. Le grammatiche non sono mai abbastanza per sapere se un pezzo di codice in qualsiasi lingua è ben formato o meno, perché sono necessari altri passaggi come il controllo del tipo o la ricerca delle variabili. Tuttavia, la maggior parte delle grammatiche linguistiche sono descritte con BNF in questi aspetti. Ad ogni modo, sono più interessato alla semantica del linguaggio macro, non alla grammatica.
gigabyte il

Ad essere onesti l'autore della risposta affronta questa preoccupazione nei commenti di altre risposte, il punto è che nel caso di TeX, l'analisi comporta una valutazione e quindi per sapere se un pezzo di codice è ben formato, potrebbe essere necessario valutare un pezzo di codice arbitrario . Questo è di nuovo sulla sintassi, comunque.
gigabyte il

In questo post di blog rjlipton.wordpress.com/2011/03/09/tex-is-great-what-is-tex , Lipton riferisce che Knuth non ha mai definito formalmente . TEX
Lamine,

Bene, l'unica cosa che si avvicina a ciò che suggerisci è initex, che è un "precompilatore", in pratica puoi fare in modo che TeX esegua determinate operazioni, quindi interromperne l'esecuzione, salvare lo stato corrente come "formato" ( file.fmt) che viene quindi caricato abbastanza veloce. Questo è in realtà quello che sta succedendo con LaTeX per sé: è costruita sopra nucleo TeX questo modo, TeX simile pianura, il contesto (anche se questo è un po 'più complicato), ecc
yo'

Risposte:


9

(Con le scuse per una lunga risposta che va in una direzione diversa dall'ambito del sito: francamente sono stato sorpreso di vedere la domanda qui in primo luogo ...)


TeX è stato progettato per la composizione, non per la programmazione; quindi, nella migliore delle ipotesi, è "strano" se considerato come un linguaggio di programmazione.

- Donald Knuth, tipografia digitale, pagina 235

Ho letto molto negli ultimi due anni sulla storia antica (circa 1977) di TeX e molto di ciò che Knuth ha scritto. La mia conclusione è che nel momento in cui parliamo di "TeX (come linguaggio di programmazione)" , qualcosa non va già.

Se guardiamo ai primi "documenti di progettazione" per TeX scritti prima (vedi TEXDR.AFTe TEX.ONE, pubblicati in Digital Typography ), è chiaro che Knuth stava progettando un sistema destinato principalmente a comporre The Art of Computer Programming (ha detto (ad esempio qui ) che gli utenti principali che aveva in mente erano se stesso e il suo segretario), con l'idea che, opportunamente modificato, potesse essere utile più in generale. Per salvare la digitazione, per le cose che uno ha dovuto fare ripetutamente (ad esempio ogni volta che TAOCP doveva includere una citazione di un autore, ti consigliamo di spostarti verticalmente di un certo importo, impostare un determinato tratto di linea, prendere un certo carattere, comporre il virgolette allineate a destra, seleziona un altro carattere, componi il nome dell'autore ...), c'erano macro.

Puoi immaginare il resto. Quello che abbiamo in TeX è un caso di "completamento accidentale di Turing" ( altro ), tranne per il fatto che è accaduto nel mezzo di una comunità (scienziati informatici e matematici, e DEK stesso deve anche "incolpare") che erano (purtroppo) troppo intelligente per ignorarlo. (La leggenda narra che Michael Spivak non aveva mai programmato prima di incontrare TeX, ma era così preso che ha finito per scrivere AMS-TeX, al momento uno dei set di macro più complicati esistenti.) Perché TeX è stato scritto per essere trasportabile su un gran numero di sistemi (che all'epoca era un grosso problema), c'era sempre la tentazione di fare tutto in TeX. Inoltre, a causa della sua esperienza nella scrittura di compilatori, Knuth ha scritto TeX come un compilatore, e occasionalmente lo ha descritto come uno, e se il programma che funziona sul tuo input è un "compilatore", allora sicuramente stai programmando, giusto?

Puoi leggere un po 'di più su come Knuth non avesse intenzione di eseguire alcuna programmazione in TeX e su come "inserisse molte delle funzionalità di programmazione di TeX solo dopo aver calciato e urlato", in questa risposta . Qualunque fossero le sue intenzioni, come ho detto, le persone hanno iniziato a capire come (ab) utilizzare il sistema macro TeX per realizzare prodigi sorprendenti di programmazione. Knuth lo ha trovato affascinante e (oltre ad aggiungere alcune funzionalità in TeX stesso) ne ha incluse alcune nell'Appendice D "Dirty Tricks" di The TeXbook, ma si scopre, nonostante il nome, che "nove esempi su dieci sono utilizzato nell'implementazione di LaTeX ”.

In altre parole: LaTeX, il sistema macro che Leslie Lamport ha scritto su TeX, come idea , è eccezionale. Creare documenti in modo semantico, strutturato e orientato all'uomo, piuttosto che (Knuth), il modo orientato alla pagina di TeX (o come lo chiamava Lamport, logico piuttosto che visivo ) è fantastico. Ma implementare qualcosa di così complicato come LaTeX usando le macro di TeX piuttosto che in un linguaggio di programmazione "corretto" è, a mio avviso e almeno se fosse stato fatto oggi, a metà strada tra un errore gigantesco e un atto di sfrenata perversità. Anche Knuth è scioccato dal fatto che le persone non si limitino a estendere il programma TeX invece di fare tutto nelle macro TeX.

Oggi ci sono modi molto migliori per fare "programmazione"; puoi usare un programma esterno in una delle molte lingue ampiamente disponibili sui computer della maggior parte delle persone, oppure puoi usare LuaTeX e programmare in Lua (e fare un lavoro migliore di quanto tu possa mai fare con le sole macro TeX, perché puoi manipolare strutture interne e algoritmi al giusto livello). E se lo fai bene, potresti avere programmi che funzionano meglio o più velocemente di quelli implementati nelle macro TeX.

Il compito di rendere più veloci i programmi in TeX è quasi divertente se visto in questa luce, e mi ricorda le ultime parole del documento che descrivono un altro "linguaggio" di programmazione "accidentalmente Turing completo": Tom Wildenhain, il delizioso " On the Turing Completeeness of MS PowerPoint ( video ) dell'anno scorso:

Mentre PPTXTM dimostra la possibilità teorica di sviluppo di PowerPoint, […]. È inoltre necessario lavorare nell'ottimizzazione delle applicazioni di PowerPoint. C'è un grande potenziale qui per sfruttare il buffering automatico di PowerPoint della diapositiva successiva, che attraverso un accurato posizionamento della diapositiva può essere utilizzato per aumentare notevolmente le prestazioni dell'applicazione.

L' aneddoto descritto da Lipton è illustrativo. Non solo non è mai esistita una semantica formale di TeX, ma è anche improbabile che ce ne sia una. È troppo "strano" un "linguaggio" per quello, e (come spero di aver spiegato sopra) non è nemmeno inteso come un linguaggio. Ad esempio, potresti pensare di scrivere macro come funzioni, ma introduce un singolo carattere randagio (anche uno spazio ) e TeX lo considera immediatamente come un'istruzione di composizione.

In breve: TeX ritorna alla composizione al più presto possibile e quando espande le macro lo fa a malincuore (impaziente di arrivare al suo "vero" lavoro di composizione), e queste espansioni possono esse stesse dipendere da centinaia di tipi di "stato" all'interno il programma TeX (i valori di parametri come \hsizeo \baselineskip, il contenuto di caselle e altri registri ...), motivo per cui qualsiasi semantica formale di TeX deve necessariamente essere qualcosa che tenga conto dell'intero stato del programma e di tutta la sua memoria, fino a quando finiscono con qualcosa come "il significato del codice TeX è qualunque cosa faccia TeX", in una forma più complessa del programma TeX stesso.


Così bene, (se ti ho convinto) TeX non era inteso come un linguaggio di programmazione e non funziona come quelli reali, non esiste una semantica formale e ci sono modi migliori per programmare oggi - ma tutto ciò non aiuta con il tuo domanda reale / problema, e cioè che, in pratica, molti documenti significato per l'elaborazione da TeX fanno uso complicato macro (come LaTeX e TikZ), edifici mozzafiato complessità mostruosa costruito su uno sopra l'altro. Come possiamo renderlo più veloce e ideare "passaggi di ottimizzazione"?

Non ci arriverai con la semantica formale IMO. Ci ho pensato di recente e di seguito sono riportati alcuni pensieri preliminari.

La mia impressione è che Knuth fosse uno degli esperti scrittori di compilatori negli anni '60 (ecco perché gli è stato chiesto di scrivere il libro dei compilatori trasformato in The Art of Computer Programming ), e TeX è (in molti modi) scritto come erano i compilatori scritto negli anni '70, diciamo. Le tecniche e il design del compilatore sono migliorati da allora, e così può essere il programma TeX. Ecco alcune cose che possono essere fatte, accelerando le cose:

  • In sostanza, TeX è scritto come una "routine interpretativa", in cui gli "occhi" e la "bocca" di TeX (le sue routine di input) forniscono istruzioni al suo "stomaco" (le sue routine semantiche), da eseguire una per una. (Puoi vedere un elenco nella parte 15 del programma TeX .) Ad esempio, quando gli occhi / la bocca di TeX incontrano \hfillo \hskipnel suo input, lo stomaco riceve un comando "hskip", su cui agisce. Questo è simile a quello che oggi si chiamano interpreti bytecode e potrebbe esserci un valore nel refactoring del programma TeX per emettere esplicitamente questi bytecode / codici operativi, in modo che possiamo essere in grado di utilizzare le tecniche di compilazione esistenti (oggi più convenzionali). O almeno memorizzali nella cache per evitare di ripetere il lavoro. Naturalmente ci sono molte sfide:

    • L'esecuzione di un comando nello "stomaco" di solito comporta ancora la lettura dell'input, ovvero il lavoro delle routine di input e delle routine semantiche non avviene in fasi separate. Ad esempio il comando "hskip", se fornito \hskip(anziché dire \hfill) invocherà la scan_gluelettura di una specifica di colla dall'input, che a sua volta può comportare l'espansione di macro e così via fino a quando non vengono trovati abbastanza token per la colla, lasciando lo stack di input in un stato sostanzialmente diverso.

    • Motori come eTeX e pdfTeX e XeTeX e LuaTeX introducono nuovi comandi e primitive (le primitive eTeX / pdfTex sono praticamente utilizzate da tutti nella pratica); dovrai supportarli anche tu, non solo quelli del programma TeX originale di Knuth.

  • Potremmo fare qualcosa come "esecuzione speculativa", elaborare paragrafi futuri (magari iniziando da checkpoint naturali come nuove sezioni o capitoli) in parallelo (usando più core), tenendo traccia di tutto lo stato interno di TeX che usano (dipendono) e lanciando via quel lavoro (e rifandolo) se in seguito scopriamo che un paragrafo precedente finisce per cambiare parte di quello stato. Al momento TeX funziona interamente in sequenza su 1 processore; l'hardware tipico si è spostato in una direzione diversa e sono disponibili più core.

  • Ancora più semplice, potremmo semplicemente memorizzare nella cache il lavoro (a quale stato TeX è stato effettuato l'accesso e modificato) da una determinata sezione del file di input. (Potremmo fare questa memorizzazione nella cache a livello dell'input - il risultato netto dell'espansione di tutte le macro - o al livello di quale gruppo di caselle è stato assemblato, o fino allo stato totale del programma.) Ad esempio il contenuto all'interno una \begin{tikzpicture} … \end{tikzpicture}è improbabile che dipenderà molto dallo stato TeX come la pagina contatore del numero, così quando abbiamo ricompilare il documento TeX possiamo semplicemente riutilizzare tutto il lavoro - se abbiamo tenuto traccia di informazioni sufficienti per sapere che è sicuro farlo. (Naturalmente TikZ in particolare ha modi di esternare questo e includere i risultati, ma l'idea è più generale.)

  • Possiamo usare tecniche (ad es. Quelle usate nella programmazione funzionale) per eseguire alcune elaborazioni TeX con "buchi" - ad es. Proprio ora, quando scrivi \ref{foo}in LaTeX per fare riferimento a un numero di sezione (diciamo futuro), funziona solo in due passaggi di compilazione: prima viene elaborato l'intero documento (tutti i paragrafi composti, float posizionati su pagine, ecc.) con i numeri di sezione scritti in un file ausiliario, quindi con un secondo passaggio tuttoil lavoro viene ripetuto, con il numero di sezione effettivamente disponibile questa volta. (Questo tipo di hack potrebbe essere stato inevitabile al momento, e so che l'impatto sul tempo di esecuzione è "solo un fattore costante", ma ...) Invece, se potessimo semplicemente elaborare il documento con un "buco" ( una casella con contenuti indeterminati ma con una larghezza stimata) rimasta per il numero di sezione, quindi alla fine dell'elaborazione del documento popolare la casella? (Sì, la nostra larghezza stimata potrebbe risultare errata e il paragrafo potrebbe dover essere rielaborato e, di conseguenza, anche la pagina, ma potremmo fare il lavoro, se necessario, o accettare, per la velocità, una modalità in cui consentiremo una larghezza errata per il numero della sezione.)

  • Tecniche simili possono funzionare per l'editing interattivo di un documento TeX: quando modifichi un paragrafo può essere elaborato "dal vivo", con i paragrafi futuri semplicemente spostati nella cambusa (diciamo). Sappiamo che è possibile, poiché esistono già implementazioni (commerciali) di TeX che lo fanno, ad esempio BaKoMaTeX e Texpad e le precedenti Textures . (Vedi il video sulla home page di BaKoMa-TeX e in modo simile a quello di TeXpad, ad esempio questo video - ho provato quest'ultimo ed era insopportabilmente difettoso in pratica.)

  • Da non sottovalutare: il valore di mostrare le cose all'utente, rendendo TeX più debuggabile. In questo momento, gli utenti vedono solo i loro input di TeX e non hanno idea esattamente di cosa sta lavorando TeX, ad esempio quanto tempo impiega a interrompere la linea per i paragrafi, o alla macro-espansione (e di quali macro), quali scatole sta assemblando e buttando via, quali speciali vengono scritti da quale pacchetto, ecc. Io (forse ottimisticamente) credo che esistano utenti che vorrebbero vedere queste informazioni e troverebbero utile, ad esempio, sapere se lo strano pacchetto che stanno usando per l'ombreggiatura le equazioni con una sfumatura sullo sfondo sono economiche (aggiungendo poco al tempo di elaborazione) o meno. Vedendo dove viene svolto un sacco di lavoro dispendioso, potrebbero buttarne via parte (almeno fino alla loro ultima stampa). (È un po 'come compilatori o altri strumenti che inseriscono informazioni di profilazione nei programmi.) Rendere TeX più trasparente e debuggabile può essere un enorme miglioramento dell'usabilità, per esempio. (TeX è già abbastanza user-friendly e debuggable per il suo tempo IMO se usiamo TeX per lo più semplice con pochissime macro, ma non con LaTeX o come la maggior parte degli utenti lo incontra oggi.)

Inoltre, qualsiasi lavoro futuro dovrebbe probabilmente prendere in considerazione (costruire) LuaTeX, che è la migliore modifica di TeX che abbiamo attualmente.

Tutti questi sono solo pensieri oziosi (non ne ho implementato nessuno, per conoscere lo sforzo richiesto o la velocità che avremmo guadagnato), ma spero che questo possa in qualche modo rispondere alla tua domanda o darti idee per direzioni future .


Sono sicuramente d'accordo con te sul fatto che la programmazione in TeX sia masochista, ma come hai detto, le persone lo fanno comunque e, come hai sottolineato, i vantaggi di una migliore strumentazione andrebbero maggiormente agli utenti. Nella seconda parte della tua risposta tocchi molte delle idee che avevo in mente prima di porre la domanda. Potrei aggiungere che a causa di \ widthof e simili, la conclusione di un ciclo potrebbe dipendere da tutti gli algoritmi di composizione e dalle definizioni dei caratteri. Quindi è davvero strano sì XD
gigabyte il

Questa risposta ha bisogno di una riscrittura importante (non ho avuto il tempo di scriverne una breve!), Ma per coincidenza, ho appena trovato questa citazione di Knuth in Coders at Work di Peter Seibel in risposta a una domanda sulla correttezza formale: “Oppure TeX, ad esempio, è un casino formale. Era inteso per uso umano, non per uso informatico. Definire cosa significa che TeX sia corretto sarebbe incomprensibile. Alcuni metodi per la semantica formale sono così complicati che nessuno può comprendere la definizione di correttezza . ”
ShreevatsaR

Quindi TeX è un linguaggio di programmazione, ma ho dovuto mettere queste funzioni a calci e urla. [...] In un certo senso, mi dispiace che ogni lingua sia universale perché saranno universali in un modo diverso. […] Stavo davvero pensando a TeX come a qualcosa che più programmava, meno faceva la sua vera missione di composizione. Quando ho inserito il calcolo dei numeri primi nel manuale di TeX, non pensavo a questo come al modo di usare TeX. Stavo pensando: "Oh, a proposito, guarda questo: i cani possono stare in piedi sulle zampe posteriori e TeX può calcolare i numeri primi".
ShreevatsaR,

Onestamente non vedo la ragione di Knuth per aggiungere funzionalità di programmazione a TeX "calciare e urlare". La programmazione TeX non viene utilizzata per eseguire calcoli arbitrari, ma per costruire astrazioni intorno ai problemi, spesso derivanti dalla stessa sintassi TeX, in modo che gli utenti possano utilizzarlo più efficacemente per la composizione. Quindi non sono d'accordo con Knuth che dice che più programmazione ci mette e meno farebbe la composizione. Forse se avesse accettato sin dall'inizio la necessità di una programmabilità generale avrebbe potuto trovare qualcosa di meglio. La stessa cosa è successa con il web e ora il mondo funziona su JavaScript.
gigabyte,

11

No, per quanto ne sappia, non c'è stato alcun lavoro sulla formalizzazione di TeX del tipo a cui sei interessato.

(Quello che segue è un commento soggettivo e personale). Penso che sia un'idea intrigante e ben posata, e la tua motivazione ad usarla per eseguire ottimizzazioni suona ragionevole - un'altra domanda correlata è se potresti definire un formato bytecode per accelerare l'interpretazione. D'altra parte, l'idea ha due aspetti negativi.

Innanzitutto, non mi è chiaro che esiste un grande potenziale di ottimizzazione (ad esempio, che tipo di trasformazioni di conservazione del programma si potrebbero eseguire per accelerare il calcolo?), In quanto la semantica del linguaggio potrebbe essere intimamente correlata all'analisi il flusso di caratteri, e quindi non molto accomodante per la progettazione di rappresentazioni intermedie di ottimizzazione.

In secondo luogo, la necessità di miglioramenti nella velocità di interpretazione di TeX non è ben stabilita: la velocità di costruzione della velocità batch è rimasta ragionevole grazie ai miglioramenti hardware. I casi in cui le accelerazioni potrebbero essere gradite sono pacchetti grafici complessi (la creazione di presentazioni con beamer può richiedere parecchio tempo per essere compilata), pacchetti che incorporano elaborati calcoli (ma quindi un'altra lingua potrebbe essere più appropriata) e casi d'uso che richiedono una ricostruzione rapida per un feedback immediato dell'utente (ma poi incrementalità, piuttosto che ottimizzazione, potrebbe essere il punto; una semantica formale aiuterebbe sicuramente anche la ragione delle implementazioni incrementali).

Vale a dire: sembra un argomento divertente e istruttivo, ma non mi è chiaro che le giustificazioni pratiche per fare il lavoro siano forti. Se qualcuno fosse interessato a farlo per curiosità, questa sembra un'avventura eccellente, ma per il resto potrebbero esserci altri modi per utilizzare lo stesso insieme di competenze il cui impatto sarebbe più ricercato dagli utenti finali.


Grazie. Come hai detto, la compilazione incrementale è forse più interessante dell'ottimizzazione qui, specialmente se pensiamo a come gli editor scarsamente possono attualmente integrarsi con la lingua
gigabyte

Un'altra applicazione correlata all'ottimizzazione è la pulizia automatica del codice, ad esempio la rimozione di inutili "\ expandafter" o simili.
gigabyte,

"pacchetto di grafica complessa" Naturalmente, se usi la grafica tikz o pgf, puoi sempre esternalizzarli e risparmiare molto tempo sulle build quando non cambiano (il che è molto simile alla compilazione incrementale, davvero).
JAB,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.