Domanda

Domanda semplice gente:Faccio un sacco di programmazione (professionale e personale) in linguaggi compilati come C++/Java e linguaggi interpretati come Python/Javascript.Personalmente trovo che il mio codice è quasi sempre più robusto quando I programmi in linguaggi tipizzati in modo statico.Tuttavia, quasi ogni linguaggio interpretato incontro utilizza la tipizzazione dinamica (PHP, Perl, Python, etc.).Io so perché i linguaggi compilati utilizzare la tipizzazione statica (la maggior parte del tempo), ma io non riesco a capire l'avversione per la tipizzazione statica in linguaggio interpretato design.

Perché la ripida scollegare?È parte della natura di linguaggi interpretati?OOP?

È stato utile?

Soluzione

Domanda interessante. A proposito, io sono l'autore / manutentore di PHC (compilatore per PHP), e sto facendo il mio dottorato di ricerca su compilatori per i linguaggi dinamici , quindi spero di poter offrire alcuni spunti.

Credo che ci sia un presupposto errato qui. Gli autori di PHP, Perl, Python, Ruby, Lua, ecc non ha progettato "linguaggi interpretati", hanno progettato linguaggi dinamici, e li implementate utilizzando interpreti. Hanno fatto questo perché gli interpreti sono molto molto più facile scrivere di compilatori.

prima implementazione di Java è stato interpretato, ed è un linguaggio a tipizzazione statica. Interpreti esistono per linguaggi statici: Haskell e OCaml entrambi hanno gli interpreti, e non vi era un interprete popolare per C, ma che era molto tempo fa. Sono popolari perché permettono un REPL , che può rendere lo sviluppo più facile.

Detto questo, c'è un'avversione per tipizzazione statica nella comunità di linguaggio dinamico, come ci si aspetterebbe. Essi credono che i sistemi di tipo statico forniti da C, C ++ e Java sono verbose, e non vale la pena. Penso che sono d'accordo con questo in una certa misura. Programmazione in Python è molto più divertente di C ++.

Per affrontare i punti degli altri:

  • dlamblin dice : "non ho mai sentito fortemente che ci fosse qualcosa di speciale compilation vs interpretazione che ha suggerito dinamica nel tipizzazione statica." Beh, sei molto sbagliato lì. Compilazione di linguaggi dinamici è molto difficile. V'è in gran parte la dichiarazione eval da considerare, che è ampiamente utilizzato in Javascript e Ruby. PHC compila PHP ahead-of-time, ma abbiamo ancora bisogno di un interprete run-time per gestire evals. eval inoltre, non può essere analizzato staticamente in un compilatore ottimizzato, se c'è una fresco tecnica se non avete bisogno di solidità.

  • Per la risposta di damblin a Andrew Hare : si potrebbe, naturalmente, eseguire l'analisi statica in un interprete, e di trovare errori di prima run-time, che è esattamente ciò ghci Haskell fa. Mi aspetto che lo stile di interprete utilizzato in linguaggi funzionali richiede questo. dlamblin è, naturalmente, il diritto di dire che l'analisi non fa parte di interpretazione.

  • Andrew Hare risposta si basa sulla interroganti presupposto sbagliato, e allo stesso modo ha cose nel modo sbagliato. Tuttavia, egli pone una domanda interessante: "quanto sia difficile è l'analisi statica di linguaggi dinamici?". Molto, molto difficile. In sostanza, si otterrà un dottorato di ricerca per descrivere come funziona, che è esattamente quello che sto facendo. Si veda anche il punto precedente.

  • La risposta più corretta finora è quello di Ivo Wetzel . Tuttavia, i punti che descrive possono essere gestite a run-time in un compilatore, ed esistono molti compilatori per Lisp e Scheme che ha questo tipo di binding dinamico. Ma, sì, la sua ingannevole.

Altri suggerimenti

I linguaggi interpretati utilizzare la tipizzazione dinamica perché non c'è passaggio di compilazione in cui fare l'analisi statica. linguaggi compilati fanno analisi statica al momento della compilazione che significa che eventuali errori di tipo sono segnalati per lo sviluppatore mentre lavorano.

E 'più facile capire se si considera che un linguaggio a tipizzazione statica ha un compilatore che applica le regole di tipo al di fuori del contesto di esecuzione. linguaggi interpretati non vengono mai analizzati in modo staticamente regole di tipo devono essere applicate dall'interprete nel contesto di esecuzione.

Credo che sia a causa della natura dei linguaggi interpretati, vogliono essere dinamici, in modo da poter cambiare le cose in fase di esecuzione. A causa di questo un compilatore non sa esattamente qual è lo stato del programma dopo la successiva riga di codice è stato excecuted.

Immaginate il seguente scenario (in Python):

import random
foo = 1

def doSomeStuffWithFoo():
    global foo
    foo = random.randint(0, 1)

def asign():
    global foo
    if foo == 1:
        return 20
    else:
        return "Test"


def toBeStaticallyAnalyzed():
    myValue = asign()

    # A "Compiler" may throw an error here because foo == 0, but at runtime foo maybe 1, so the compiler would be wrong with its assumption
    myValue += 20


doSomeStuffWithFoo() # Foo could be 1 or 0 now... or 4 ;)
toBeStaticallyAnalyzed()

Come si può vedere si spera, un compilatore non avrebbe alcun senso in questa situazione. Acutally potrebbe mettere in guardia circa la possibilità che "myValue" forse qualcosa di diverso da un numero. Ma poi in JavaScript, che verrebbe a mancare, perché se "myValue" è una stringa, 20 sarebbero implictily convertito in una stringa troppo, quindi si sarebbe verificato alcun errore. Così si potrebbe ottenere migliaia di avvertimenti inutili in tutto il luogo, e non credo che questo sia l'intenzione di un compilatore.

La flessibilità viene sempre con un prezzo, è necessario prendere uno sguardo più profondo al vostro programma, o il programma con più attenzione, in altre parole si è il compilatore in situazioni come sopra.

Quindi, la soluzione, come il compilatore? - Fissare con una "prova: tranne":)

Compilatori + tipi statici = macchina efficiente codice
I compilatori + tipi dinamici = codice macchina inefficiente

Si consideri il seguente pseudocodice:

function foo(a, b) {
    return a+b
}

Un linguaggio statico sarà in grado di sapere (da dichiarazione o deduzione), che a e b sono numeri interi, e compilerà fino a

%reg = addi a,b

o qualcosa di simile, in ogni caso.

Un compilatore per un linguaggio dinamico avrebbe dovuto emettere il codice per
1. Controllare essi tipi di A e B
2. gestire ogni caso o una combinazione di casi

%reg1 = typeof a
beq %reg1, int, a_int_case
beq %reg1, float, a_float_case
beq %reg1, string, a_string_case

label a_int_case
%reg1 = typeof b
beq %reg1, int, a_int_b_int_case
beq %reg1, float, a_int_b_float_case
beq %reg1, string, a_int_b_string_case

label a_int_b_int_case
%out = addi a,b
goto done

label a_int_b_float_case
%tmp = mkfloat a
%out = addf %tmp,b
goto done

... Etc. I can't finish

Mentre si potrebbe generare codice macchina più intelligente di quello, non sarebbe in grado di aiutare la generazione di un sacco di codice -. Questo rende la compilazione non è una vittoria importante per un linguaggio dinamico

Dal momento che gli interpreti sono molto più facili da scrivere, e la compilazione non fare molto bene, perché non scrivere un interprete?

(compilatori Just-in-time in realtà hanno informazioni sul tipo e possono compilare fino alla singola istruzione Essi in realtà hanno più informazioni rispetto ai sistemi di tipo statico, e può teoricamente fare ancora meglio Tutti Assembler è simulata;.. Qualsiasi riferimento a vero e proprio codice che potrebbe funzionare su una macchina reale è puramente casuale).

Forse è perché uno dei miei principali linguaggi interpretati è Perl e uno dei miei linguaggi compilati è Objective-C, ma non ho mai sentito fortemente che ci fosse qualcosa di speciale compilation vs interpretazione che ha suggerito dinamica nel tipizzazione statica.

Credo che sia chiaro che entrambe le parti stanno guardando l'altro e pensando: "Ci sono alcuni vantaggi per quello." E 'più facile in diverse applicazioni per ottenere una certa flessibilità di tipo dinamico, mentre può essere più facile da mantenere qualcosa che è staticamente tipizzato e applicata.

Non sono d'accordo con Andrew Hare spiegazione però. Mentre un linguaggio puramente interpretato dovrà aggiungere in una fase di pre-elaborazione, e quindi non essere puramente interpretato per avvertire il programmatore prima dell'esecuzione di errori di battitura statici, non preclude gettare un errore di tipo in fase di esecuzione, come si verifica. Quindi manca la compilazione non significa può verificarsi alcun controllo di tipo statico. Ma dal momento che ottenere un errore di tipo a run-time non è così utile come ottenere uno alla compilazione, o durante un controllo preflight, posso vedere come il "vantaggio" di tipizzazione statica in quella situazione può sembrare di essere più di un fastidio, e quindi ottenere buttato fuori a favore dei vantaggi tipizzazione dinamica portano.

Se si sapeva fin dall'inizio che si preferisce mantenere i tipi statico, perché personalmente di scrivere codice migliore, più gestibile come un risultato da, e si stava progettando il vostro linguaggio interpretato, nulla dovrebbe impedire di progettazione del linguaggio come staticamente tipizzato uno .

Per citare il linguaggi interpretati articolo wiki "In teoria, qualsiasi lingua può essere compilato o interpretato , in modo da questa designazione si applica solo a causa della pratica realizzazione comune e non una proprietà sottostante di un linguaggio. "
C'è un articolo wiki sul solo la digitazione.

Dinamicamente tipizzato linguaggi interpretati dare più libertà nel modo in cui si programma.Esso consente per la meta di programmazione per essere fattibile.Esso consente per le variabili create in fase di esecuzione.Permette di hash anonimo e anonimo matrici essere creato in qualsiasi momento durante la fase di esecuzione, senza che mai in precedenza dichiarare nulla prima mano.Consente indeterminato di informazioni da attribuirsi in un hash senza mai dichiarare tutti i tasti in anticipo.Si può avere sottoprogrammi creato dalla indeterminato input casuale.Si può nutrire un programma di codice che può essere eseguito in modo dinamico.I linguaggi interpretati gratis le catene da cui limiti della programmazione in generale.Si sono limitati a ciò che si digita nel file di origine con linguaggi tipizzati in modo statico.Si può fare di più con meno, in un linguaggio tipizzato in modo dinamico.

La maggior parte dei robot, che oggi si occupano di linguaggi interpretati più perché l'informazione deve essere determinato in fase di esecuzione e di nuove variabili devono essere fatte per memorizzare queste informazioni in fase di runtime.Macchina di apprendimento è basato su informazioni di essere interpretato.Noi stessi in quanto esseri umani, interpreti, che è il motivo per cui i robot sono stati progettati in questo modo.Il futuro è davvero interpretato.Naturalmente, avete bisogno di staticamente tipizzato lingue per costruire interpreti in modo staticamente tipizzato lingue non andrà mai via a meno che non interpreti sono costruiti in codice assembly in futuro.Più interpreti sono costruite su linguaggi tipizzati in modo statico in questi giorni.

I linguaggi interpretati excel in un ambiente dinamico.Se è possibile interpretare il codice/informazioni in fase di esecuzione, quindi perché non.Se il tuo davvero bene in modo dinamico di programmazione, quindi è possibile creare codice che può creare variabili e hash senza mai digitando il tutto.È possibile ridurre la quantità di linee drasticamente se il lavoro con enormi quantità di dati.È possibile utilizzare un data dumper stampare tutte le informazioni, poiché i linguaggi interpretati, di solito tenere traccia del tipo di variabili in fase di runtime, permettendo che questo è possibile.Non si può fare questo in barebone c++.L'unica volta che c++ e c sa cosa sta succedendo è in fase di compilazione.Dopo che la vostra sul proprio se si implementa qualcosa di te stesso.

Chi vuole essere legato, tanto per il file di origine in questi giorni, soprattutto quando il tuo lavoro in ambienti dinamici.Tutto il vostro fare è limitare il vostro potenziale.Una volta che il vostro collo profondo in modo dinamico codice interpretato e tornare a qualsiasi staticamente tipizzato lingua che sarà difficile modificare il codice perché la vostra ancora di pensare a un limite di mentalità.La vostra mente deve tornare ad essere limitata, di nuovo, a ciò che è digitato il file di origine.

Nel modo di stili di programmazione:Staticamente tipizzato codice produce statico risultati.Dinamicamente tipizzato codice produce dinamico o statico risultati.

Se la vostra intenzione di essere la programmazione di qualcosa che non cambia mai un comportamento diverso da ciò che è conosciuto, staticamente tipizzato lingue sono grandi per questo.Se il vostro fare con un comportamento dinamico quindi dinamicamente tipizzato lingue più adatto per questi casi.Tutto dipende dalla situazione, per lo più.

Ogni lingua ha i loro alti e bassi.Devo solo scegliere e scegliere con saggezza.

Credo tipizzazione statica rende più facile per i compilatori e questo è il principale (se non unico) ragione che è presente nei linguaggi compilati.

Per linguaggi interpretati è più facile supporre che le variabili non hanno tipo (solo valori hanno) perché si ritiene di non come un riproduttore per i dati che devono stare dentro, ma piuttosto etichetta per i dati che galleggia da qualche parte sul mucchio .

Se il programmatore vuole di lui può sempre affermare che variabile contiene un valore di tipo data (ad esempio in missione). Non v'è alcun motivo per costruire in lingua. Naturalmente questo non è lo stesso tipo di controllo che si ha per linguaggi compilati.

Probabilmente potrebbe avere la lingua in cui si deve dichiarare in modo esplicito il tipo di ciascuna variabile, ma se non è molto più facile fare le cose interessanti che con tipizzazione statica richiederebbero dal programmatore con cura artigianale i tipi generici molto complessa.

D'altra parte. Sapete qualsiasi modo dinamico digitati linguaggio compilato (staticamente non JIT)?

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