Domanda

Per definizione la parola homoiconic significa:

  

stessa rappresentazione di codice e dati

In LISP questo significa che si potrebbe avere un elenco citato e valutare, in modo (car list) sarebbe la funzione e (cdr list) gli argomenti. Questo può accadere in di compilazione o in fase di esecuzione, ma richiede un interprete.

E 'possibile che i linguaggi compilati senza un interprete di tempo di compilazione possono essere homoiconic pure? O è il concetto di homoiconicity limitato a interpreti?

È stato utile?

Soluzione

'Homoiconic' è una specie di un costrutto vaga. 'Codice è di dati' è un po 'più chiaro.

In ogni caso, la prima frase su Wikipedia per Homoiconic non è così male. Si dice che la lingua deve avere una rappresentazione di origine tramite le sue strutture di dati . Se dimentichiamo 'stringhe' la rappresentanza fonte (che è banale e non che utile avere un concetto utile 'homoiconic'), poi Lisp ha liste, simboli, numeri, stringhe, ecc che vengono utilizzati per rappresentare il codice sorgente. L'interfaccia della funzione EVAL determina il tipo di rappresentazione sorgente linguaggio sta lavorando. In questo caso, Lisp, non è stringhe. EVAL attende la solita varietà di strutture dati e le regole di valutazione di Lisp determinare che una stringa valuta se stessa (e quindi non sarà interpretato come espressione programma, ma i dati di stringa soli). Un numero valuta anche a se stesso. Un elenco (peccato 3.0) è un elenco di un simbolo e un numero. Le regole di valutazione dicono che questa lista con un simbolo che denota una funzione come il primo oggetto sarà valutata come applicazione funzioni. Ci sono alcune regole di valutazione di questo tipo per i dati, gli operatori speciali, applicazioni macro e applicazioni funzionali. Questo è tutto.

Per chiarire: in Lisp la funzione eval è definita su strutture di dati Lisp . Si aspetta una struttura di dati, lo valuta secondo le sue regole di valutazione e restituisce un risultato -. Ancora una volta con le sue strutture di dati

Questo corrisponde alla definizione di homoiconic: codice sorgente ha una rappresentazione nativa utilizzando i tipi di dati di Lisp

.

Ora, la parte interessante è questo: non importa come viene implementato EVAL . Tutto ciò che conta è che si accetta il codice sorgente utilizzando le strutture di dati Lisp, che esegue il codice e che restituisce un risultato.

è perfettamente legale che EVAL utilizza un compilatore .

(EVAL code)  =  (run (compile-expression code))

Ecco come diversi Lisp sistema di lavoro, alcuni non hanno nemmeno un interprete.

Quindi, 'Homoiconic' dice che il codice sorgente ha una rappresentazione dei dati. Non dice che in fase di esecuzione questo codice sorgente deve essere interpretata o che l'esecuzione è sulla base di questo codice sorgente.

Se il codice viene compilato, è necessario né il compilatore né un interprete in fase di esecuzione . Coloro che sarebbero necessari solo se il programma vuole eval o compilare il codice in fase di esecuzione -. Qualcosa che non è spesso necessario

Lisp fornisce anche una funzione primitiva LEGGI , che traduce una rappresentazione esterna (S-espressioni) di dati in una rappresentazione interna dei dati (dati Lisp). Così può anche essere utilizzato per tradurre una rappresentazione esterna di codice sorgente in una rappresentazione interna del codice sorgente. Lisp non usa un parser speciale per il codice sorgente -. Dal momento che il codice è dati, c'è di sola lettura

Altri suggerimenti

Sì. Lisp può essere compilato a un binario nativo

Mi sembra di essere una domanda strana:

In primo luogo, la parte homoiconic è l'interfaccia presentata al programmatore. Il punto di lingue è che essi astratto una funzionalità di livello inferiore che conserva la stessa semantica della presentazione di più alto livello (anche se un diverso mezzo).

punto la macchina-codice del DSM è un buon punto, ma a condizione che:

  1. La sintassi e la semantica presentati sono homoiconic
  2. La definizione di una maschera di livello inferiore (codice macchina o interpretato o altro) non rimuove qualsiasi semantica originali allora

Perché l'attuazione di livello inferiore importa qui?

Inoltre:

  

linguaggi compilati senza un interprete di tempo di compilazione

Senza un programma di interpretarlo, sarebbe richiesto di essere nativo della CPU, quindi, lingua madre del CPU sarebbe necessario per essere homoiconic (o VM in esecuzione il codice).

Lingue senza interpretazione in fase di compilazione ... sarebbe abbastanza vincolata ... come sarebbero non essere compilati a tutti .

Ma non sono un esperto, e forse manca il punto.

Nella forma più letterale, C è homoiconic. È possibile ottenere l'accesso alla rappresentazione di una funzione tramite &functionName ed eseguire dati utilizzando somePtrCastToFnPtr(SomeArgs). Tuttavia questo è a livello di codice macchina e senza un qualche tipo di supporto delle librerie troverete molto difficile lavorare. Una specie di compilatore integrabile (mi sembra di ricordare che LLVM può fare questo) lo renderebbe più pratica.

Lisp è normalmente compilato. Ci sono state le implementazioni con i compilatori JIT invece di interpreti.

Quindi, non è necessario avere un interprete (nel senso di "non un compilatore") per le lingue Codice-is-dati.

Codice macchina in sé è homoiconic, quindi sì.

I dati o le istruzioni sono solo una questione di semantica (e forse il segmento di memoria in cui esse si trovano).

Il problema è che un sacco di processori separati aree istruzioni e dati, e prevenire attivamente programmi da modificare il proprio codice. Questo tipo di codice usato per essere chiamato "Codice degenerata", e considerato una cosa molto brutta.

Gli interpreti (e VM) non hanno questo problema, come si può curare l'intero programma come dati, con il "codice" solo essere l'interprete.

Sì; non resta che attaccare una copia del compilatore nella language runtime. Scheme Chez è uno dei molti compilatori fini che fare proprio questo.

La compilazione è solo ottimizzato interpretazione. Un interprete prende un pezzo di dati che rappresentano il codice e poi "significa" che il codice: il significato del codice si trasforma in percorsi di esecuzione e flusso dei dati attraverso le viscere della dell'interprete. Un compilatore prende gli stessi dati, lo traduce in un'altra forma e poi lo passa ad un altro interprete:. Quello implementato in silicio (CPU) o forse un falso (macchina virtuale)

Questo il motivo per cui alcune implementazioni Lisp sono in grado di non avere interpreti del. La funzione EVAL può compilare il codice e poi diramare a esso. EVAL e compilare non devono avere distinte modalità di funzionamento. (Clozure, Corman Lisp, SBCL sono esempi di "solo" del compilatore Lisps.)

La parte dei dati in principio è la chiave per la lingua essendo homoiconic, non se l'esecuzione di codice è ottimizzato per la compilazione. "Codice è dati" " fonte è il codice di dati" non è "codice eseguibile è un dato". (Codice eseguibile Naturalmente è un dato, ma dai dati si intende la rappresentazione schiacciante preferita del codice che vogliamo manipolare.)

Lingue costruiti in cima (CLR .NET, JRE ect) VM possono utilizzare tecniche avanzate che consentono al codice di volo generazione. Uno di loro è IL tessitura. Anche se, non è chiaro come eval di di ECMAScript / Lisp / Scheme ect ma può ad un certo grado emulare un simile comportamento.

Per esempi controllare Castello DynamicProxy e per ulteriori esempio interattivo controllare LINQPad, F # Interactive, Scala interattivo.

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