Domanda

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

Vedi anche : che cosa è l'amore per linguaggi dinamici (un thread molto più polemico ...)

È stato utile?

Soluzione

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 è da Digitazione statica Dove Possibile digitazione dinamica all'occorrenza: la fine della guerra fredda tra i linguaggi di programmazione di Erik Meijer e Peter Drayton presso Microsoft:

  

I sostenitori della tipizzazione statica sostengono che   i vantaggi della tipizzazione statica   include il rilevamento anticipato di   errori di programmazione (ad es. prevenzione   aggiungendo un numero intero a un valore booleano),   migliore documentazione sotto forma di   firme di tipo (ad esempio incorporando   numero e tipi di argomenti quando   risoluzione dei nomi), più opportunità   per ottimizzazioni del compilatore (ad es.   sostituzione di chiamate virtuali con diretta   chiama quando il tipo esatto di   il ricevitore è noto staticamente),   maggiore efficienza di runtime (ad es. no   tutti i valori devono avere una dinamica   tipo) e un tempo di progettazione migliore   esperienza degli sviluppatori (ad es. conoscenza del   tipo di ricevitore, l'IDE può   presenta un menu a discesa di tutti   membri applicabili). Digitazione statica   i fanatici cercano di farcelo credere   "I programmi ben digitati non possono andare storti".   Anche se questo suona certamente   impressionante, è piuttosto vacuo   dichiarazione. Il controllo statico del tipo è a   astrazione in fase di compilazione di   comportamento di runtime del programma e   quindi è necessariamente solo parzialmente   sano e incompleto. Ciò significa che   i programmi possono ancora sbagliare a causa di   proprietà che non sono tracciate da   controllo del tipo e che ci sono   programmi che mentre non possono andare   non è possibile verificare il tipo di errore. Il   impulso per ridurre la tipizzazione statica   tipo di cause parziali e più complete   i sistemi diventeranno eccessivamente complicati   ed esotico come testimoniano i concetti   come "tipi fantasma" [11] e   "Tipi traballanti" [10]. Questo è come   cercando di correre una maratona con una palla   e catena legata alla gamba e   urlando trionfalmente che quasi   ce l'ho fatta anche se sei stato salvato   dopo il primo miglio.

     

Sostenitori della digitazione dinamica   le lingue sostengono che la tipizzazione statica sia   troppo rigido, e che la morbidezza di   dinamicamente le lingue li rendono   ideale per sistemi di prototipazione   con requisiti mutevoli o sconosciuti,   o che interagiscono con altri sistemi   che cambiano in modo imprevedibile (dati e   integrazione dell'applicazione). Ovviamente,   le lingue tipizzate dinamicamente sono   indispensabile per affrontare veramente   comportamento dinamico del programma come   intercettazione del metodo, caricamento dinamico,   codice mobile, riflessione di runtime, ecc.   Nella madre di tutti i documenti su   scripting [16], sostiene John Ousterhout   che sistemi tipizzati staticamente   i linguaggi di programmazione riducono il codice   riutilizzabile, più dettagliato, non più sicuro,   e meno espressivo che dinamico   linguaggi di scripting digitati. Questo   l'argomento è letteralmente pappagallo da molti   sostenitori di dinamicamente digitato   linguaggi di scripting. Noi lo sosteniamo   questo è un errore e cade nel   stessa categoria dell'argomentazione secondo cui   l'essenza della programmazione dichiarativa è   eliminando l'incarico. O come John   Hughes dice [8], è logico   impossibilità di rendere più una lingua   potente omettendo le funzionalità.   Difendere il fatto che ritardare tutto   il controllo del tipo in fase di esecuzione è positivo   cosa, sta giocando tattiche di struzzo con   il fatto che gli errori dovrebbero essere colti   già nel processo di sviluppo come   possibile.

Altri suggerimenti

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 in realtà garantisce che le prove termineranno , "risoluzione" il problema di arresto .

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'implementazione PersistentVector di Clojure a causa del suo 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 modalità di "escape", per sovrascrivere il controllo statico. Per la maggior parte delle lingue, questi prendono la forma del casting, anche se alcuni (come C # e Haskell) hanno intere modalità che sono contrassegnate come "non sicuro".

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 arrestino in modo anomalo nel 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 funzionalità che sono impossibili o non sicure nei sistemi di tipo dinamico ( conversioni implicite vengono in mente). È 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 della digitazione y " soffiano semplicemente fumo. La digitazione dinamica può "sentire". più veloce in molti casi, ma perde terreno quando si tenta effettivamente di eseguire l'esecuzione della propria fantasia applicazione. 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 tipi e produttività, non esiste un proiettile d'argento.

Nota finale: non preoccuparti delle prestazioni quando si confronta statico 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 nella maggior parte dei casi, la digitazione dinamica non è l'enorme killer delle prestazioni che alcune persone si rendono conto di essere.

Well, both are very, very very very misunderstood and also two completely different things. that aren't mutually exclusive.

Static types are a restriction of the grammar of the language. Statically typed langauges strictly could be said to not be context free. The simple truth is that it becomes inconvenient to express a language sanely in context free grammars that doesn't treat all its data simply as bit vectors. Static type systems are part of the grammar of the language if any, they simply restrict it more than a context free grammar could, grammatical checks thus happen in two passes over the source really. Static types correspond to the mathematical notion of type theory, type theory in mathematics simply restricts the legality of some expressions. Like, I can't say 3 + [4,7] in maths, this is because of the type theory of it.

Static types are thus not a way to 'prevent errors' from a theoretical perspective, they are a limitation of the grammar. Indeed, provided that +, 3 and intervals have the usual set theoretical definitions, if we remove the type system 3 + [4,7]has a pretty well defined result that's a set. 'runtime type errors' theoretically do not exist, the type system's practical use is to prevent operations that to human beings would make no sense. Operations are still just the shifting and manipulation of bits of course.

The catch to this is that a type system can't decide if such operations are going to occur or not if it would be allowed to run. As in, exactly partition the set of all possible programs in those that are going to have a 'type error', and those that aren't. It can do only two things:

1: prove that type errors are going to occur in a program
2: prove that they aren't going to occur in a program

This might seem like I'm contradicting myself. But what a C or Java type checker does is it rejects a program as 'ungrammatical', or as it calls it 'type error' if it can't succeed at 2. It can't prove they aren't going to occur, that doesn't mean that they aren't going to occur, it just means it can't prove it. It might very well be that a program which will not have a type error is rejected simply because it can't be proven by the compiler. A simple example being if(1) a = 3; else a = "string";, surely since it's always true, the else-branch will never be executed in the program, and no type error shall occur. But it can't prove these cases in a general way, so it's rejected. This is the major weakness of a lot of statically typed languages, in protecting you against yourself, you're necessarily also protected in cases you don't need it.

But, contrary to popular believe, there are also statically typed languages that work by principle 1. They simply reject all programs of which they can prove it's going to cause a type error, and pass all programs of which they can't. So it's possible they allow programs which have type errors in them, a good example being Typed Racket, it's hybrid between dynamic and static typing. And some would argue that you get the best of both worlds in this system.

Another advantage of static typing is that types are known at compile time, and thus the compiler can use this. If we in Java do "string" + "string" or 3 + 3, both + tokens in text in the end represent a completely different operation and datum, the compiler knows which to choose from the types alone.

Now, I'm going to make a very controversial statement here but bear with me: 'dynamic typing' does not exist.

Sounds very controversial, but it's true, dynamically typed languages are from a theoretical perspective untyped. They are just statically typed languages with only one type. Or simply put, they are languages that are indeed grammatically generated by a context free grammar in practice.

Why don't they have types? Because every operation is defined and allowed on every operant, what's a 'runtime type error' exactly? It's from a theoretical example purely a side-effect. If doing print("string") which prints a string is an operation, then so is length(3), the former has the side effect of writing string to the standard output, the latter simply error: function 'length' expects array as argument., that's it. There is from a theoretical perspective no such thing as a dynamically typed language. They are untyped

All right, the obvious advantage of 'dynamically typed' language is expressive power, a type system is nothing but a limitation of expressive power. And in general, languages with a type system indeed would have a defined result for all those operations that are not allowed if the type system was just ignored, the results would just not make sense to humans. Many languages lose their Turing completeness after applying a type system.

The obvious disadvantage is the fact that operations can occur which would produce results which are nonsensical to humans. To guard against this, dynamically typed languages typically redefine those operations, rather than producing that nonsensical result they redefine it to having the side effect of writing out an error, and possibly halting the program altogether. This is not an 'error' at all, in fact, the language specification usually implies this, this is as much behaviour of the language as printing a string from a theoretical perspective. Type systems thus force the programmer to reason about the flow of the code to make sure that this doesn't happen. Or indeed, reason so that it does happen can also be handy in some points for debugging, showing that it's not an 'error' at all but a well defined property of the language. In effect, the single remnant of 'dynamic typing' that most languages have is guarding against a division by zero. This is what dynamic typing is, there are no types, there are no more types than that zero is a different type than all the other numbers. What people call a 'type' is just another property of a datum, like the length of an array, or the first character of a string. And many dynamically typed languages also allow you to write out things like "error: the first character of this string should be a 'z'".

Another thing is that dynamically typed languages have the type available at runtime and usually can check it and deal with it and decide from it. Of course, in theory it's no different than accessing the first char of an array and seeing what it is. In fact, you can make your own dynamic C, just use only one type like long long int and use the first 8 bits of it to store your 'type' in and write functions accordingly that check for it and perform float or integer addition. You have a statically typed language with one type, or a dynamic language.

In practise this all shows, statically typed languages are generally used in the context of writing commercial software, whereas dynamically typed languages tend to be used in the context of solving some problems and automating some tasks. Writing code in statically typed languages simply takes long and is cumbersome because you can't do things which you know are going to turn out okay but the type system still protects you against yourself for errors you don't make. Many coders don't even realize that they do this because it's in their system but when you code in static languages, you often work around the fact that the type system won't let you do things that can't go wrong, because it can't prove it won't go wrong.

As I noted, 'statically typed' in general means case 2, guilty until proven innocent. But some languages, which do not derive their type system from type theory at all use rule 1: Innocent until proven guilty, which might be the ideal hybrid. So, maybe Typed Racket is for you.

Also, well, for a more absurd and extreme example, I'm currently implementing a language where 'types' are truly the first character of an array, they are data, data of the 'type', 'type', which is itself a type and datum, the only datum which has itself as a type. Types are not finite or bounded statically but new types may be generated based on runtime information.

Perhaps the single biggest "benefit" of dynamic typing is the shallower learning curve. There is no type system to learn and no non-trivial syntax for corner cases such as type constraints. That makes dynamic typing accessible to a lot more people and feasible for many people for whom sophisticated static type systems are out of reach. Consequently, dynamic typing has caught on in the contexts of education (e.g. Scheme/Python at MIT) and domain-specific languages for non-programmers (e.g. Mathematica). Dynamic languages have also caught on in niches where they have little or no competition (e.g. Javascript).

The most concise dynamically-typed languages (e.g. Perl, APL, J, K, Mathematica) are domain specific and can be significantly more concise than the most concise general-purpose statically-typed languages (e.g. OCaml) in the niches they were designed for.

The main disadvantages of dynamic typing are:

  • Run-time type errors.

  • Can be very difficult or even practically impossible to achieve the same level of correctness and requires vastly more testing.

  • No compiler-verified documentation.

  • Poor performance (usually at run-time but sometimes at compile time instead, e.g. Stalin Scheme) and unpredictable performance due to dependence upon sophisticated optimizations.

Personally, I grew up on dynamic languages but wouldn't touch them with a 40' pole as a professional unless there were no other viable options.

From Artima's Typing: Strong vs. Weak, Static vs. Dynamic article:

strong typing prevents mixing operations between mismatched types. In order to mix types, you must use an explicit conversion

weak typing means that you can mix types without an explicit conversion

In the Pascal Costanza's paper, Dynamic vs. Static Typing — A Pattern-Based Analysis (PDF), he claims that in some cases, static typing is more error-prone than dynamic typing. Some statically typed languages force you to manually emulate dynamic typing in order to do "The Right Thing". It's discussed at Lambda the Ultimate.

It depends on context. There a lot benefits that are appropriate to dynamic typed system as well as for strong typed. I'm of opinion that the flow of dynamic types language is faster. The dynamic languages are not constrained with class attributes and compiler thinking of what is going on in code. You have some kinda freedom. Furthermore, the dynamic language usually is more expressive and result in less code which is good. Despite of this, it's more error prone which is also questionable and depends more on unit test covering. It's easy prototype with dynamic lang but maintenance may become nightmare.

The main gain over static typed system is IDE support and surely static analyzer of code. You become more confident of code after every code change. The maintenance is peace of cake with such tools.

There are lots of different things about static and dynamic languages. For me, the main difference is that in dynamic languages the variables don't have fixed types; instead, the types are tied to values. Because of this, the exact code that gets executed is undetermined until runtime.

In early or naïve implementations this is a huge performance drag, but modern JITs get tantalizingly close to the best you can get with optimizing static compilers. (in some fringe cases, even better than that).

It is all about the right tool for the job. Neither is better 100% of the time. Both systems were created by man and have flaws. Sorry, but we suck and making perfect stuff.

I like dynamic typing because it gets out of my way, but yes runtime errors can creep up that I didn't plan for. Where as static typing may fix the aforementioned errors, but drive a novice(in typed languages) programmer crazy trying to cast between a constant char and a string.

Static Typing: The languages such as Java and Scala are static typed.

The variables have to be defined and initialized before they are used in a code.

for ex. int x; x = 10;

System.out.println(x);

Dynamic Typing: Perl is an dynamic typed language.

Variables need not be initialized before they are used in code.

y=10; use this variable in the later part of code

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