Linguaggi di tipo dinamico rispetto a linguaggi di tipo statico


205

Quali sono i vantaggi e i limiti delle lingue di tipo dinamico rispetto alle lingue di tipo statico?

Vedi anche : cos'è l'amore per i linguaggi dinamici (un filo molto più polemico ...)


10
Questa domanda è troppo soggettiva.
Jason Dagit,

7
Non lo definirei soggettivo, ma esca fiamma. Ma ci sono alcuni fatti oggettivi a riguardo.
Vinko Vrsalovic,

2
Concordato: troppo soggettivo. È interessante confrontare e confrontare i due approcci, ma vacilla pericolosamente sull'orlo dell'apocalisse del forum.
Daniel Spiewak,

17
I linguaggi dinamici sono ottimi per lo sviluppo rapido di applicazioni demo / usa e getta perché se fai un refuso a chi importa, la pagina web si carica ancora potresti avere un paio di elementi di dati sbagliati qui o là. Non riesco a immaginare nessun'altra situazione in cui la capacità di digitare in modo errato le variabili senza ottenere un errore del compilatore sia vista come un "vantaggio".
Alex R

4
Un errore del genere in genere porrebbe JavaScript in una brusca frenata, che considero un'ottima cosa. Perlomeno genererebbe errori che trovo anche preziosi. Per qualche motivo è sempre un tipo da un paradigma di digitazione statica che vuole seppellire i suoi errori javascript con vuote istruzioni try / catch. È stato qualcosa di un fenomeno nella mia esperienza. Cos'è quello? Indipendentemente da ciò, non è che non riceviamo feedback quando eseguiamo il nostro codice.
Erik Reppen,

Risposte:


139

La capacità dell'interprete di dedurre conversioni di tipo e tipo velocizza i tempi di sviluppo, ma può anche provocare errori di runtime che non è possibile ottenere in un linguaggio tipicamente statico in cui vengono rilevati al momento della compilazione. Ma quale è il migliore (o anche se è sempre vero) è discusso caldamente nella comunità in questi giorni (e da molto tempo).

Una buona idea della questione è quella della tipizzazione statica ove possibile, la digitazione dinamica quando necessario: la fine della guerra fredda tra i linguaggi di programmazione di Erik Meijer e Peter Drayton di Microsoft:

I sostenitori della tipizzazione statica sostengono che i vantaggi della tipizzazione statica includono il rilevamento precoce di errori di programmazione (ad es. Impedire l'aggiunta di un numero intero a un valore booleano), una migliore documentazione sotto forma di firme di tipo (ad es. Incorporando numero e tipi di argomenti quando si risolvono i nomi), altro opportunità di ottimizzazione del compilatore (ad es. sostituzione di chiamate virtuali con chiamate dirette quando il tipo esatto di ricevitore è noto staticamente), maggiore efficienza di runtime (ad es. non tutti i valori devono avere un tipo dinamico) e una migliore esperienza di sviluppo in fase di progettazione (ad es. il tipo di ricevitore, l'IDE può presentare un menu a discesa di tutti i membri applicabili). I fanatici della tipizzazione statica cercano di farci credere che "i programmi ben digitati non possono andare storti". Anche se questo suona sicuramente impressionante, è un'affermazione piuttosto vacua. Il controllo statico del tipo è un'astrazione in fase di compilazione del comportamento in fase di esecuzione del programma e quindi è necessariamente solo parzialmente sana e incompleta. Ciò significa che i programmi possono comunque andare storto a causa di proprietà che non vengono monitorate dal controllo del tipo e che ci sono programmi che, sebbene non possano andare male, non possono essere controllati. L'impulso a rendere la tipizzazione statica meno parziale e più completa fa sì che i sistemi di tipi diventino eccessivamente complicati ed esotici, come testimoniano concetti come "tipi fantasma" [11] e "tipi traballanti" [10]. È come provare a correre una maratona con una palla e una catena legate alla gamba e gridare trionfalmente che ce l'hai quasi fatta anche se sei stato salvato dopo il primo miglio. Il controllo statico del tipo è un'astrazione in fase di compilazione del comportamento in fase di esecuzione del programma e quindi è necessariamente solo parzialmente sana e incompleta. Ciò significa che i programmi possono comunque andare storto a causa di proprietà che non vengono monitorate dal controllo del tipo e che ci sono programmi che, sebbene non possano andare male, non possono essere controllati. L'impulso a rendere la tipizzazione statica meno parziale e più completa fa sì che i sistemi di tipi diventino eccessivamente complicati ed esotici, come testimoniano concetti come "tipi fantasma" [11] e "tipi traballanti" [10]. È come provare a correre una maratona con una palla e una catena legate alla gamba e gridare trionfalmente che ce l'hai quasi fatta anche se sei stato salvato dopo il primo miglio. Il controllo statico del tipo è un'astrazione in fase di compilazione del comportamento in fase di esecuzione del programma e quindi è necessariamente solo parzialmente sana e incompleta. Ciò significa che i programmi possono comunque andare storto a causa di proprietà che non vengono monitorate dal controllo del tipo e che ci sono programmi che, sebbene non possano andare male, non possono essere controllati. L'impulso a rendere la tipizzazione statica meno parziale e più completa fa sì che i sistemi di tipi diventino eccessivamente complicati ed esotici, come testimoniano concetti come "tipi fantasma" [11] e "tipi traballanti" [10]. È come provare a correre una maratona con una palla e una catena legate alla gamba e gridare trionfalmente che ce l'hai quasi fatta anche se sei stato salvato dopo il primo miglio. e quindi è necessariamente solo parzialmente sano e incompleto. Ciò significa che i programmi possono comunque andare storto a causa di proprietà che non vengono monitorate dal controllo del tipo e che ci sono programmi che, sebbene non possano andare male, non possono essere controllati. L'impulso a rendere la tipizzazione statica meno parziale e più completa fa sì che i sistemi di tipi diventino eccessivamente complicati ed esotici, come testimoniano concetti come "tipi fantasma" [11] e "tipi traballanti" [10]. È come provare a correre una maratona con una palla e una catena legate alla gamba e gridare trionfalmente che ce l'hai quasi fatta anche se sei stato salvato dopo il primo miglio. e quindi è necessariamente solo parzialmente sano e incompleto. Ciò significa che i programmi possono comunque andare storto a causa di proprietà che non vengono monitorate dal controllo del tipo e che ci sono programmi che, sebbene non possano andare male, non possono essere controllati. L'impulso a rendere la tipizzazione statica meno parziale e più completa fa sì che i sistemi di tipi diventino eccessivamente complicati ed esotici, come testimoniano concetti come "tipi fantasma" [11] e "tipi traballanti" [10]. È come provare a correre una maratona con una palla e una catena legate alla gamba e gridare trionfalmente che ce l'hai quasi fatta anche se sei stato salvato dopo il primo miglio. e che ci sono programmi che pur non potendo sbagliare non possono essere controllati dal tipo. L'impulso a rendere la tipizzazione statica meno parziale e più completa fa sì che i sistemi di tipi diventino eccessivamente complicati ed esotici, come testimoniano concetti come "tipi fantasma" [11] e "tipi traballanti" [10]. È come provare a correre una maratona con una palla e una catena legate alla gamba e gridare trionfalmente che ce l'hai quasi fatta anche se sei stato salvato dopo il primo miglio. e che ci sono programmi che pur non potendo sbagliare non possono essere controllati dal tipo. L'impulso a rendere la tipizzazione statica meno parziale e più completa fa sì che i sistemi di tipi diventino eccessivamente complicati ed esotici, come testimoniano concetti come "tipi fantasma" [11] e "tipi traballanti" [10]. È come provare a correre una maratona con una palla e una catena legate alla gamba e gridare trionfalmente che ce l'hai quasi fatta anche se sei stato salvato dopo il primo miglio.

I sostenitori di linguaggi tipizzati dinamicamente sostengono che la tipizzazione statica è troppo rigida e che la morbidezza dei linguaggi dinamici li rende ideali per prototipi di sistemi con requisiti mutevoli o sconosciuti o che interagiscono con altri sistemi che cambiano in modo imprevedibile (integrazione di dati e applicazioni). Naturalmente, i linguaggi tipizzati dinamicamente sono indispensabili per affrontare comportamenti di programma veramente dinamici come l'intercettazione di metodi, il caricamento dinamico, il codice mobile, la riflessione sul runtime, ecc. Nella madre di tutti gli articoli sullo scripting [16], John Ousterhout sostiene che i sistemi tipizzati staticamente i linguaggi di programmazione rendono il codice meno riutilizzabile, più dettagliato, non più sicuro e meno espressivo dei linguaggi di script tipizzati dinamicamente. Questo argomento è letteralmente pappagallo da molti sostenitori di linguaggi di script tipizzati in modo dinamico. Sosteniamo che questo è un errore e rientra nella stessa categoria dell'argomentazione secondo cui l'essenza della programmazione dichiarativa sta eliminando l'incarico. O come dice John Hughes [8], è un'impossibilità logica di rendere un linguaggio più potente omettendo le funzionalità. Difendere il fatto che ritardare tutto il controllo del tipo al runtime sia una buona cosa, sta giocando tattiche di struzzo con il fatto che gli errori dovrebbero essere colti il ​​più presto possibile nel processo di sviluppo. è un'impossibilità logica di rendere più potente un linguaggio omettendo le funzionalità. Difendere il fatto che ritardare tutto il controllo del tipo al runtime sia una buona cosa, sta giocando tattiche di struzzo con il fatto che gli errori dovrebbero essere colti il ​​più presto possibile nel processo di sviluppo. è un'impossibilità logica di rendere più potente un linguaggio omettendo le funzionalità. Difendere il fatto che ritardare tutto il controllo del tipo al runtime sia una buona cosa, sta giocando tattiche di struzzo con il fatto che gli errori dovrebbero essere colti il ​​più presto possibile nel processo di sviluppo.


37
"intercettazione del metodo, caricamento dinamico, codice mobile, riflessione del runtime" possono essere fatti tutti in Java, solo per la cronaca.
Will Hartung,

13
I tipi fantasma non sono "eccessivamente complicati".
Jon Harrop,

12
Il collegamento al documento Meijer è interrotto dal 16/05/2010.
jchadhowell,


4
@VinkoVrsalovic I linguaggi statici con inferenza di tipo e polimorfismo sono abbastanza buoni per la prototipazione rapida. Offrono lo stesso comfort del linguaggio dinamico e la sicurezza dei linguaggi statici.
Edgar Klerks,

119

I sistemi di tipo statico cercano di eliminare staticamente determinati errori, ispezionando il programma senza eseguirlo e tentando di dimostrare la solidità sotto certi aspetti. Alcuni sistemi di tipi sono in grado di rilevare più errori di altri. Ad esempio, C # può eliminare le eccezioni del puntatore null se usato correttamente, mentre Java non ha tale potere. Twelf ha un sistema di tipi che garantisce effettivamente che le prove terminino , "risolvendo" il problema di interruzione .

Tuttavia, nessun sistema di tipi è perfetto. Per eliminare una particolare classe di errori, devono anche rifiutare alcuni programmi perfettamente validi che violano le regole. Questo è il motivo per cui Twelf non risolve davvero il problema dell'arresto, lo evita semplicemente lanciando un gran numero di prove perfettamente valide che si risolvono in modo strano. Allo stesso modo, il sistema di tipi Java rifiuta l' PersistentVectorimplementazione di Clojure a causa dell'uso di array eterogenei. Funziona in fase di esecuzione, ma il sistema di tipi non può verificarlo.

Per questo motivo, la maggior parte dei sistemi di tipo fornisce "escape", modi per sovrascrivere il controllo statico. Per la maggior parte delle lingue, questi prendono la forma del casting, sebbene alcuni (come C # e Haskell) abbiano intere modalità contrassegnate come "non sicure".

Soggettivamente, mi piace la digitazione statica. Implementato correttamente (suggerimento: non Java), un sistema di tipo statico può essere di grande aiuto per eliminare gli errori prima che si blocchino il sistema di produzione. I linguaggi tipizzati dinamicamente tendono a richiedere più test unitari, il che è noioso il più delle volte. Inoltre, i linguaggi tipizzati staticamente possono avere determinate caratteristiche che sono impossibili o non sicure nei sistemi di tipo dinamico (vengono in mente conversioni implicite ). È tutta una questione di requisiti e gusto soggettivo. Non costruirò più il prossimo Eclipse in Ruby di quanto proverei a scrivere uno script di backup in Assembly o patch un kernel usando Java.

Oh, e le persone che affermano che "la digitazione x è 10 volte più produttiva di quella y " soffiano semplicemente fumo. La digitazione dinamica può "sentirsi" più veloce in molti casi, ma perde terreno quando si tenta effettivamente di far funzionare l' applicazione fantasia . Allo stesso modo, la digitazione statica può sembrare la rete di sicurezza perfetta, ma uno sguardo ad alcune delle definizioni di tipo generico più complicate in Java fa sì che la maggior parte degli sviluppatori si affretti a cercare paraocchi. Anche con sistemi di tipo e produttività, non esiste un proiettile d'argento.

Nota finale: non preoccuparti delle prestazioni quando si confronta statica con la digitazione dinamica. I JIT moderni come V8 e TraceMonkey si avvicinano pericolosamente alle prestazioni del linguaggio statico. Inoltre, il fatto che Java si compili effettivamente in un linguaggio intermedio intrinsecamente dinamico dovrebbe essere un suggerimento che per la maggior parte dei casi, la digitazione dinamica non è l'enorme killer delle prestazioni che alcune persone si rendono conto di essere.


5
A proposito della performance. In casi comuni non farà molta differenza, ma in matematica ad alta tensione e simili, c'è una vera differenza. I test hanno dimostrato che il richiamo di una funzione, nel caso di ipy vs C #, differisce di mille cicli. Solo perché il primo deve essere sicuro che esista un metodo.
Dykam,

29
puoi approfondire il punto "C # può eliminare le eccezioni del puntatore null se usato correttamente, mentre Java non ha tale potere." ? Un esempio o una citazione sarebbe molto apprezzato.
Srinivas Reddy Thatiparthy

13
"alcune delle definizioni di tipo generico più complicate in Java inviano la maggior parte degli sviluppatori a cercare paraocchi" - se questo è il tuo esempio peggiore, ovviamente non hai usato C ++ ;-)
bacar

3
"Inoltre, il fatto che Java si compili effettivamente in un linguaggio intermedio intrinsecamente dinamico dovrebbe essere un suggerimento che per la maggior parte dei casi, la digitazione dinamica non è l'enorme killer delle prestazioni che alcune persone si rendono conto di essere." - quando il tuo esempio di linguaggio con "buone prestazioni" è Java, potresti voler riconsiderare.
Yakk - Adam Nevraumont,

" Java si compila fino a un intermedio intrinsecamente dinamico " - che manca il punto. I controlli statici sono stati eseguiti in anticipo e pertanto non sono necessari ulteriori controlli del tempo di esecuzione a copertura di quelli poiché il compilatore sceglie le istruzioni come daddperché sa in anticipo che gli operandi sono doubles.
Michael Beer,

45

Bene, entrambi sono molto, molto, molto molto fraintesi e anche due cose completamente diverse. che non si escludono a vicenda .

I tipi statici sono una limitazione della grammatica della lingua. Si potrebbe dire che i linguaggi tipicamente statici rigorosamente non siano contestuali. La semplice verità è che diventa scomodo esprimere una lingua in modo saggio in grammatiche libere dal contesto che non trattano tutti i suoi dati semplicemente come vettori di bit. I sistemi di tipo statico fanno parte della grammatica della lingua, se ce ne sono, semplicemente la limitano più di quanto potrebbe fare una grammatica libera dal contesto, quindi i controlli grammaticali avvengono in due passaggi sulla fonte. I tipi statici corrispondono alla nozione matematica della teoria dei tipi, la teoria dei tipi in matematica limita semplicemente la legalità di alcune espressioni. Come, non posso dire 3 + [4,7]in matematica, questo è dovuto alla sua teoria dei tipi.

I tipi statici non sono quindi un modo per "prevenire errori" dal punto di vista teorico, sono una limitazione della grammatica. Infatti, purché +, 3 e gli intervalli abbiano le solite definizioni teoriche impostate, se rimuoviamo il sistema dei tipi 3 + [4,7]ha un risultato abbastanza ben definito che è un insieme. teoricamente non esistono "errori di runtime", l'uso pratico del sistema dei tipi è di prevenire operazioni che per gli esseri umani non avrebbero alcun senso. Le operazioni sono ancora solo lo spostamento e la manipolazione di bit, ovviamente.

Il problema è che un sistema di tipo non è in grado di decidere se tali operazioni si verificheranno o meno se ne sarebbe consentito l'esecuzione. Come in, esattamente partizionare l'insieme di tutti i programmi possibili in quelli che avranno un 'errore di tipo' e quelli che non lo sono. Può fare solo due cose:

1: prova che si verificheranno errori di tipo in un programma
2: prova che non si verificheranno in un programma

Potrebbe sembrare che mi stia contraddicendo. Ma quello che fa un verificatore di tipo C o Java rifiuta un programma come "non grammaticale", o come lo chiama "errore di tipo" se non riesce a 2. Non può provare che non si verificherà, ciò non significa che non si verificheranno, significa solo che non può provarlo. Potrebbe benissimo essere che un programma che non avrà un errore di tipo venga rifiutato semplicemente perché non può essere provato dal compilatore. Un semplice esempioif(1) a = 3; else a = "string";, sicuramente poiché è sempre vero, il ramo else non verrà mai eseguito nel programma e non si verificherà alcun errore di tipo. Ma non può dimostrare questi casi in modo generale, quindi viene respinto. Questa è la principale debolezza di molte lingue tipicamente statiche, nel proteggerti da te stesso, sei necessariamente anche protetto nei casi in cui non ne hai bisogno.

Ma, contrariamente alla credenza popolare, ci sono anche linguaggi tipicamente statici che funzionano secondo il principio 1. Rifiutano semplicemente tutti i programmi di cui possono provare che provocherà un errore di tipo e passano tutti i programmi di cui non possono. Quindi è possibile che consentano programmi che presentano errori di battitura, un buon esempio è Typed Racket, è ibrido tra la tipizzazione dinamica e statica. E alcuni direbbero che in questo sistema ottieni il meglio da entrambi i mondi.

Un altro vantaggio della tipizzazione statica è che i tipi sono noti al momento della compilazione, e quindi il compilatore può usarlo. Se in Java facciamo "string" + "string"o 3 + 3, entrambi i +token nel testo alla fine rappresentano un'operazione e un dato completamente diversi, il compilatore sa quale scegliere tra i soli tipi.

Ora farò una dichiarazione molto controversa qui, ma sopporterò con me: la "digitazione dinamica" non esiste .

Sembra molto controverso, ma è vero, i linguaggi tipizzati in modo dinamico sono da una prospettiva teorica non tipizzata . Sono solo lingue tipicamente statiche con un solo tipo. O semplicemente, sono lingue che sono effettivamente generate grammaticalmente da una grammatica libera dal contesto in pratica.

Perché non hanno tipi? Poiché ogni operazione è definita e consentita su ogni operatore, cos'è esattamente un "errore di tipo runtime"? È da un esempio teorico puramente un effetto collaterale . Se fare ciò print("string")che stampa una stringa è un'operazione, allora lo è anche length(3), il primo ha l'effetto collaterale di scrivere stringsull'output standard, il secondo semplicemente error: function 'length' expects array as argument., tutto qui. Dal punto di vista teorico non esiste un linguaggio tipizzato dinamicamente. Sono non tipizzati

Va bene, l'ovvio vantaggio del linguaggio "tipizzato in modo dinamico" è il potere espressivo, un sistema di tipi non è altro che una limitazione del potere espressivo. E in generale, le lingue con un sistema di tipi avrebbero effettivamente un risultato definito per tutte quelle operazioni che non sono consentite se il sistema di tipi fosse semplicemente ignorato, i risultati non avrebbero senso per gli umani. Molte lingue perdono la completezza di Turing dopo aver applicato un sistema di tipi.

L'ovvio svantaggio è il fatto che possono verificarsi operazioni che potrebbero produrre risultati insensati per l'uomo. Per evitare ciò, i linguaggi tipizzati dinamicamente in genere ridefiniscono quelle operazioni, piuttosto che produrre quel risultato senza senso lo ridefiniscono per avere l'effetto collaterale di scrivere un errore e possibilmente arrestare del tutto il programma. Questo non è affatto un "errore", infatti, la specifica del linguaggio di solito implica questo, si tratta di un comportamento tanto del linguaggio quanto della stampa di una stringa da una prospettiva teorica. I sistemi di tipo costringono quindi il programmatore a ragionare sul flusso del codice per assicurarsi che ciò non accada. O addirittura, la ragione in modo che esso faAccadere può anche essere utile in alcuni punti per il debug, dimostrando che non è affatto un "errore" ma una proprietà ben definita della lingua. In effetti, l'unico residuo della "tipizzazione dinamica" che la maggior parte delle lingue ha è a guardia di una divisione per zero. Questo è ciò che è la tipizzazione dinamica, non ci sono tipi, non ci sono più tipi di quello zero è un tipo diverso rispetto a tutti gli altri numeri. Quello che la gente chiama un 'tipo' è solo un'altra proprietà di un dato, come la lunghezza di un array, o il primo carattere di una stringa. E molte lingue tipizzate dinamicamente ti permettono anche di scrivere cose come "error: the first character of this string should be a 'z'".

Un'altra cosa è che le lingue tipizzate dinamicamente hanno il tipo disponibile in fase di esecuzione e di solito possono verificarlo, gestirlo e decidere da esso. Ovviamente, in teoria non è diverso dall'accedere al primo carattere di un array e vedere di cosa si tratta. In effetti, puoi creare la tua C dinamica, basta usare solo un tipo come long long int e usare i suoi primi 8 bit per memorizzare il tuo 'tipo' e scrivere le funzioni di conseguenza che lo controllano ed eseguono il float o l'aggiunta di numeri interi. Hai una lingua tipicamente statica con un tipo o una lingua dinamica.

In pratica tutto ciò mostra che i linguaggi tipizzati staticamente sono generalmente utilizzati nel contesto della scrittura di software commerciale, mentre i linguaggi tipizzati dinamicamente tendono ad essere utilizzati nel contesto della risoluzione di alcuni problemi e dell'automazione di alcune attività. Scrivere codice in lingue tipicamente statiche richiede semplicemente molto tempo ed è ingombrante perché non puoi fare cose che sai andranno bene, ma il sistema dei tipi ti protegge ancora da te stesso per gli errori che non commetti. Molti programmatori non si rendono nemmeno conto che lo fanno perché è nel loro sistema ma quando si codifica in linguaggi statici, spesso si aggira il fatto che il sistema di tipi non ti consente di fare cose che non possono andare storte, perché non posso provare che non andrà storto.

Come ho notato, "tipizzato staticamente" in generale significa caso 2, colpevole fino a prova contraria. Ma alcuni linguaggi, che non derivano affatto il loro sistema di tipi dalla teoria dei tipi, usano la regola 1: innocente fino a prova contraria, che potrebbe essere l'ibrido ideale. Quindi, forse Typed Racket è per te.

Inoltre, per un esempio più assurdo ed estremo, sto attualmente implementando un linguaggio in cui "tipi" sono veramente il primo carattere di un array, sono dati, dati di "tipo", "tipo", che è esso stesso un tipo e un dato, l'unico dato che ha se stesso come tipo. I tipi non sono limitati o limitati staticamente ma è possibile generare nuovi tipi in base alle informazioni di runtime.


1
"Molte lingue perdono la completezza di Turing dopo aver applicato un sistema di tipi". non si applica ai soliti linguaggi di programmazione, giusto? da quello che ho letto, le lingue normali non sono complete
Răzvan Flavius ​​Panda,

1
@ RăzvanPanda: Lajla probabilmente si riferiva alle variazioni del calcolo lambda tipizzato o ad alcuni dei linguaggi di programmazione che usano sui dimostratori di teoremi. Molti di questi possono solo esprimere programmi che sono garantiti per fermarsi e quindi non sono completi di Turing. Pratici linguaggi di programmazione funzionale basati su questi sistemi di tipo aggirano questa limitazione estendendo il calcolo di base con tipi ricorsivi.
hugomg,

1
"Sembra molto controverso, ma è vero, i linguaggi tipizzati dinamicamente sono da una prospettiva teorica non tipizzata." - ... e, in un attimo, so che non hai idea di cosa stai parlando. La digitazione dinamica significa solo che i tipi appartengono ai valori, non agli identificatori. Rende i programmi più difficili da dimostrare, ma non necessariamente impossibili. Il polimorfismo integrato e parametrico ha già portato allo sviluppo dell'ottimizzazione del tempo di collegamento; che risolve lo stesso tipo di problema che ha la compilazione di linguaggi ottimizzati tipicamente dinamicamente: che sta conoscendo tutti i possibili input e output.
DeftlyHacked,

25

Forse il più grande "vantaggio" della tipizzazione dinamica è la curva di apprendimento più superficiale. Non esiste un sistema di tipi da imparare e nessuna sintassi non banale per casi angolari come i vincoli di tipo. Ciò rende la digitazione dinamica accessibile a molte più persone e fattibile per molte persone per le quali sofisticati sistemi di tipo statico sono fuori portata. Di conseguenza, la tipizzazione dinamica ha preso piede nei contesti dell'educazione (ad esempio Scheme / Python presso il MIT) e nei linguaggi specifici del dominio per i non programmatori (ad esempio Mathematica ). I linguaggi dinamici hanno anche preso piede nelle nicchie in cui hanno poca o nessuna concorrenza (ad esempio Javascript).

I linguaggi tipizzati dinamicamente più concisi (ad esempio Perl, APL, J, K, Mathematica ) sono specifici del dominio e possono essere significativamente più concisi dei linguaggi tipicamente statici di uso generale più concisi (ad esempio OCaml ) nelle nicchie per cui sono stati progettati .

I principali svantaggi della tipizzazione dinamica sono:

  • Errori di tipo runtime.

  • Può essere molto difficile o addirittura praticamente impossibile raggiungere lo stesso livello di correttezza e richiede molti più test.

  • Nessuna documentazione verificata dal compilatore.

  • Scarse prestazioni (di solito in fase di esecuzione ma a volte in fase di compilazione, ad esempio Stalin Scheme) e prestazioni imprevedibili a causa della dipendenza da sofisticate ottimizzazioni.

Personalmente, sono cresciuto con linguaggi dinamici ma non li toccherei con un palo da 40 'come professionista se non ci fossero altre opzioni praticabili.


2
Direi una barriera inferiore all'entrata ma la padronanza non è meno di una curva di apprendimento.
Erik Reppen,

La curva di apprendimento non è inferiore perché non hai un sistema di tipi da imparare?
Jon Harrop,

C'è ancora un sistema di tipi. Puoi fare ipotesi ragionevoli su cosa succede quando aggiungi un bool e una stringa, ma spesso aiuta molto a conoscere alcuni dettagli reali su come i tipi sono costretti in un linguaggio tipizzato dinamicamente. Questo è ciò che molte persone solo rigide non ottengono. In realtà impariamo queste cose.
Erik Reppen,

@ErikReppen: stiamo usando diverse definizioni di "sistema di tipo". Mi riferivo al fatto di non dover imparare un sistema di tipo statico, ad esempio tipi di dati algebrici, generici. I "tipi" a cui ti riferisci sono solo dati. Il fatto che alcune funzioni rifiutino alcuni dati in fase di esecuzione è universale.
Jon Harrop

12

Dall'articolo di Artima : Strong vs. Weak, Statico vs. Dynamic articolo:

la tipizzazione forte impedisce operazioni di miscelazione tra tipi non corrispondenti. Per mescolare i tipi, è necessario utilizzare una conversione esplicita

la digitazione debole significa che puoi mescolare i tipi senza una conversione esplicita

Nel documento di Pascal Costanza, La tipizzazione dinamica vs. statica - Un'analisi basata su pattern (PDF), afferma che in alcuni casi, la tipizzazione statica è più soggetta a errori rispetto alla tipizzazione dinamica. Alcune lingue tipizzate staticamente ti costringono ad emulare manualmente la digitazione dinamica per fare "La cosa giusta". È discusso in Lambda the Ultimate .


1
"La digitazione statica è più soggetta a errori rispetto alla digitazione dinamica" - Sì, sì e DOPPIO sì! Ho avuto molta esperienza in entrambi i tipi di linguaggi, e in ogni caso il linguaggio dinamico "funziona" mentre lo statico richiede il doppio del tempo di debug (Vedi C ++ e Delphi). Ciò è spesso dovuto a problemi di tipo, in particolare il passaggio di dati tra moduli e funzioni con tipi folli. Anche se ci sono molti tipi di bug teorici che i linguaggi dinamici possono presumibilmente causare, in pratica, è MOLTO raro per me imbattersi in un bug causato dalla coercizione del tipo a meno che tu non sia un povero programmatore che abusa di tipi dinamici.
dallin

7
Ho letto un progetto di Costanza alcuni anni fa. Ovunque avesse scritto "statico", intendeva proprio "Java". Gli ho dato dozzine di contro esempi in lingue come OCaml che hanno smentito le sue affermazioni, ma è andato avanti e lo ha comunque pubblicato. A quanto sembra quel giornale, sta ancora pubblicando la stessa vecchia assurdità. Ad esempio, in quel documento afferma che "C # è generalmente una brutta copia di Java". Questo non ha posto in un articolo scientifico ...
Jon Harrop,

@dallin la mia esperienza è esattamente l'opposto: dovendo programmare molto in C, C ++, Java, Python, Perl e simili, non inizierei mai nulla di più grande di un piccolo programma di modifica in un linguaggio tipizzato dinamicamente se non forzato. In Python, rabbrividisco ancora quando penso a un progetto WSGI: i callback che ho dovuto sovrascrivere sono stati passati nei riferimenti agli oggetti, e il codice sembrava funzionare bene, quando si è schiantato perché si è scoperto che a volte non sono oggetti ma alcuni tipi elementali essere passato. Un linguaggio che rende così facile creare roba del genere è chiaramente pericoloso.
Michael Beer,

@MichaelBeer Potresti anche dire che un linguaggio come C / C ++ che ti consente di gestire direttamente la memoria è assolutamente pericoloso! Ho certamente lottato con errori di memoria per ore. Anche i grandi progetti Java non sono un picnic. In qualsiasi lingua, devi capire i pericoli della lingua e delle buone pratiche. I progetti peggiori in assoluto su cui abbia mai lavorato sono stati i progetti PHP di gruppo con poca struttura, ma ho anche lavorato a progetti con linguaggi dinamici che erano un sogno quando usavano un buon framework e buone pratiche di programmazione.
dallin

@dallin D'accordo, ogni lingua ha le sue insidie. Ma i difetti a cui ho fatto riferimento sono inerenti a qualsiasi linguaggio tipizzato dinamicamente, la possibilità di manipolare direttamente la memoria non è una proprietà intrinseca dei linguaggi tipizzati staticamente. Puoi immaginare linguaggi tipicamente dinamici che ti consentono di manipolare direttamente mem. Concordo sul fatto che C ++ sia un vero disastro, con l'inventore del linguaggio stesso che non crede che una sola persona su questo pianeta sia in grado di conoscere tutte le parti del linguaggio. Tuttavia, questo non può essere biasimato dal fatto che il C ++ sia stato tipizzato staticamente, ma un mostro che era in crescita da 30 anni ...
Michael Beer,

3

Dipende dal contesto. Ci sono molti vantaggi che sono appropriati per il sistema tipizzato dinamico e anche per quello tipizzato forte. Sono dell'opinione che il flusso del linguaggio dei tipi dinamici sia più veloce. I linguaggi dinamici non sono vincolati agli attributi di classe e al compilatore che pensa a cosa sta succedendo nel codice. Hai un po 'di libertà. Inoltre, il linguaggio dinamico di solito è più espressivo e produce meno codice, il che è positivo. Nonostante ciò, è più soggetto a errori che è anche discutibile e dipende maggiormente dalla copertura dei test unitari. È un prototipo semplice con un linguaggio dinamico ma la manutenzione può diventare un incubo.

Il principale vantaggio rispetto al sistema tipizzato statico è il supporto IDE e sicuramente un analizzatore statico di codice. Diventa più sicuro del codice dopo ogni modifica del codice. La manutenzione è un gioco da ragazzi con tali strumenti.


0

Ci sono molte cose diverse sui linguaggi statici e dinamici. Per me, la differenza principale è che nei linguaggi dinamici le variabili non hanno tipi fissi; invece, i tipi sono legati ai valori. Per questo motivo, il codice esatto che viene eseguito è indeterminato fino al runtime.

Nelle prime o ingenui implementazioni questa è un'enorme riduzione delle prestazioni, ma i moderni JIT si avvicinano in modo allettante al meglio che puoi ottenere con l'ottimizzazione dei compilatori statici. (in alcuni casi marginali, anche meglio di così).


0

Si tratta dello strumento giusto per il lavoro. Né è meglio il 100% delle volte. Entrambi i sistemi sono stati creati dall'uomo e presentano difetti. Scusa, ma facciamo schifo e realizziamo cose perfette.

Mi piace la digitazione dinamica perché mi impedisce, ma sì, gli errori di runtime possono insinuarsi che non avevo pianificato. Laddove la digitazione statica può correggere gli errori di cui sopra, ma fa impazzire un programmatore principiante (in lingue tipizzate) cercando di lanciare tra un carattere costante e una stringa.


-3

Digitazione statica: le lingue come Java e Scala sono tipizzate staticamente.

Le variabili devono essere definite e inizializzate prima di essere utilizzate in un codice.

per es. int x; x = 10;

System.out.println (x);

Digitazione dinamica: Perl è una lingua tipizzata dinamica.

Le variabili non devono essere inizializzate prima di essere utilizzate nel codice.

y = 10; usa questa variabile nella parte successiva del codice


5
Questo non ha nulla a che fare con il sistema dei tipi.
Thiago Negri,
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.