Domanda

C ++ è probabilmente il linguaggio più popolare per metaprogramming statico e Java non lo supporta .

Esistono altre lingue oltre a C ++ che supportano la programmazione generativa (programmi che creano programmi)?

È stato utile?

Soluzione

L'alternativa alla meta-programmazione in stile template è lo stile Macro che si vede in varie implementazioni Lisp. Suggerirei di scaricare On Lisp di Paul Graham e dare un'occhiata anche a Clojure se sei interessato a un Lisp con macro che gira su JVM.

Le macro in Lisp sono molto più potenti dello stile C / C ++ e costituiscono un linguaggio a sé stante - sono pensate per la meta-programmazione.

Altri suggerimenti

fammi elencare un alcuni dettagli importanti su come metaprogrammazione funziona in lisp (o schema o ardesia , oppure scegli la tua lingua preferita " dinamica "):

  • quando si esegue la metaprogrammazione in lisp, non è necessario gestire due lingue . il codice meta livello è scritto nella stessa lingua del codice livello oggetto che genera. la metaprogrammazione non si limita a due livelli ed è anche più facile per il cervello.
  • in lisp hai il compilatore disponibile in fase di esecuzione . in effetti la distinzione tempo di compilazione / tempo di esecuzione sembra molto artificiale lì ed è molto soggetta a dove posizioni il tuo punto di vista. in lisp con una semplice chiamata di funzione è possibile compilare funzioni in istruzioni macchina che è possibile utilizzare da allora in poi come oggetti di prima classe; cioè possono essere funzioni senza nome che è possibile mantenere in una variabile locale o una tabella hash globale, ecc ...
  • I
  • macro in lisp sono molto semplici: un mucchio di funzioni inserite in una tabella hash e fornite al compilatore. per ogni modulo che il compilatore sta per compilare, consulta quella tabella hash. se trova una funzione, la chiama in fase di compilazione con il modulo originale e al posto del modulo originale compila il modulo restituito da questa funzione. (modulo alcuni dettagli non importanti) quindi le macro lisp sono essenzialmente plugin per il compilatore .
  • la scrittura di una funzione lisp in lisp che valuta il codice lisp è di circa due pagine di codice (di solito si chiama eval ). in tale funzione hai tutto il potere di introdurre le nuove regole che desideri a livello meta. (per farlo funzionare velocemente ci vorrà un po 'di sforzo però ... più o meno come fare il bootstrap di una nuova lingua ... :)

esempi casuali di ciò che puoi implementare come libreria utente usando la metaprogrammazione lisp (questi sono esempi reali di librerie lisp comuni):

  • estendi la lingua con continuazioni delimitate (hu.dwim.delico)
  • implementa una macro js-to-lisp-rpc che puoi usare in javascript (che viene generato da lisp). si espande in una combinazione di codice js / lisp che pubblica automaticamente (nella richiesta http) tutte le variabili locali referenziate, le decodifica sul lato server, esegue il corpo del codice lisp sul server e restituisce il valore restituito a javascript lato.
  • aggiungi prolog come backtracking al linguaggio che si integra perfettamente con " normale " codice lisp (vedi urlatore)
  • una Estensione di template XML a lisp comune (include un esempio di < strong> macro del lettore che sono plugin per il parser lisp)
  • una tonnellata di piccoli DSL, come loop o iterate per un facile looping

La metaprogrammazione dei modelli è essenzialmente un abuso del meccanismo dei modelli. Quello che voglio dire è che ottieni fondamentalmente quello che ti aspetteresti da una caratteristica che era un effetto collaterale non pianificato --- è un casino e (anche se gli strumenti stanno migliorando) un vero dolore nel culo perché la lingua non lo fa supportarti nel farlo (dovrei notare che la mia esperienza con lo stato dell'arte su questo è obsoleta, dal momento che ho essenzialmente rinunciato all'approccio. Non ho sentito parlare di grandi passi fatti, però)

È stato un casino con questo nel '98 che mi ha spinto a cercare soluzioni migliori. Potevo scrivere sistemi utili che si basavano su di esso, ma erano infernali. Frugare alla fine mi ha portato al Common Lisp. Certo, il meccanismo del modello è Turing completo, ma anche in questo caso è intercalare.

Common Lisp esegue la metaprogrammazione `destra '. Hai la piena potenza della lingua disponibile mentre lo fai, nessuna sintassi speciale e poiché la lingua è molto dinamica puoi farci di più.

Ci sono altre opzioni ovviamente. Nessun altro linguaggio che ho usato fa metaprogrammazione meglio di Lisp, motivo per cui lo uso per il codice di ricerca. Ci sono molte ragioni per cui potresti voler provare qualcos'altro, ma saranno tutti dei compromessi. Puoi guardare Haskell / ML / OCaml ecc. Molti linguaggi funzionali hanno qualcosa che si avvicina al potere delle macro Lisp. Puoi trovare alcune cose mirate su .NET, ma sono tutte piuttosto marginali (in termini di base di utenti ecc.). Nessuno dei grandi attori delle lingue usate industrialmente ha qualcosa del genere, davvero.

Nemerle e Boo sono i miei preferiti personali per queste cose. Nemerle ha una sintassi macro molto elegante, nonostante la sua scarsa documentazione. La documentazione di Boo è eccellente ma le sue macro sono un po 'meno eleganti. Entrambi funzionano incredibilmente bene, tuttavia.

Entrambi si rivolgono a .NET, quindi possono interagire facilmente con C # e altri linguaggi .NET, anche con i binari Java, se si utilizza IKVM.

Modifica: per chiarire, intendo le macro nel senso Lisp della parola, non le macro del preprocessore di C. Questi consentono la definizione di nuova sintassi e metaprogrammazione pesante durante la compilazione. Ad esempio, Nemerle viene fornito con macro che convalideranno le query SQL sul server SQL in fase di compilazione.

Nim è un linguaggio di programmazione relativamente nuovo che ha un ampio supporto per la meta-programmazione statica e produce un codice compilato efficiente (tipo C ++).

http://nim-lang.org/

Supporta la valutazione della funzione di compilazione in tempo, trasformazioni di codice AST simili a lisp tramite macro, riflessione in fase di compilazione, tipi generici che possono essere parametrizzati con valori arbitrari e riscrittura dei termini che possono essere utilizzati per creare alto livello definito dall'utente ottimizzazioni di spioncino sensibili al tipo. È anche possibile eseguire programmi esterni durante il processo di compilazione che possono influenzare la generazione del codice. Ad esempio, considera di parlare con un server di database in esecuzione localmente al fine di verificare che la definizione ORM nel tuo codice (fornita tramite alcuni DSL) corrisponda allo schema del database.

Il " D " il linguaggio di programmazione è simile al C ++ ma ha un supporto di metaprogrammazione molto migliore. Ecco un esempio di ray-tracer scritto usando solo metaprogrammi in fase di compilazione:

Ctrace

Inoltre, esiste un ramo gcc chiamato " Concept GCC " che supporta la metaprogrammazione contratta che il C ++ non (almeno non ancora).

Concept GCC

Common Lisp supporta programmi che scrivono programmi in diversi modi.

1) Dati del programma e programma "albero di sintassi astratto" sono uniformi (espressioni S!)

2) defmacro

3) Macro Reader.

4) MOP

Di questi, il vero strabiliante è il MOP. Leggi " The Art of the Metaobject Protocol. & Quot; Cambierà le cose per te, lo prometto!

Ti consiglio Haskell . Ecco un paper che descrive le sue capacità di metaprogrammazione in fase di compilazione.

Molto lavoro in Haskell: DSL (Domain Specific Languages), specifiche eseguibili, trasformazione del programma, applicazione parziale, calcolo graduale. Pochi link per iniziare:

La famiglia di lingue ML è stata progettata appositamente per questo scopo. Una delle storie di successo più famose di OCaml è la FFTW per FFT ad alte prestazioni che è il codice C generato quasi interamente da un OCaml programma.

Saluti, Jon Harrop.

La maggior parte delle persone cerca di trovare un linguaggio che abbia "la riflessione finale" per l'autoispezione e qualcosa di simile a "quot" eval " per reificare il nuovo codice. Tali lingue sono difficili da trovare (essendo LISP un primo controesempio) e certamente non sono mainstream.

Ma un altro approccio consiste nell'utilizzare una serie di strumenti in grado di ispezionare, generare e manipolare il codice del programma. Il jackpot è un tale strumento focalizzato su Java. http://jackpot.netbeans.org/

Lo è il nostro toolkit di reingegnerizzazione del software DMS tale strumento, che funziona su C, C ++, C #, Java, COBOL, PHP, Javascript, Ada, Verilog, VHDL e varietà di altre lingue. (Utilizza front-end di qualità di produzione per consentirgli di leggere tutti questi linguaggi). Meglio, può farlo con più lingue nello stesso istante. Vedi http://www.semdesigns.com/Products/DMS/DMSToolkit.html

DMS ha successo perché fornisce un metodo regolare e un'infrastruttura di supporto per l'accesso completo alla struttura del programma come AST e, nella maggior parte dei casi, dati aggiuntivi come tabelle di simboli, informazioni sui tipi, controllo e analisi del flusso di dati, tutto ciò che è necessario per eseguire programmi sofisticati manipolazione.

'metaprogrammazione' è davvero un brutto nome per questa specifica funzione, almeno quando stai discutendo più di una lingua, poiché questa funzione è necessaria solo per una porzione ristretta di lingue che sono:

  • static
  • compilato in linguaggio macchina
  • fortemente ottimizzato per le prestazioni in fase di compilazione
  • estendibile con tipi di dati definiti dall'utente (OOP nel caso di C ++)
  • estremamente popolare

elimina una di queste e la "metaprogrammazione statica" non ha senso. pertanto, sarei sorpreso se qualsiasi linguaggio remoto tradizionale avesse qualcosa del genere, come capito su C ++.

ovviamente, i linguaggi dinamici e diversi linguaggi funzionali supportano concetti totalmente diversi che potrebbero anche essere chiamati metaprogrammazione.

Lisp supporta una forma di "metaprogrammazione", sebbene non nello stesso senso della metaprogrammazione di modelli C ++. Inoltre, il termine "statico" potrebbe significare cose diverse in questo contesto, ma Lisp supporta anche la digitazione statica, se è questo che intendi.

La meta-lingua (ML), ovviamente: http: // cs.anu.edu.au/student/comp8033/ml.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top