Qual è il presunto aumento di produttività della tipizzazione dinamica? [chiuso]


82

Ho spesso sentito l'affermazione secondo cui le lingue tipizzate dinamicamente sono più produttive delle lingue tipizzate staticamente. Quali sono i motivi di questa affermazione? Non si tratta solo di strumenti con concetti moderni come la convenzione sulla configurazione, l'uso della programmazione funzionale, modelli di programmazione avanzata e l'uso di astrazioni coerenti? Certamente c'è meno disordine perché le dichiarazioni di tipo (ad esempio in Java) spesso ridondanti non sono necessarie, ma puoi anche omettere la maggior parte delle dichiarazioni di tipo in linguaggi tipicamente statici che usano l'inferenza di tipo, senza perdere gli altri vantaggi della tipizzazione statica. E tutto questo è disponibile anche per le moderne lingue tipicamente statiche come Scala.

Quindi: cosa c'è da dire sulla produttività con la tipizzazione dinamica che è davvero un vantaggio del modello di tipo stesso?

Chiarimento: sono più interessato ai progetti di grandi / medie dimensioni che agli hack rapidi. :-)


10
Ti aspetteresti che il "duo statico" sia più veloce o più produttivo del "duo dinamico"?
Steve314,

Cosa intendi con duo? Comunque: posso pensare a un paio di ragioni per cui la tipizzazione statica è più produttiva della digitazione dinamica: più controlli del compilatore per errori, completamento del codice, più informazioni sull'intento del programmatore nel codice. Ecco perché sto chiedendo del contrario.
Hans-Peter Störr,

11
Era uno scherzo con un punto. Il "duo dinamico" è Batman e Robin. Non proverebbero quasi la stessa paura nel mondo sotterraneo criminale di Gotham City se fossero chiamati il ​​"duo statico". Poiché gli sviluppatori sono persone, le cose superficiali possono fare la differenza indipendentemente dal significato dei termini.
Steve314,

La mia prima domanda è se so cosa sto facendo o no. Se lo faccio, allora posso progettare le cose in anticipo e la digitazione statica ha senso. In caso contrario, dovrò cambiare molte cose al volo e la digitazione dinamica sarà più semplice. Common Lisp è la miglior lingua che ho trovato quando non so cosa sto facendo. (Avvertenza: ho solo grattato Haskell, e quindi non ho una buona sensazione per la digitazione statica inferita.)
David Thornley,

2
Sono totalmente d'accordo con John Skeet msmvps.com/blogs/jon_skeet/archive/2009/11/17/…
utente

Risposte:


99

In realtà penso che sia una chiamata piuttosto ravvicinata. Sia la tipizzazione dinamica che quella statica hanno i loro vantaggi.

Ragioni per cui la digitazione dinamica è più produttiva:

  • È più conciso : se si digita in modo dinamico tutto il codice della caldaia in modo estraneo, è possibile rimuovere un sacco di codice estraneo: dichiarazioni di tipo, logica di tipografia, ecc. A parità di altre condizioni, il codice più breve è leggermente più veloce da scrivere, ma soprattutto può essere più veloce da leggere e manutenzione (poiché non è necessario scorrere molte pagine di codice per avere un'idea di ciò che sta accadendo)
  • Tecniche di "hacking" più semplici come la tipizzazione delle anatre e il patching delle scimmie possono ottenere risultati molto rapidamente (anche se potrebbero confondervi in ​​seguito ...)
  • Più interattivo : la tipizzazione dinamica è probabilmente più adatta per la programmazione interattiva, simile a REPL, per la prototipazione rapida, il debug in tempo reale di istanze di programmi in esecuzione o persino la codifica live.
  • I casi di test possono rilevare gli errori di runtime - supponendo che tu stia utilizzando TDD o almeno abbia una buona suite di test, questo dovrebbe rilevare eventuali problemi di digitazione nel tuo codice.
  • Migliore polimorfismo : i linguaggi dinamici sono potenzialmente più propensi a incoraggiare la creazione di funzioni e astrazioni polimorfiche, che possono aumentare la produttività e il riutilizzo del codice. Il clojure, ad esempio, fa un grande uso del polimorfismo dinamico nelle sue molte astrazioni .
  • Prototipi : i modelli di dati / oggetti basati su prototipi sono, a mio avviso, più potenti e flessibili rispetto alle gerarchie ereditarie tipicamente statiche. I linguaggi dinamici hanno maggiori probabilità di consentire o incoraggiare un approccio basato sui prototipi, Javascript è un ottimo esempio.

Ragioni per cui la tipizzazione statica è più produttiva:

  • Migliore design : essere costretti a pensare in anticipo ai tipi di valori nel software può spingerti verso soluzioni più logiche e più pulite. (Dico can - è ancora possibile progettare codice davvero pessimo ...)
  • Migliore controllo del tempo di compilazione : la digitazione statica può consentire di rilevare più errori al momento della compilazione. Questo è un enorme vantaggio ed è probabilmente la cosa migliore delle lingue tipicamente statiche in generale.
  • Completamento automatico : la digitazione statica può anche fornire ulteriori informazioni all'IDE, in modo che il completamento automatico del codice o della ricerca della documentazione sia più efficace.
  • Scoraggia gli hack : devi mantenere la disciplina dei tipi nel tuo codice, che probabilmente sarà un vantaggio per la manutenibilità a lungo termine.
  • Inferenza del tipo : in alcune lingue (ad es. Scala) questo può darti molti dei vantaggi concisi dei linguaggi dinamici che manterranno comunque la disciplina del tipo.

In media la mia conclusione (dopo molti anni di esperienza su entrambi i lati della recinzione) è che la digitazione dinamica può essere più produttiva a breve termine, ma alla fine diventa difficile da mantenere se non si hanno ottime suite di test e disciplina di test.

D'altra parte, in realtà preferisco gli approcci tipicamente statici in generale, perché penso che i vantaggi di correttezza e il supporto degli strumenti offrano una migliore produttività a lungo termine.


14
+1, risposta molto dettagliata. Il valore del punto "Migliore controllo del tempo di compilazione" non può essere sottolineato abbastanza.
NoChance,

8
Insieme a Type Inference, c'è anche un sovraccarico in stile Haskell, modelli C ++, generici e forse alcune altre funzionalità linguistiche che offrono alcuni dei vantaggi della tipizzazione Duck all'interno di un framework di tipizzazione statica - purché l'oggetto fornisca l'interfaccia necessaria (esso "cacca come un'anatra") puoi usarlo, quasi indipendentemente da quel tipo di oggetto nominale. Il "quasi" è perché alcuni approcci richiedono un tipo di dichiarazione "questo tipo ciondola come il tipo rilevante di anatra" - ad esempio la dichiarazione di "classe" in Haskell.
Steve314,

45
Devo dissentire fortemente dalla tua affermazione che "il codice più breve ... è più veloce da leggere e mantenere". C'è un passaggio intermedio, capire il codice. Ho dovuto mantenere il codice di altre persone sia in Delphi che in JavaScript, e il codice Delphi è molto più facile da capire perché è più dettagliato. E soprattutto perché il codice Delphi ha dichiarazioni di tipo e JavaScript no. Quando si ha a che fare con qualcosa di più complesso dei primitivi, le dichiarazioni di tipo rendono banale vedere quali sono le variabili e cosa possono fare, che è conoscenza essenziale per i lavori di manutenzione.
Mason Wheeler,

21
Mi permetto di non essere d'accordo con la maggior parte dei motivi indicati qui. Prendi Haskell, che probabilmente ha il sistema di tipi più rigoroso là fuori. Ha un REPL (in realtà almeno due), presenta un polimorfismo molto potente facendo corrispondenze di modelli sui costruttori ed è conciso come si può sperare - molto più di Javascript o Python. Quindi immagino che alcuni dei motivi che menzioni siano accidentali piuttosto che inerenti a linguaggi tipicamente vaghi.
Andrea,

15
Non darei troppa fiducia ai "casi di test". Non puoi confrontarli con un buon sistema di tipi. Un sistema di tipi fornisce una prova che la tua funzione sarà già chiamata con almeno i parametri corretti di tipo, mentre i casi di test possono solo fornire prove empiriche. Eppure anche questa evidenza è raccolta da un ambiente artificiale.
Ingo,

56

Con i linguaggi dinamici puoi scrivere codice schifoso più velocemente di quando usi una lingua digitata.

Dopo aver creato rapidamente il tuo enorme mucchio di cose dinamiche, puoi tranquillamente passare a un altro progetto senza preoccuparti della manutenzione a lungo termine.

Questo è un aumento della produttività :)

Sto scherzando, ma dopo essere stato coinvolto in un progetto usando il "linguaggio dinamico", sono stato spaventato dalla quantità di test, documentazioni e convenzioni non necessari che devi affrontare se vuoi avere un prodotto funzionante.
E con la gioia di molti errori di runtime che potrebbero essere stati rilevati durante la compilazione.
Oh, ho anche dimenticato di parlare di tutti quegli hack e voodo che la meta-programmazione ti ha permesso di introdurre nel tuo codice!

Quindi l'aumento di produttività potrebbe essere un mito per progetti medio / grandi nel corso della sua vita.


11
Sì, la mia esperienza è la stessa. Uno script perl di 100 righe è ok, e senza strumenti così grandi ci saremmo persi. Ma un progetto perl di 100k line sarà molto probabilmente un incubo.
Ingo,

3
... e poi hai JavaScript (non solo dinamico ma anche debolmente digitato).
Den,

16

Esiste anche una visione teorica di questo problema: un sistema di tipo statico è essenzialmente un proverore di teoremi specializzato che accetta il programma solo quando può dimostrarne la correttezza del tipo. Tutti i sistemi di tipo statico rifiutano alcuni programmi validi perché nessun sistema di tipo statico decidibile è abbastanza potente da dimostrare tutti i possibili programmi di tipo corretto.

Si potrebbe obiettare che quei programmi che non sono provabili da un typechecker statico sono hack e / o cattivi stili, ma se hai già un programma valido e il typechecker non lo accetta, sicuramente comprometterà la tua produttività nel breve periodo.

Alcuni casi in cui potresti notare che il controllo del tipo si mette in mezzo è con contenitori generici e co-/ contraddizione in argomenti e tipi di ritorno.


18
Al contrario, se hai inserito erroneamente un programma errato , il compilatore ti informa immediatamente e evidenzia la linea errata. questo migliora la tua produttività, se paragonato al notare un test fallito e al debug per trovare l'errore.
MarkJ

5
i contenitori generici e la co-/ contravarianza esplicita sono pensati per "mettersi in mezzo" se si sbaglia. qual è il vantaggio della compilazione del codice che fallirà in fase di esecuzione?
M. Stramm,

Di solito il lavoro viene considerato 0% eseguito fino a quando non viene eseguito correttamente tutti i test. Solo così i tuoi progressi possono essere considerati più che niente. Con questo in mente, non penso che valga la pena misurare la produttività su qualcosa che non è ancora stato completato.
Pijusn,

-1 Non affronta la vera domanda ("guadagni di produttività", ricordi?) Inoltre, probabilmente non vorrai nemmeno scrivere quei "programmi validi che il sistema di tipo rifiuta". Solo perché puoi non significa che dovresti. E perché dovresti anche avere un "programma valido" che il typechecker rifiuta? Cosa, stavi codificando un programma Javascript e all'improvviso hai provato a farlo compilare in Java?
Andres F.

Quei programmi validi che il sistema di tipo rifiuta possono aiutare ad accorciare il tuo codice portando così a meno errori che il sistema di tipi non riesce a capire (meno codice = meno errori). Il compilatore / IDE che evidenzia la riga può essere eseguito in linguaggi dinamici con valori di test (ad es. Sviluppo guidato da REPL) in modo da poter vedere i valori intermedi e che possono rilevare errori che il sistema di tipi non può così come errori di tipo. È inoltre possibile utilizzare l'inferenza di tipo statico per fornire avvisi di tipo.
aoeu256,

15

Un vantaggio che ho riscontrato con la maggior parte dei linguaggi dinamici è che facilitano la scrittura di codice più generico. È molto più facile scrivere a un livello superiore di astrazione quando non è necessario combattere il sistema di tipi per farlo.

Non devi pensarci troppo: scrivere codice che fa qualcosa di non banale con qualsiasi oggetto in Java è difficile e probabilmente richiede una riflessione che è sostanzialmente tipizzata in modo dinamico; con qualcosa come JavaScript, scrivere una funzione che fa qualcosa di interessante per tutti gli oggetti è una seconda natura. Un esempio perfetto potrebbe essere una funzione che ho scritto di recente che prende un oggetto e sostituisce tutti i suoi metodi con quelli che fanno la stessa cosa ma attivano anche un evento. Non ho idea di come affrontare qualcosa di simile in Java. Tuttavia, non sono sicuro di quanto ciò sia dovuto ai sistemi di tipo e quanto sia dovuto ad altre differenze linguistiche.

Tuttavia, di recente ho iniziato a utilizzare Haskell. Haskell mi permette di scrivere un codice astratto e generico con la stessa facilità con cui ho usato qualsiasi linguaggio tipicamente dinamico. Il mio esempio Java / JavaScript sopra non ha senso in Haskell perché non ha oggetti, metodi, eventi o persino molte mutazioni, ma altri tipi di codice generico sono davvero facili da scrivere.

In effetti, Haskell può scrivere un codice generico che le lingue tipizzate dinamicamente non possono; un esempio perfetto è la readfunzione che è sostanzialmente l'opposto di toString. È possibile ottenere un Into un Doubleo qualsiasi tipo desiderato (purché sia ​​in una determinata classe di tipo). Si può anche avere polimorfici costanti , in modo da maxBoundpoter essere il massimo Int, Double, Char... ecc., Il tutto a seconda del tipo che si suppone di essere.

La mia teoria ora è che il guadagno di produttività derivante dall'uso di un linguaggio dinamico è sempre comparato a linguaggi come Java con sistemi di tipo meno capaci, più dettagliati e meno flessibili.

Tuttavia, anche il sistema di tipi di Haskell presenta alcuni fastidiosi problemi che non avresti in un linguaggio tipizzato in modo dinamico. Il più grande che mi ha infastidito è il modo in cui i numeri vengono gestiti; per esempio, devi scherzare con il sistema di tipi da usare length(di un elenco) come doppio, qualcosa con cui non avresti problemi senza un sistema di tipi. Un'altra cosa fastidiosa in cui mi imbatto è lavorare con Word8(un tipo int senza segno) e funzioni che si aspettano Int.

Quindi, in definitiva, non avere un sistema di tipi rende più semplice scrivere codice generico senza pensare troppo ed evita anche fastidiose insidie ​​dei sistemi di tipo. Non devi mai combattere il sistema dei tipi in un linguaggio dinamico, ma non puoi nemmeno fare affidamento su di esso.


1
Sì, per qualche motivo i sistemi numerici sono difficili da ottenere. In scala è anche un casino. Penso che i sistemi di tipo dinamico vincano a mani basse su semplici tipi di sistemi statici in termini di facilità di lavoro con esso, ma perdono da quelli più avanzati (come Scala, Haskell, ML ecc., Che utilizzano tutti varianti del sistema-F ).
Edgar Klerks,

3
La tua risposta è ben intenzionata, ma presenta errori. Primo, non è vero che i linguaggi dinamici "non hanno un sistema di tipi", quindi non può essere questo il motivo per cui "facilitano la scrittura di codice generico". Non lo rendono più facile, come mostra il tuo controesempio con Haskell (hai smascherato la tua affermazione!). "Non devi mai combattere il sistema dei tipi" è falso: combatti ogni volta che devi correggere un bug causato da un insufficiente controllo statico dei caratteri. Infine, forzare esplicitamente il Intreso da una lista è banale; esempio 1.0 + fromIntegral (length myList):, cioè basta usare fromIntegral.
Andres F.

2
Infine, "scrivere codice velocemente"! = "Essere più produttivo". Il tuo codice deve funzionare! Se si scrive software difettoso che in seguito è necessario dedicare tempo al debug e alla correzione, non si è produttivi.
Andres F.

"senza pensare troppo" bandiera rossa per ciò che la maggior parte della gente intende quando parlano di lingue più tipicamente "più produttive"
Ataraxia,

Se i sistemi di tipo hanno davvero migliorato la produttività, dove sono tutte le applicazioni utili in Haskell o Idris? Penso che cose come quanto sia facile capire l'errore di tipo, la "patchability" (capacità di modificare l'applicazione in modi imprevedibili) e il controllo dell'errore al 90% di test e inferenza di tipo potrebbero essere più importanti.
aoeu256,

7

D: Ho spesso sentito l'affermazione secondo cui le lingue tipizzate dinamicamente sono più produttive delle lingue tipizzate staticamente. Quali sono i motivi di questa affermazione? "

Questo ha ragioni storiche. Se torni indietro di qualche decennio, i linguaggi dinamici erano indiscutibilmente molto più produttivi dei linguaggi statici (anche se significativamente più lenti). Perl è chiaramente molto più produttivo di C se conosci entrambi e il compito a portata di mano lo consente. Ma nel tempo le lingue si sono indebitate molto l'una dall'altra e le lingue più recenti stanno riducendo il divario (sia in termini di produttività che di prestazioni).

Ecco alcuni punti da considerare:

Raccolta dei rifiuti : la raccolta dei rifiuti è un enorme aumento della produttività. Credo che Java sia stato il primo linguaggio statico tradizionale con GC. Prima di questo, statico significava essenzialmente la gestione manuale della memoria. (Nota: qui e nel seguito sto solo prendendo in considerazione i linguaggi mainstream. Esistono molte lingue sperimentali e di nicchia che forniranno controesempi a qualsiasi punto che faccio.)

Sicurezza della memoria : è un miglioramento della produttività che non devi preoccuparti di spararti al piede. Prima di linguaggi statici "gestiti" come Java, statico significava in genere l'accesso diretto alla memoria. Anche il debug fa parte della produttività e l'accesso alla memoria non sicuro può portare a bug davvero oscuri.

Sistemi di tipo ingombranti. Prima dell'introduzione di tipi parametrici (come modelli o generici) nei linguaggi statici, le limitazioni dei sistemi di tipi statici erano spesso un peso. Ad esempio, in Java è stato necessario eseguire il downcast esplicito ogni volta che si è scelto un elemento da una raccolta. Quindi hai il sovraccarico sintattico di un cast e nessuna sicurezza di tipo. Considerando come le collezioni onnipresenti sono in programmazione, questo è stato un grosso svantaggio.
Dover dichiarare il tipo di tutto è un sacco di tipizzazione ridondante, ma con l'inferenza del tipo moderno, questo può essere ridotto in modo significativo.

Grande libreria standard. Python è stato pubblicizzato come "batterie incluse" a causa della grande libreria standard. Questo rispetto a C che ha una libreria standard molto minimalista. Ma con piattaforme come Java e .net, una vasta libreria standard sta diventando standard e linguaggi più recenti come Scala e F # ereditano questo "gratuitamente".

Strutture di dati di prima classe. Linguaggi dinamici come Perl e Python hanno strutture dati di prima classe integrate come elenchi e mappe con comode scorciatoie sintattiche per operazioni comuni. Rispetto a questo, C non ha raccolte incorporate tranne le matrici di dimensioni fisse.

Chiusure e sintassi lambda : in genere i linguaggi dinamici hanno avuto questo dall'inizio, ma i linguaggi statici hanno adottato questo, più recentemente Java.

REPL la capacità di testare rapidamente frammenti di codice in modo interattivo è un grande vantaggio. Ma sebbene gli strumenti IDE, come la finestra "immediata" in Visual Studio, i linguaggi statici possano emularlo in una certa misura.

Strumenti avanzati : oltre ai punti precedenti in cui i linguaggi statici si stanno avvicinando alla praticità dei linguaggi dinamici, i moderni editor stanno sfruttando l'analisi statica in modo che i linguaggi dinamici abbiano difficoltà a corrispondere. Ad esempio, i redattori possono fornire rifatturazioni automatiche sicure, cosa che a rigore è impossibile in un linguaggio dinamico.

In conclusione: storicamente era vero, ma oggi la risposta è meno chiara.


D: Quindi: cosa c'è da dire sulla produttività con la tipizzazione dinamica che è davvero un vantaggio del modello di tipo stesso?

È in qualche modo difficile separare il modello di tipizzazione dinamica dai linguaggi dinamici, ma ad esempio C # ha adottato più funzioni più dinamiche nel tempo, anche se il suo nucleo è un linguaggio statico. Questa è davvero una prova del vantaggio del modello di tipo dinamico. Esempi:

Reflection Reflection è fondamentalmente una funzione di digitazione dinamica. Ispeziona i tipi di oggetto in fase di runtime rispetto al tempo di compilazione. Quando è stato introdotto, era un po 'malvisto, ma in C # l'uso della riflessione diventa sempre più onnipresente, ad esempio ASP.Net MVC usa pesantemente la riflessione.

Attributi Gli attributi sono un esempio di digitazione dinamica. È possibile aggiungere attributi arbitrari a una classe in fase di compilazione, quindi ispezionare in fase di esecuzione (tramite la riflessione) e manipolare oggetti basati su di essa. Qualcosa come MEP è fondamentalmente un framework di estensione basato su un modello di tipo dinamico.

Linq a SQL, EF mv. I vari trasformatori Linq ispezionano le query come oggetti runtime e generano sql al volo. Non diventa più dinamico dell'ispezione del codice in fase di esecuzione. CodeDom è l'altro lato della medaglia, in cui il codice può essere generato in fase di esecuzione

Roslyn Roslyn fondamentalmente implementa eval, che una volta era considerata la caratteristica distintiva di un linguaggio veramente dinamico.

Dinamico Il dynamictipo è la caratteristica più esplicitamente dinamica in C # ed è pubblicizzata nel rendere più semplice e produttiva l'interazione con oggetti e linguaggi esterni. Ma è anche usato in Asp.net MVC per comodità.

Il vantaggio di tutte le funzionalità sopra riportate mostra che il modello dinamico presenta vantaggi evidenti anche in un linguaggio statico con tipi parametrizzati, tipi strutturali e inferenza di tipo.


Non mi piace davvero questa risposta, perché quasi tutti i punti non affrontano la domanda principale, "Qual è il presunto aumento di produttività della digitazione dinamica ?" lingue non dinamiche .
tata

@nanny potresti approfondire la tua differenza percepita tra lingue tipizzate dinamiche e lingue dinamiche? (è una di quelle cose sfocate). Potresti dare un esempio di un linguaggio tipizzato dinamico che non è un linguaggio dinamico, insieme a definizioni chiare di ciascuno?

@nanny: la domanda in realtà pone delle "lingue tipizzate dinamicamente", non solo della "tipizzazione dinamica".
Jacques B

@MichaelT Mi dispiace non essere stato chiaro. La digitazione dinamica è un aspetto di tutti i linguaggi dinamici. Questa risposta parla di altri aspetti che, storicamente, tendono a venire con i linguaggi dinamici, senza affrontare effettivamente la parte di battitura dinamica.
tata

1
@Nanny: Fondamentalmente sto rispondendo a questa domanda: "Ho spesso sentito l'affermazione secondo cui le lingue tipizzate dinamicamente sono più produttive delle lingue tipicamente statiche. Quali sono i motivi di questa affermazione?" - Ritengo che le ragioni di questa affermazione siano storiche e correlate non solo alla tipizzazione dinamica, ma anche ad altre funzionalità che migliorano la produttività dei linguaggi dinamici.
Jacques B

6

Tutte le funzionalità del linguaggio moderno sono così grandi che la tipizzazione statica e dinamica da sola non ha molto peso.

La regola è che migliore è la tua lingua, più breve è il tuo codice. È abbastanza semplice. Java mostra come la tipizzazione statica possa andare terribilmente storto, il che dà ai suoi avversari molto da nutrire. Le funzionalità del linguaggio mal progettate generalmente hanno un costo, e la digitazione statica in Java è in primo luogo una funzione obbligatoria (altrimenti la maggior parte delle persone probabilmente non la userebbe nemmeno) e in secondo luogo eseguita male.
Questo è il motivo per cui, in confronto, la maggior parte dei linguaggi dinamici risplende, anche se direi che PHP non migliora davvero la tua vita nel complesso generale (almeno fino a poco tempo fa), a causa di molte altre stranezze non correlate ai sistemi di tipo.

D'altra parte hai molte lingue con sistemi di tipo espressivo che non ti ostacolano e che non sono nemmeno obbligatori. E alcuni di essi consentono persino di incorporare codice non tipizzato, ogni volta che è necessario sfuggire al sistema dei tipi.

Personalmente, uso haXe, che è un linguaggio con inferenza di tipo, sottotipo sia nominale che strutturale, codice non tipizzato opzionale, tipi di funzione di prima classe, tipi di dati algebrici e macro lessicali (non abbastanza maturi ma estremamente potenti), evitando al contempo la sintassi arcana. Dopo aver usato haXe per circa 3 anni, sono giunto a una semplice conclusione:

La programmazione diventa molto più semplice, quando il tuo linguaggio non ti blocca nelle scelte religiose sui paradigmi ma cerca di essere solo un buon strumento. Ci sono un certo numero di lingue statiche e dinamiche e lingue miste , che ci riescono. Alcuni sono facili da imparare, molto difficili da padroneggiare.
Il loro potere deriva dal modo in cui le loro singole caratteristiche possono essere composte per creare facilmente soluzioni semplici a problemi complessi. Ciò preclude una certa ortogonalità che può essere raggiunta solo attraverso un delicato equilibrio di inclusione o omissione di tutte le caratteristiche linguistiche esplorate finora. Se provassi ad aggiungere la tipizzazione statica a Ruby, lo paralizzeresti, se provassi a toglierlo da Haskell, lo schiacceresti. Al contrario: se lo togliessi da C, le persone difficilmente se ne accorgerebbero e se lo togliessi da Java, alcuni potrebbero ringraziarti.

Per esperienza personale, posso dirti questo: mi piace Ruby. Ha ampliato i miei orizzonti e il modo in cui progetto i sistemi. IMHO dovrebbe essere usato per insegnare alle persone la programmazione in primo luogo. È discreto, potente, conciso, divertente. Capisco perché a qualcuno che viene da una lingua ortodossa piacerà.
A lungo termine, tuttavia, la tipizzazione statica consente di rimandare il lavoro all'analizzatore statico e con l'inferenza del tipo questo viene sostanzialmente a costo zero. Il risultato è un codice che è più facile da mantenere e spesso viene eseguito più velocemente.

Ma ancora una volta, la digitazione statica da sola non può fare nulla. È una questione di combinazione. Penso che da qualche parte tra F #, Scala, Nemerle, OCaml o haXe puoi trovare il tuo ottimismo personale. Ma alla fine dipende da te, perché il linguaggio dovrebbe permetterti di incorporare i tuoi pensieri senza sforzo, invece di costringerti a piegarli attorno ad esso. Dopotutto, nulla produce più guadagno di produttività, se la programmazione è divertente.


"La regola è, migliore è la tua lingua, più breve è il tuo codice." Questo potrebbe essere dovuto all'opinione a un certo livello, ma non credo che questa affermazione sia accurata. Il codice più breve non offre troppi vantaggi da solo, oltre a comportare una minore digitazione al momento della scrittura e forse occupare meno spazio su disco (che non è comunque un fattore nei linguaggi compilati). Penso che il segno di un buon linguaggio stia trasmettendo quante più informazioni su ciò che sta facendo nel modo più conciso possibile. La digitazione dinamica non è molto auto-documentante e, di conseguenza, perde la manutenibilità
Ataraxia,

È possibile integrare il codice digitato dinamico con informazioni come valori predefiniti / argomenti di parole chiave, tipi ottenuti dall'inferenza di tipo, inferenza di tipo dinamica da un compilatore JIT o semplicemente registrando tutte le funzioni [passare attraverso ogni funzione o classe in un programma in esecuzione e sostituirli con un versione della funzione che registra i suoi argomenti / risultati). Quindi puoi vedere il registro delle precedenti esecuzioni di una funzione. Un'altra idea è quella di rifiutare il codice che non ha annotazioni di tipo, contratti di runtime o test di sessione REPL di esempio, ma offre allo sviluppatore la possibilità di scegliere uno dei tre.
aoeu256,

3

Personalmente, l'unica ragione per cui la digitazione dinamica sarebbe di aiuto è se sei un dattilografo veramente lento o se costruisci funzioni / metodi / whatevers giganti che sono difficili da navigare. Devi anche affrontare l'intero problema di test dell'unità. I tipi dinamici richiedono (a meno che non ti piaccia scrivere il codice non funzionante) test di unità vigorosi (per garantire che i tipi dinamici non esplodano in modo imprevisto (cioè la variabile è principalmente anatra, ma a volte dcuk accidentalmente)). La statica cercherà molto di più per impedirlo (e sì, puoi fare l'argomento per vigorosi test unitari)


0

Penso innanzitutto che sia necessario definire la "produttività". Che cosa significa "produttività" e include?

Se per "più produttivo" intendi scrivere meno righe di codice per implementare la stessa funzionalità, allora sì, i linguaggi di programmazione a digitazione dinamica sono più "produttivi" rispetto ai linguaggi a scrittura statica.

Tuttavia, se si considera anche il tempo impiegato per il debug e la correzione dei bug, i linguaggi di tipizzazione dinamica potrebbero non essere così produttivi, poiché i linguaggi di tipizzazione dinamica tendono a spingere il controllo degli errori in runtime mentre, al contrario, i linguaggi di tipizzazione statica può eseguire un controllo degli errori in fase di compilazione. Poiché è comunemente accettato che, di solito, più tardi viene trovato un bug, più costoso è risolvere il bug. Pertanto, il codice di tipizzazione dinamica può risultare generalmente uguale o forse anche inferiore alla produttività rispetto al codice di tipizzazione statica.


In generale, non è vero che è possibile scrivere una funzione in meno righe usando un linguaggio dinamico. Quali lingue stai confrontando, comunque?
Andres F.

@AndresF. Oh, uso principalmente Python e C ++.
Yaobin,

1
Ok, ma non puoi generalizzare dinamico vs statico quando stai effettivamente confrontando Python e C ++. Il C ++ non è un esempio particolarmente rappresentativo di un linguaggio con tipizzazione statica. Esistono linguaggi tipicamente statici estremamente concisi, che consentono più o meno di scrivere programmi brevi come con Python. Quindi, in generale, la tua affermazione è falsa.
Andres F.

Sì, ma cosa succede se si modifica il programma mentre è ancora in esecuzione? Eventuali problemi di runtime si verificano semplicemente e puoi risolverli proprio lì. In Lisp, ogni volta che ricevi un errore puoi semplicemente correggere il tuo programma e poi continuare a eseguirlo ... Sì, per le annotazioni del tipo di percorsi più complessi sarebbe buono [forse puoi usare una digitazione graduale come mypy & lisp], ma quei percorsi più complessi hanno anche la possibilità di errori non di tipo, quindi evitare percorsi complessi in qualsiasi lingua può essere una buona idea.
aoeu256,

-1

Il grande vantaggio della digitazione dinamica è la produttività.

Python, Ruby ecc. Hanno molti altri booster di produttività oltre alla tipizzazione dinamica (parametri predefiniti, dizionari come tipi incorporati ecc. Ecc.) L'effetto cumulativo sulla produttività del programmatore è impressionante.

Le penalità in termini di velocità (o mancanza di!) E consumo di risorse non sono male come ci si aspetterebbe e nella maggior parte dei casi sono più che compensate dalla velocità e flessibilità dello sviluppo.

C'è un (molto vecchio!) La carta sul tema qui. È uno dei pochi studi condotti correttamente sulla produttività del programmatore e molte delle conclusioni sono ancora valide.

Ciò che sarebbe (probabilmente) diverso se lo studio fosse condotto oggi:

  1. Le JVM Java sono migliorate oltre il riconoscimento.
  2. Gli IDE moderni avrebbero migliorato la produttività dei codificatori C ++ e Java, ma, facendo poca differenza per i linguaggi di scripting.
  3. C # sarebbe incluso e probabilmente si troverebbe nello stesso parco palla di Java ma leggermente meglio.

Quindi il messaggio è a meno che le prestazioni non siano un problema davvero serio. I linguaggi dinamici aumenteranno la tua produttività.


2
La mia chiarezza è esattamente ciò che fa la digitazione dinamica per aumentare la produttività. Il documento è interessante, tuttavia si tratta di un programma molto piccolo, e non sono sicuro di come questo si ripercuota su molte migliaia di righe di codice nella maggior parte dei programmi.
Hans-Peter Störr,

5
Tale studio utilizza solo C, C ++ e Java come esempi di linguaggi statici, quindi tenta di applicare le conclusioni trovate ai linguaggi di programmazione tradizionali in generale. Tutte e tre le lingue condividono la stessa sintassi di base, con gli stessi difetti intrinseci che riducono la prduttività, rendendo non valido il confronto. Non è che i linguaggi statici siano improduttivi, è che la famiglia C non è produttiva. Se avessero incluso un dialetto Pascal nei loro test, molto probabilmente avrebbero raggiunto alcune conclusioni diverse.
Mason Wheeler,

@mason - ci sono pochissimi studi oggettivi reali in questo campo. Questo è uno dei pochi studi reali con numeri reali ecc. Il programma "campione" non è banale! Combina elementi di gestione dei dizionari, algoritmi complessi e grandi volumi di dati. L'elevata percentuale di tentativi falliti e di crash conferma la natura non banale dell'attività.
James Anderson,

2
-1 Non stai dicendo molto su ciò che rende le lingue tipizzate dinamiche più produttive. I parametri e i dizionari predefiniti possono essere trovati in linguaggi tipizzati statici come ad esempio Scala.
Jonas,

1
@JamesAnderson Ancora peggio, il documento a cui ti sei collegato non supporta nemmeno il tuo punto. Confronta "linguaggi di scripting" (spesso dinamici) con " linguaggi convenzionali " (spesso statici). Ora, dimmi, che cosa sono esattamente le lingue "convenzionali"? Pensi che sia uguale all'insieme delle lingue con la tipizzazione statica? Ancora peggio, il giornale non è così vecchio. Nel 2000, esistevano già molte grandi lingue con la tipizzazione statica che erano probabilmente più produttive delle lingue dinamiche.
Andres F.
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.