Digitazione graduale: "Quasi tutte le lingue con un sistema di tipo statico hanno anche un sistema di tipo dinamico"

19

Questo reclamo di Aleks Bromfield afferma:

Almost every language with a static type system also has a dynamic type system. Aside from C, I can't think of an exception

È un reclamo valido? Capisco che con Reflection o Caricamento di classi in fase di esecuzione Java diventa un po 'come questo - ma questa idea di "digitazione graduale" può essere estesa a un gran numero di lingue?

    
posta hawkeye 28.12.2013 - 23:07
fonte

6 risposte

36

Originale tweeter qui. :)

Prima di tutto, sono un po 'divertito / scioccato dal fatto che il mio tweet sia preso così sul serio! Se avessi saputo che sarebbe stato ampiamente diffuso, avrei impiegato più di 30 secondi a scriverlo!

Thiago Silva ha ragione a sottolineare che "statico" e "dinamico" descrivono più accuratamente il tipo controllo , piuttosto che il tipo sistemi . In effetti, non è proprio esatto dire che anche una lingua è tipizzata staticamente o dinamicamente. Piuttosto, un linguaggio ha un sistema di tipi e un'implementazione di tale linguaggio potrebbe far rispettare il sistema di tipi usando il controllo statico, o il controllo dinamico, o entrambi, o nessuno dei due (anche se non sarebbe un'implementazione linguistica molto accattivante!).

Come accade, ci sono alcuni tipi di sistemi (o caratteristiche di sistemi di tipi) che sono più suscettibili di controllo statico, e ci sono alcuni sistemi di tipi (o caratteristiche di sistemi di tipi) che sono più suscettibili di controllo dinamico. Ad esempio, se la tua lingua ti permette di specificare nel testo di un programma che un particolare valore deve sempre essere un array di numeri interi, allora è ragionevolmente semplice scrivere un controllo statico per verificare quella proprietà. Al contrario, se la tua lingua ha sottotitoli e se consente il downcasting, allora è ragionevolmente semplice verificare la validità di un downcast in fase di runtime, ma estremamente difficile farlo in fase di compilazione.

Ciò che intendevo veramente con il mio tweet è semplicemente che la stragrande maggioranza delle implementazioni linguistiche esegue alcuni quantità di controllo dinamico dei tipi. Oppure, equivalentemente, la stragrande maggioranza delle lingue ha alcune caratteristiche che sono difficili (se non impossibili) da controllare staticamente. Downcasting è un esempio. Altri esempi includono l'overflow aritmetico, il controllo dei limiti dell'array e il controllo nullo. Alcuni di questi possono essere controllati staticamente in alcune circostanze, ma in generale è difficile trovare un'implementazione linguistica che non esegua alcun controllo in fase di runtime.

Questa non è una brutta cosa. È solo un'osservazione che ci sono molte proprietà interessanti che vorremmo applicare ai nostri linguaggi e che in realtà non sappiamo come controllare staticamente. Ed è un promemoria che distinzioni come "tipi statici" e "tipi dinamici" non sono così netti come alcune persone vorrebbero far credere. :)

Un'ultima nota: i termini "strong" e "debole" non sono realmente usati nella comunità di ricerca del linguaggio di programmazione, e non hanno realmente un significato coerente. In generale, ho scoperto che quando qualcuno dice che una lingua ha una "tipizzazione strong" e che in qualche altro linguaggio c'è "una digitazione debole", stanno davvero dicendo che la loro lingua preferita (quella con "strong tipizzazione") impedisce loro di facendo un errore che l'altra lingua (quella con "digitazione debole") non - o al contrario, che la loro lingua preferita (quella con "digitazione debole") permetta loro di fare qualcosa di interessante che l'altra lingua (il uno con "strong tipizzazione") non lo fa.

    
risposta data 29.12.2013 - 06:49
fonte
6

Ebbene si. Puoi avere sacchi di proprietà in qualsiasi linguaggio tipizzato staticamente. La sintassi sarà terribile mentre allo stesso tempo otterrai tutti gli svantaggi del sistema digitato dinamicamente. Quindi non c'è alcun vantaggio a meno che il compilatore non ti permetta di usare una sintassi migliore, qualcosa come C # con dynamic .

Inoltre, puoi farlo abbastanza facilmente anche in C.

In risposta ad altre risposte: penso che le persone stiano scambiando una digitazione statica / dinamica con una tipizzazione strong / debole. La tipizzazione dinamica riguarda la possibilità di modificare la struttura dei dati in fase di runtime e il codice è in grado di utilizzare dati che si adattano esattamente a ciò di cui il codice ha bisogno. Questo è chiamato Duck Typing .

Il menzionare la riflessione non significa raccontare l'intera storia, perché la riflessione non ti consente di modificare la struttura esistente dei dati. Non puoi aggiungere un nuovo campo a una classe o struttura in C, C ++, Java o C #. Nei linguaggi dinamici, l'aggiunta di nuovi campi o attributi a classi esistenti non è solo possibile, ma in realtà abbastanza comune.

Ad esempio, guarda Cython , il compilatore Python-to-C. Crea codice C statico, ma il sistema di tipi mantiene ancora la sua natura dinamica. C è un linguaggio tipizzato staticamente, ma è in grado di supportare la tipizzazione dinamica da Python.

    
risposta data 28.12.2013 - 23:28
fonte
5

Le lingue dinamiche sono lingue statiche . Quello che viene comunemente chiamato "digitazione dinamica" è in realtà un caso speciale di digitazione statica, il caso in cui ti sei limitato a un solo tipo. Come esperimento mentale, immagina di scrivere un programma in Java o C # usando solo Object variabili / campi / parametri e down-casting immediatamente prima di chiamare il metodo any . Sarebbe più corretto chiamare linguaggi come Python o Javascript "unityped". (Questa affermazione probabilmente confonderà / disturberà molte persone, considerando che un tale programma Java o C # userebbe molti sottotipi, ma questo perché il linguaggio OOP medio confonde tipi e classi. Leggi il post del blog per maggiori dettagli.)

Nota che anche C ha una digitazione "dinamica" - puoi lanciare qualsiasi puntatore a un puntatore void (e se la memoria mi serve, char ) e tornare indietro. E si noti, inoltre, che non vi è alcun runtime che verifica lì; se ti sbagli, goditi il tuo comportamento indefinito!

    
risposta data 18.02.2014 - 21:00
fonte
2

La differenza tra digitazione statica e dinamica è quando viene controllato il tipo di un valore: tempo di compilazione e tempo di esecuzione. Nelle lingue in cui valori portano il loro tipo con essi (ad es. Oggetti Java), puoi sempre ricorrere alla digitazione dinamica anche quando la lingua effettivamente preferisce la digitazione statica. Ecco un esempio in Java, con un metodo digitato in modo dinamico:

void horribleJava(List untypedList) {
  for (Object o : untypedList)
    ((SpecificType) o).frobnicate();
}

Si noti come viene controllato il tipo di ciascun elemento in fase di runtime. Il metodo equivalente staticamente digitato è:

void goodJava(List<SpecificType> typedList) {
  for (SpecificType o : typedList) {
    o.forbnicate();
  }
}

In C, i valori (e in particolare i puntatori) non mantengono il loro tipo durante il runtime - ogni puntatore equivale a void * . Invece, variabili e le espressioni hanno un tipo. Per ottenere una digitazione dinamica, devi portare tu stesso le informazioni sul tipo (ad esempio come campo in una struttura).

    
risposta data 28.12.2013 - 23:31
fonte
2

La tipizzazione statica e quella dinamica si riferiscono fondamentalmente a come vengono controllati i tipi. La tipizzazione statica significa che la verifica dei tipi di varie variabili o espressioni viene controllata in base al codice effettivo (di solito dal compilatore) mentre in un sistema di tipo dinamico questa verifica viene eseguita solo in fase di esecuzione, dall'ambiente di runtime.

Ciò a cui credo che il testo si riferisca è che anche se i tipi sono effettivamente controllati staticamente, vengono controllati anche in fase di runtime, cioè dinamicamente. Hai giustamente menzionato Java Reflection; la riflessione avviene solo in fase di esecuzione e Java Runtime Environment (JVM) esegue effettivamente il controllo dei tipi quando viene utilizzato il reflection, che in pratica significa controllo dinamico dei tipi.

    
risposta data 28.12.2013 - 23:29
fonte
-1

L'escpetion è sbagliato: C ha anche un importante sistema di tipo dinamico. Semplicemente non lo controlla ("C è strongmente tipizzato, debolmente controllato"). Ad esempio, il trattamento di una struct come double ( reinternpret_cast -style) produce un comportamento non definito, un errore di tipo dinamico.

    
risposta data 04.07.2016 - 09:05
fonte

Leggi altre domande sui tag