10

Per me, il Patten interprete suona molto come un anti-modello noto come decima regola di Greenspun:INTERPRETER è un anti-pattern?

Qualsiasi programma Fortran C sufficientemente complicato o contiene ad hoc, in modo informale specificato, piena di bachi, lenta attuazione di metà di Common Lisp.

Cioè, se è necessario utilizzare Interprete, è probabile che si crei qualcosa che sia lento, ad-hoc e scarsamente specificato. La soluzione giusta è usare la lingua giusta fin dall'inizio.

Oppure, in alternativa, incorporare nella propria applicazione un linguaggio ben noto e ben specificato, come Guile (lo schema GNU embeddable). Oppure usa Haskell come linguaggio specifico del dominio incorporato.

Ma non l'ho visto in pratica, quali sono le tue esperienze riguardo alla creazione di lingue incorporate? È una buona idea? È meglio che incorporare una lingua già esistente?

(io non sono particolarmente un fanboy Lisp. E 'bello, ma così di C e Haskell e pitone e un sacco di altre lingue.)

+3

C'è una scuola di pensiero che dice che lo Smalltalkers tra la Banda dei Quattro mettere il modello interprete nel libro come uno scherzo, solo per deridere il C++ folla. Sfortunatamente, il pubblico del C++ non ha capito la battuta, e ora siamo rimasti bloccati. (Lo scherzo è, naturalmente, che in Smalltalk il programmatore ottiene il pieno accesso runtime programmatico al compilatore e interprete, e quindi non c'è bisogno di qualcosa di simile al modello interprete.) –

risposta

31

Non c'è niente nel modello interprete che dice che deve essere un altro di programmazione la sintassi del linguaggio che stai interpretando. Se hai bisogno di analizzare una semplice espressione matematica, allora l'interprete è la cosa giusta.

Sapere quando usare un motivo è ciò che gli impedisce di essere un anti-pattern.

+9

ho quasi voglia di modificare questo post solo per aggiungere enfasi al l'ultima frase. Ma non credo sia possibile aggiungere tutta l'enfasi che ritengo abbia bisogno, quindi non mi preoccuperò. –

+0

È possibile votare per la mia risposta, che è essenzialmente solo l'ultima frase di questo: D –

+0

Il modello interprete è quella che l'età molto male (semplici espressioni matematiche tendono ad essere sempre più complessi fino ad avere il proprio Mathematica). Dovresti davvero pensare a questo rischio confrontando i benefici a breve termine con quelli a lungo termine. – coredump

0

Forse l'implementazione del compilatore Lisp include un esempio del pattern Interpreter.

Non penso che dovresti dire che "wheel", ad esempio, è un anti-pattern, anche se di solito dovresti comprare le ruote già pronte invece di reinventarle.

0

L'interprete è l'idea alla base del generatore di parser JavaCC. Penso che funzioni bene.

L'interprete è un modello GoF molto più rispettabile di Singleton. Questo è quello che deve essere votato al largo dell'isola. Forse anche Memento.

0

Uno dei motivi per cui XML è stato inventato è stato quello di salvarci da tutti gli interpreti EDI che scrivono; ma almeno lo scopo era ben definito e lo abbiamo fatto approssimativamente in modo equo (almeno sufficientemente). Almeno sono ancora abbastanza deluso da pensare che fosse la cosa giusta da fare.

Sembra che tu stia cercando di iniziare una nuova leggenda metropolitana? Sei congenitamente contrario alle lingue specifiche del dominio?

+0

"Sei congenitamente contrario alle lingue specifiche del dominio?" -- Affatto. In effetti, sto utilizzando lo schema incorporato per la mia applicazione con adattatore wiimote-to-XTest, con un set limitato di primitive nell'API del file di configurazione utente. Non sono sicuro di cosa fare del modello di progettazione di INTERPRETRO. // Forse mi è stato presentato per progettare schemi nel modo sbagliato: come una serie di regole severe (io chiamo questo "modello di camicia di forza di modelli di design") mentre in realtà sono solo un insieme di linee guida e di ispirazione (che Io chiamo "il modello ispiratore dei modelli di design"). –

14

Qualsiasi motivo di progettazione è un anti-modello se usato in modo improprio.

Buone usi del Interpreter Pattern:

  • compilatore Software
  • motore di valutazione di SQL
  • grafica ingresso calcolatrice parser
  • parser XML

Questi sono tutti i programmi che risolvono il problema di valutare parole in una lingua, whatever that language may be.

+1

"Motore di valutazione SQL" - Ermm ... no? AFAICT, lo schema di INTERPRETO dice di valutare l'albero dal basso verso l'alto. Un pianificatore di query modestamente sofisticato eseguirà le trasformazioni in query sufficientemente complicate che le velocizzano, a volte in modo drammatico. L'esecuzione di SQL con una valutazione dal basso non è la strada giusta da percorrere. (Allo stesso modo per i compilatori). Ma ... INTERPRETER sta parlando di qualsiasi tipo di attraversamento AST? Inoltre, non è il contrario/doppio/ortogonale al visitatore? –

-1

Generalmente le fasi di un compilatore/interprete assomiglia a questo:

  1. Sintassi
  2. Parse Albero
  3. AST
  4. Compile o interpretare

In Lisp, 1 e 2 sono combinati in 3.

Theref o è un po 'ovvio che i programmi complessi possano avere un linguaggio personalizzato incorporato in essi che è "un'implementazione lenta, ad hoc informata, corrotta da bug, di metà del Common Lisp".

Tuttavia, dovrei dire che la scrittura a mano degli alberi AST è sgradevole e non è la fine di tutto il linguaggio, non importa quanti Lips affermano di essere.

3

A un certo punto o un altro, un progetto probabilmente avrà bisogno di un sistema di configurazione. in un primo momento qualcosa di semplice è tutto ciò che è necessario, qualcosa come le coppie chiave-valore in modo che il sistema possa connettersi al database locale, o qualcosa di simile. Se questo è tutto ciò di cui si ha bisogno, è normale che sia sufficiente un semplice parser per un dialetto di INI o CSV e andare avanti. Ma man mano che il sistema cresce e matura, viene data maggiore importanza alla configurazione. Questo è normale e sano, refactoring funzionalità e responsabilità per il livello corretto di astrazione. Da qui non ci vorrà molto per gli sviluppatori o anche per gli utenti (ansiosi) di volere un linguaggio di configurazione più espressivo. Prima ancora che qualcuno se ne accorga, il sistema ha un linguaggio completo e integrato.

Questo è il modello di base di Greenspunning. Tutto è stato ben progettato fino all'ultimo bit, dove un linguaggio ad hoc è stato inserito nel regno del vero lavoro computazionale.

Qualsiasi sistema di dimensioni adeguate probabilmente deve contenere almeno metà del clisp.

Sapendo che in anticipo è un grande passo. Un modo molto conveniente per scrivere sistemi di grandi dimensioni è scegliere un linguaggio interpretativo piacevole e facilmente modificabile e scrivere il proprio sistema al suo interno. Questo è esattamente ciò che TCL è progettato per fare, ma in questi giorni è difficile ottenere qualcuno dietro un grande progetto in quella lingua. D'altra parte ci sono un sacco di altre lingue che ora offrono tutti questi vantaggi.

Il vantaggio di fare le cose in questo modo è il Active File Pattern. Le configurazioni semplici sono scritte in modo compatibile con un parser di lingua disponibile per il sistema. Poiché il file viene analizzato dal linguaggio, è possibile incorporare facilmente una logica più complessa.

Un esempio di questo in the wild è settings.py di django.Per qualche ragione, django non è molto intelligente nell'indovinare dove è installato il progetto django. Usando un'infarinatura di standard python nel file di configurazione, questo può essere gestito nel caso generale in modo portatile, che si adatta a quasi tutti gli utenti possibili. Nonostante ciò, la maggior parte del file settings.py ha l'aspetto di semplici vecchie coppie chiave = valore tipiche dei file di configurazione in stile .ini.

La relazione con il modello dell'interprete è che questi linguaggi maturi possono ottenere il modello a destra anche per alcuni usi patologici. Non appena sai che devi analizzare qualcosa, trova una buona ragione per non usare una lingua esistente per questo.

8

Tenere presente che il "modello di interprete" è uno schema di progettazione specifico in OOP.

Non ha nulla a che vedere con "Interpreti" o con i loro usi in generale.

2

Il modello dell'interprete non implica la scrittura di un linguaggio di script generale completo. Se ne hai bisogno, ovviamente sarebbe più sensato usare un linguaggio ben noto che le persone abbiano già scritto dei buoni libri (o meglio di tutti, per consentire all'utente di scegliere la lingua).

L'interprete modello è di più l'idea di persistente un oggetto grafico, ma la scelta di un formato di persistenza che è leggibile e umano modificabile (come 2 + 3 che rappresenta un oggetto Addition con puntatori a un paio di Integer oggetti). Anche se non viene mai esposto ai clienti come "lingua", continua a favorire il debug, il supporto, l'hacking in loco e così via. Altri esempi comuni sarebbero i linguaggi di query come HQL in [N] Hibernate: nessuna lingua esistente sarebbe stata altrettanto buona allo scopo di descrivere una query a quel livello di astrazione.

Come altri hanno suggerito, XML è comunemente usato come sintassi di base per questo (specialmente quando si concepisce il grafico dell'oggetto persistente come un "file di configurazione" e si vede anche XAML di Microsoft), ma in realtà è una scelta non ottimale . JSON in UTF-8 (o simile) sarebbe più pulito, più facile da analizzare, più leggibile e modificabile e quindi probabilmente migliore per la maggior parte delle applicazioni. Ma ci sono alcune grandi librerie parser leggere che prendono una descrizione sintattica simile a BNF e possono quindi analizzare il testo in una struttura walkable simile a DOM, il tutto in fase di runtime, quindi creare una sintassi sintattica molto specifica non è un problema.

0

Ovviamente non sei un "fanboy" Lisp, perché i ragazzi e le ragazze che si adattano a quella descrizione possono solitamente essere contati per sapere che il Lisp è un linguaggio compilato. Lisp apparve nel 1958. Il manuale Lisp 1 del 1961 descrive già la compilazione.

L'interpretazione è utile; ci dà semantica senza dover scrivere prima un compilatore. Questa semantica fornisce un modello di riferimento per la semantica compilata: i programmi idealmente, interpretati e compilati fanno la stessa cosa. Quando troviamo che non lo fanno, o lo risolvono, o in qualche modo delineano e giustificano la situazione.

L'interpretazione può essere utilizzata per avviare un sistema Lisp compilato senza richiedere un'implementazione Lisp esistente, ma utilizzando un altro linguaggio come C. Interpretazione evita la necessità di scrivere un compilatore Lisp nel linguaggio di avvio.

L'implementazione CLISP di ANSI Common Lisp ne è un buon esempio. Per compilare CLISP è necessario solo un compilatore C. Il compilatore Lisp di CLISP è scritto in Lisp. Quindi, ovviamente, non hai nulla con cui eseguire il compilatore. La soluzione è interpretare il compilatore utilizzando un interprete scritto in C.

Mentre è in esecuzione interpretato, il compilatore compila gran parte della libreria Lisp.Il risultato di ciò è ciò che CLISP chiama "immagine di memoria parzialmente compilata": un'immagine che contiene routine compilate, ma alcune routine interpretate. (Penso che il compilatore stesso sia ancora interpretato codice).

Questa immagine mezza compilato viene quindi utilizzato per compilare il codice rimanente, con conseguente nell'immagine completamente compilato.

Senza l'interprete, compilatore di CLISP potrebbe essere bootstrap solo insistendo su un'altra implementazione Lisp per essere installato prima. (Il modo in cui hai bisogno di un compilatore C per il GCC di boostrap). Oppure, il compilatore di CLISP dovrebbe essere scritto in C, in modo che il compilatore venga compilato usando il compilatore C esistente e quindi applicato al codice Lisp per compilarlo prima che possa essere eseguito.

Nessuno ha ragione di voler scrivere un compilatore Lisp in C e richiedere un'implementazione Lisp per creare un'implementazione Lisp è un grosso svantaggio in un mondo in cui il Lisp non è onnipresente. Cosa accadrebbe con il modello boostrapping Lisp-compiler-in-C è che il compilatore Lisp scritto in C sarebbe uno completamente minima e anche incompleta che emette il codice di scarsa qualità, solo abbastanza buono per iniziare la boostrapping, e un "vero" il compilatore sarebbe ancora scritto in Lisp.

Problemi correlati