Question

Quels sont les avantages et les inconvénients des langages de type dynamique par rapport aux langages de type statique?

Voir aussi : avec l'amour de langages dynamiques (un fil beaucoup plus argumentatif ...)

Était-ce utile?

La solution

La capacité de l'interprète à déduire des types et des conversions de types accélère le temps de développement, mais peut également provoquer des échecs d'exécution que vous ne pouvez pas obtenir dans un langage à typage statique où vous les récupérez lors de la compilation. Mais lequel est meilleur (ou même si cela est toujours vrai) fait l'objet de discussions animées dans la communauté ces jours-ci (et depuis longtemps).

La question est pertinente dans Saisie de texte statique où Dactylographie dynamique possible en cas de besoin: la fin de la guerre froide entre les langages de programmation par Erik Meijer et Peter Drayton chez Microsoft:

  

Les défenseurs du typage statique soutiennent que   les avantages du typage statique   inclure une détection plus précoce de   erreurs de programmation (par exemple, empêcher   ajouter un entier à un booléen),   meilleure documentation sous forme de   signatures de type (par exemple, incorporant   nombre et types d'arguments lorsque   résolution de noms), plus d'opportunités   pour les optimisations du compilateur (par exemple,   remplacer les appels virtuels par des appels directs   appelle lorsque le type exact du   récepteur est connu statiquement),   amélioration de l'efficacité d'exécution (par exemple, pas   toutes les valeurs doivent avoir une dynamique   type), et un meilleur temps de conception   expérience de développeur (par exemple, connaître le   type de récepteur, l'IDE peut   présenter un menu déroulant de tous   membres applicables). Typage statique   les fanatiques essaient de nous faire croire que   «Les programmes bien typés ne peuvent pas aller mal».   Bien que cela sonne certainement   impressionnant, c’est un vide   déclaration. La vérification de type statique est un   abstraction au moment de la compilation   comportement d'exécution de votre programme, et   il est donc nécessairement que partiellement   sain et incomplet. Cela signifie que   les programmes peuvent toujours aller mal à cause de   propriétés qui ne sont pas suivies par le   dactylographier, et qu'il y a   des programmes qui alors qu'ils ne peuvent pas aller   mal ne peut pas être dactylographié. le   impulsion pour réduire le typage statique   type de causes partielles et plus complètes   les systèmes deviennent trop compliqués   et exotique comme en témoignent les concepts   tels que les «types fantômes» [11] et   «Types instables» [10]. C'est comme   essayer de courir un marathon avec un ballon   et une chaîne attachée à votre jambe et   criant triomphalement que vous avez presque   fait même si vous renfloué   après le premier kilomètre.

     

Avocats du type dynamiquement   les langues soutiennent que le typage statique est   trop rigide, et que la douceur de   dynamiquement les langues les rend   idéal pour les systèmes de prototypage   avec des exigences changeantes ou inconnues,   ou qui interagissent avec d'autres systèmes   qui changent de façon imprévisible (données et   intégration d'applications). Bien sûr,   les langues typées dynamiquement sont   indispensable pour traiter vraiment   comportement de programme dynamique tel que   interception de méthode, chargement dynamique,   code mobile, réflexion à l'exécution, etc.   Dans la mère de tous les papiers sur   l'écriture de scripts [16], soutient John Ousterhout   que les systèmes statiquement typés   les langages de programmation rendent le code moins   réutilisable, plus verbeux, pas plus sûr,   et moins expressif que dynamique   langages de script tapés. Ce   l'argument est répété littéralement par beaucoup   les partisans du typage dynamique   langages de script. Nous soutenons que   c'est une erreur et tombe dans le   même catégorie en faisant valoir que la   essence de la programmation déclarative est   élimination de la cession. Ou comme John   Hughes dit [8], c'est une logique   impossibilité de faire une langue plus   puissant en omettant les fonctionnalités.   Défendre le fait que retarder tous   la vérification du type à l'exécution est un bon   chose, joue à la tactique d'autruche avec   le fait que des erreurs doivent être attrapées   dès le début du processus de développement   possible.

Autres conseils

Les systèmes de types statiques cherchent à éliminer certaines erreurs de manière statique, en inspectant le programme sans l'exécuter et en essayant de prouver la validité à certains égards. Certains systèmes de types sont capables d’attraper plus d’erreurs que d’autres. Par exemple, C # peut éliminer les exceptions de pointeur nul lorsqu'il est utilisé correctement, alors que Java n'a pas ce pouvoir. Twelf a un système de types qui garantit la fin des épreuves , " résolution " le problème d'arrêt .

Cependant, aucun système de typage n'est parfait. Afin d'éliminer une classe d'erreurs particulière, ils doivent également rejeter certains programmes parfaitement valides qui violent les règles. C’est la raison pour laquelle Twelf ne résout pas vraiment le problème d’arrêt, il l’évite en jetant un grand nombre de preuves parfaitement valables qui se terminent de manière étrange. De même, le système de types de Java rejette l'implémentation de PersistentVector de Clojure en raison de son utilisation de tableaux hétérogènes. Cela fonctionne au moment de l'exécution, mais le système de types ne peut pas le vérifier.

Pour cette raison, la plupart des systèmes de types fournissent des "échappements", moyens de remplacer le vérificateur statique. Pour la plupart des langues, il s’agit d’un casting, bien que certaines (comme C # et Haskell) aient des modes complets qui sont marqués comme "non sécurisés".

Subjectivement, j'aime le typage statique. Mis en œuvre correctement (astuce: pas Java), un système de types statiques peut s'avérer très utile pour éliminer les erreurs avant qu'elles ne plantent le système de production. Les langues à typage dynamique ont tendance à nécessiter davantage de tests unitaires, ce qui est fastidieux dans le meilleur des cas. De même, les langages à typage statique peuvent avoir certaines fonctionnalités impossibles ou dangereuses dans les systèmes de types dynamiques ( les conversions implicites me viennent à l’esprit). Tout est une question d'exigences et de goût subjectif. Je ne voudrais pas plus construire le prochain Eclipse dans Ruby que d’essayer d’écrire un script de sauvegarde dans Assembly ou de patcher un noyau avec Java.

Oh, et les personnes qui affirment que la frappe " x est 10 fois plus productive que la frappe y " ne font que souffler de la fumée. La frappe dynamique peut "se sentir". plus rapide dans de nombreux cas, mais il perd du terrain une fois que vous essayez réellement de rendre votre application fantaisie exécutée . De même, le typage statique peut sembler être le filet de sécurité parfait, mais un regard sur certaines des définitions de types génériques plus complexes en Java envoie la plupart des développeurs se précipiter pour des aveugles. Même avec les systèmes de types et la productivité, il n’ya pas de solution miracle.

Remarque finale: ne vous inquiétez pas des performances lorsque vous comparez des saisies statiques avec des saisies dynamiques. Les JIT modernes tels que V8 et TraceMonkey s'approchent dangereusement des performances du langage statique. De plus, le fait que Java compile réellement vers un langage intermédiaire intrinsèquement dynamique devrait indiquer que, dans la plupart des cas, le typage dynamique n’est pas l’énorme killer en termes de performances que certaines personnes prétendent être.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top