Langages de types dynamiques et langages de types statiques

205

Quels sont les avantages et les limites des langages de type dynamiques par rapport aux langages de type statiques?

Voir aussi : ce qui est avec l'amour des langages dynamiques (un fil beaucoup plus argumentatif ...)

cvs
la source
10
Cette question est trop subjective.
Jason Dagit
7
Je n'appellerais pas cela subjectif, mais un appât à flamme. Mais il y a des faits objectifs à ce sujet.
Vinko Vrsalovic
2
D'accord: trop subjectif. Il est intéressant de comparer et de contraster les deux approches, mais cela vacille dangereusement au bord de l'apocalypse du forum.
Daniel Spiewak
17
Les langages dynamiques sont parfaits pour le développement rapide d'applications de démonstration / jetables car si vous faites une faute de frappe qui vous intéresse, la page Web se charge toujours, vous risquez d'avoir quelques éléments de données erronés ici ou là. Je ne peux imaginer aucune autre situation où la possibilité de mal saisir vos variables sans obtenir une erreur de compilation est considérée comme un "avantage".
Alex R
4
Une telle erreur entraînerait généralement l'arrêt brutal de JavaScript, ce que je considère comme une très bonne chose. À tout le moins, cela provoquerait des erreurs que je trouve également précieuses. Pour une raison quelconque, c'est toujours un gars d'un paradigme de frappe statique qui veut enterrer ses erreurs javascript avec des instructions try / catch vides. Cela a été quelque chose d'un phénomène dans mon expérience. Qu'est-ce que c'est? Quoi qu'il en soit, ce n'est pas comme si nous n'obtenions pas de commentaires lorsque nous exécutons notre code.
Erik Reppen

Réponses:

139

La capacité de l'interpréteur à déduire le type et les conversions de type accélère le temps de développement, mais il peut également provoquer des échecs d'exécution que vous ne pouvez tout simplement pas obtenir dans un langage typé où vous les interceptez au moment de la compilation. Mais lequel est le meilleur (ou même si c'est toujours vrai) est chaudement discuté dans la communauté ces jours-ci (et depuis longtemps).

Un bon point de vue sur le problème vient de Typing Static Where Possible, Dynamic Typing When Needed: The End of the Cold War Between Programming Languages par Erik Meijer et Peter Drayton chez Microsoft:

Les partisans du typage statique soutiennent que les avantages du typage statique comprennent la détection précoce des erreurs de programmation (par exemple, empêcher l'ajout d'un entier à un booléen), une meilleure documentation sous la forme de signatures de type (par exemple l'incorporation de nombre et de types d'arguments lors de la résolution de noms), plus possibilités d'optimisation du compilateur (par exemple, remplacement d'appels virtuels par des appels directs lorsque le type exact du récepteur est connu statiquement), efficacité d'exécution accrue (par exemple, toutes les valeurs n'ont pas besoin de porter un type dynamique), et une meilleure expérience de développeur au moment de la conception (par exemple, connaissance le type de récepteur, l'IDE peut présenter un menu déroulant de tous les membres applicables). Les fanatiques de frappe statique essaient de nous faire croire que «les programmes bien typés ne peuvent pas se tromper». Bien que cela semble certainement impressionnant, c'est une déclaration plutôt vide de sens. La vérification de type statique est une abstraction au moment de la compilation du comportement d'exécution de votre programme, et par conséquent elle n'est nécessairement que partiellement saine et incomplète. Cela signifie que les programmes peuvent toujours mal tourner en raison de propriétés qui ne sont pas suivies par le vérificateur de type et qu'il existe des programmes qui, même s'ils ne peuvent pas se tromper, ne peuvent pas être vérifiés par type. L'impulsion pour rendre le typage statique moins partiel et plus complet fait que les systèmes de types deviennent trop compliqués et exotiques, comme en témoignent des concepts tels que les «types fantômes» [11] et les «types chancelants» [10]. C'est comme essayer de courir un marathon avec une balle et une chaîne attachées à votre jambe et crier triomphalement que vous avez presque réussi même si vous vous êtes échappé après le premier kilomètre. La vérification de type statique est une abstraction au moment de la compilation du comportement d'exécution de votre programme, et par conséquent elle n'est nécessairement que partiellement saine et incomplète. Cela signifie que les programmes peuvent toujours mal tourner en raison de propriétés qui ne sont pas suivies par le vérificateur de type et qu'il existe des programmes qui, même s'ils ne peuvent pas se tromper, ne peuvent pas être vérifiés par type. L'impulsion pour rendre le typage statique moins partiel et plus complet fait que les systèmes de types deviennent trop compliqués et exotiques, comme en témoignent des concepts tels que les «types fantômes» [11] et les «types chancelants» [10]. C'est comme essayer de courir un marathon avec une balle et une chaîne attachées à votre jambe et crier triomphalement que vous avez presque réussi même si vous vous êtes échappé après le premier kilomètre. La vérification de type statique est une abstraction au moment de la compilation du comportement d'exécution de votre programme, et par conséquent elle n'est nécessairement que partiellement saine et incomplète. Cela signifie que les programmes peuvent toujours mal tourner en raison de propriétés qui ne sont pas suivies par le vérificateur de type et qu'il existe des programmes qui, même s'ils ne peuvent pas se tromper, ne peuvent pas être vérifiés par type. L'impulsion pour rendre le typage statique moins partiel et plus complet fait que les systèmes de types deviennent trop compliqués et exotiques, comme en témoignent des concepts tels que les «types fantômes» [11] et les «types chancelants» [10]. C'est comme essayer de courir un marathon avec une balle et une chaîne attachées à votre jambe et crier triomphalement que vous avez presque réussi même si vous vous êtes échappé après le premier kilomètre. et par conséquent, il n'est nécessairement que partiellement sain et incomplet. Cela signifie que les programmes peuvent toujours mal tourner en raison de propriétés qui ne sont pas suivies par le vérificateur de type et qu'il existe des programmes qui, même s'ils ne peuvent pas se tromper, ne peuvent pas être vérifiés par type. L'impulsion pour rendre le typage statique moins partiel et plus complet fait que les systèmes de types deviennent trop compliqués et exotiques, comme en témoignent des concepts tels que les «types fantômes» [11] et les «types chancelants» [10]. C'est comme essayer de courir un marathon avec une balle et une chaîne attachées à votre jambe et crier triomphalement que vous avez presque réussi même si vous vous êtes échappé après le premier kilomètre. et par conséquent, il n'est nécessairement que partiellement sain et incomplet. Cela signifie que les programmes peuvent toujours mal tourner en raison de propriétés qui ne sont pas suivies par le vérificateur de type et qu'il existe des programmes qui, même s'ils ne peuvent pas se tromper, ne peuvent pas être vérifiés par type. L'impulsion pour rendre le typage statique moins partiel et plus complet fait que les systèmes de types deviennent trop compliqués et exotiques, comme en témoignent des concepts tels que les «types fantômes» [11] et les «types chancelants» [10]. C'est comme essayer de courir un marathon avec une balle et une chaîne attachées à votre jambe et crier triomphalement que vous avez presque réussi même si vous vous êtes échappé après le premier kilomètre. et qu'il existe des programmes qui, même s'ils ne peuvent pas se tromper, ne peuvent pas être vérifiés par type. L'impulsion pour rendre le typage statique moins partiel et plus complet fait que les systèmes de types deviennent trop compliqués et exotiques, comme en témoignent des concepts tels que les «types fantômes» [11] et les «types chancelants» [10]. C'est comme essayer de courir un marathon avec une balle et une chaîne attachées à votre jambe et crier triomphalement que vous avez presque réussi même si vous vous êtes échappé après le premier kilomètre. et qu'il existe des programmes qui, même s'ils ne peuvent pas se tromper, ne peuvent pas être vérifiés par type. L'impulsion pour rendre le typage statique moins partiel et plus complet fait que les systèmes de types deviennent trop compliqués et exotiques, comme en témoignent des concepts tels que les «types fantômes» [11] et les «types chancelants» [10]. C'est comme essayer de courir un marathon avec une balle et une chaîne attachées à votre jambe et crier triomphalement que vous avez presque réussi même si vous vous êtes échappé après le premier kilomètre.

Les partisans des langages typés dynamiquement affirment que le typage statique est trop rigide et que la douceur des langages dynamiquement les rend parfaitement adaptés aux 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 (intégration de données et d'applications). Bien sûr, les langages typés dynamiquement sont indispensables pour gérer un comportement de programme vraiment dynamique comme l'interception de méthode, le chargement dynamique, le code mobile, la réflexion d'exécution, etc. Dans la mère de tous les articles sur les scripts [16], John Ousterhout soutient que les systèmes typés statiquement les langages de programmation rendent le code moins réutilisable, plus verbeux, pas plus sûr et moins expressif que les langages de script typés dynamiquement. Cet argument est littéralement interprété par de nombreux partisans des langages de script typés dynamiquement. Nous soutenons qu'il s'agit d'une erreur et tombe dans la même catégorie que l'argument selon lequel l'essence de la programmation déclarative est d'éliminer l'affectation. Ou comme le dit John Hughes [8], c'est une impossibilité logique de rendre un langage plus puissant en omettant des fonctionnalités. Défendre le fait que reporter toute vérification de type à l'exécution est une bonne chose, c'est jouer à la tactique de l'autruche avec le fait que les erreurs doivent être détectées le plus tôt possible dans le processus de développement. c'est une impossibilité logique de rendre un langage plus puissant en omettant des fonctionnalités. Défendre le fait que reporter toute vérification de type à l'exécution est une bonne chose, c'est jouer à la tactique de l'autruche avec le fait que les erreurs doivent être détectées le plus tôt possible dans le processus de développement. c'est une impossibilité logique de rendre un langage plus puissant en omettant des fonctionnalités. Défendre le fait que reporter toute vérification de type à l'exécution est une bonne chose, c'est jouer à la tactique de l'autruche avec le fait que les erreurs doivent être détectées le plus tôt possible dans le processus de développement.

Vinko Vrsalovic
la source
37
«l'interception de méthode, le chargement dynamique, le code mobile, la réflexion à l'exécution» peuvent tous être effectués en Java, juste pour mémoire.
Will Hartung, le
13
Les types fantômes ne sont pas "trop ​​compliqués".
Jon Harrop
12
Le lien vers le document Meijer est rompu au 16/05/2010.
jchadhowell
5
@jchadhowell, vous pouvez le trouver ici research.microsoft.com/en-us/um/people/emeijer/Papers/…
Srinivas Reddy Thatiparthy
4
@VinkoVrsalovic Les langages statiques avec inférence de type et polymorphisme sont assez bons pour le prototypage rapide. Ils offrent le même confort que le langage dynamique et la sécurité des langages statiques.
Edgar Klerks
119

Les systèmes de type statique cherchent à éliminer statiquement certaines erreurs, inspectant le programme sans l'exécuter et essayant de prouver la solidité à certains égards. Certains systèmes de types sont capables de détecter 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 un tel pouvoir. Twelf a un système de type qui garantit effectivement que les preuves se termineront , "résolvant" le problème d'arrêt .

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

Pour cette raison, la plupart des systèmes de type fournissent des "échappements", des moyens de remplacer le vérificateur statique. Pour la plupart des langages, ceux-ci prennent la forme d'un casting, bien que certains (comme C # et Haskell) aient des modes entiers qui sont marqués comme "dangereux".

Subjectivement, j'aime la frappe statique. Implémenté correctement (indice: pas Java), un système de type statique peut être d'une grande aide pour éliminer les erreurs avant qu'elles ne plantent le système de production. Les langages typés dynamiquement ont tendance à nécessiter plus de tests unitaires, ce qui est fastidieux dans le meilleur des cas. En outre, les langages typés statiquement peuvent avoir certaines fonctionnalités qui sont soit impossibles soit dangereuses dans les systèmes de type dynamique (des conversions implicites viennent à l'esprit). Tout est une question d'exigences et de goût subjectif. Je ne construirais pas plus la prochaine Eclipse dans Ruby que je n'essaierais d'écrire un script de sauvegarde dans Assembly ou de corriger un noyau en utilisant Java.

Oh, et les gens qui disent que "la frappe x est 10 fois plus productive que la frappe y " soufflent simplement de la fumée. Typage dynamique peut « sentir » plus rapide dans de nombreux cas, mais il perd du terrain une fois que vous essayez réellement de faire votre demande de fantaisie terme . De même, le typage statique peut sembler être le filet de sécurité parfait, mais un coup d'œil à certaines des définitions de types génériques les plus compliquées de Java envoie la plupart des développeurs à la recherche de œillères. Même avec les systèmes de type et la productivité, il n'y a pas de solution miracle.

Remarque finale: ne vous inquiétez pas des performances lors de la comparaison de la frappe statique avec la frappe dynamique. Les JIT modernes comme V8 et TraceMonkey se rapprochent dangereusement des performances du langage statique. De plus, le fait que Java se compile en un langage intermédiaire intrinsèquement dynamique devrait être un indice que, dans la plupart des cas, la frappe dynamique n'est pas l'énorme performance-killer que certaines personnes prétendent être.

Daniel Spiewak
la source
5
À propos de la performance. Dans les cas courants, cela ne fera pas beaucoup de différence, mais en mathématiques haute tension et autres, il y a une vraie différence. Les tests ont prouvé que l'appel d'une fonction, dans le cas de ipy vs C #, diffère de mille cycles. Tout simplement parce que le premier doit être sûr qu'une méthode existe.
Dykam
29
peut u développer sur le point "C # peut éliminer les exceptions de pointeur nul lorsqu'il est utilisé correctement, alors que Java n'a pas un tel pouvoir." ? Un exemple ou une citation serait très apprécié.
Srinivas Reddy Thatiparthy
13
"certaines des définitions de types génériques les plus compliquées de Java envoient la plupart des développeurs à la recherche de œillères" - si c'est votre pire exemple, vous n'avez évidemment pas utilisé C ++ ;-)
bacar
3
"De plus, le fait que Java se compile en un langage intermédiaire intrinsèquement dynamique devrait être un indice que, dans la plupart des cas, la frappe dynamique n'est pas l'énorme performance-killer que certaines personnes prétendent être." - lorsque votre exemple de langage avec de "bonnes performances" est Java, vous voudrez peut-être reconsidérer.
Yakk - Adam Nevraumont
" Java se compile en un intermédiaire intrinsèquement dynamique " - ce qui manque le point. Les vérifications statiques ont été effectuées à l'avance et, par conséquent, aucune vérification supplémentaire du temps d'exécution couvrant celles-ci n'est requise car le compilateur choisit des instructions comme daddparce qu'il sait à l'avance que les opérandes sont doubles.
Michael Beer
45

Eh bien, les deux sont très, très très très mal compris et aussi deux choses complètement différentes. qui ne s'excluent pas mutuellement .

Les types statiques sont une restriction de la grammaire de la langue. On pourrait dire que les langages typés statiquement ne sont pas dépourvus de contexte. La simple vérité est qu'il devient gênant d'exprimer un langage sainement dans des grammaires sans contexte qui ne traitent pas toutes ses données simplement comme des vecteurs de bits. Les systèmes de type statiques font partie de la grammaire du langage, le cas échéant, ils la restreignent simplement plus qu'une grammaire sans contexte pourrait le faire, les vérifications grammaticales se produisent donc en deux passages sur la source. Les types statiques correspondent à la notion mathématique de la théorie des types, la théorie des types en mathématiques restreint simplement la légalité de certaines expressions. Comme, je ne peux pas dire 3 + [4,7]en mathématiques, c'est à cause de la théorie des types.

Les types statiques ne sont donc pas un moyen de «prévenir les erreurs» d'un point de vue théorique, ils sont une limitation de la grammaire. En effet, à condition que +, 3 et les intervalles aient les définitions théoriques habituelles de l'ensemble, si nous supprimons le système de type, le résultat 3 + [4,7]est assez bien défini, c'est un ensemble. les «erreurs de type d'exécution» n'existent théoriquement pas, l'utilisation pratique du système de type est d'empêcher des opérations qui pour les êtres humains n'auraient aucun sens. Bien sûr, les opérations ne sont que le déplacement et la manipulation de bits.

L'inconvénient est qu'un système de type ne peut pas décider si de telles opérations vont se produire ou non s'il est autorisé à s'exécuter. Comme dans, partitionnez exactement l'ensemble de tous les programmes possibles dans ceux qui vont avoir une «erreur de type» et ceux qui ne le sont pas. Il ne peut faire que deux choses:

1: prouver que les erreurs de type vont se produire dans un programme
2: prouver qu'elles ne vont pas se produire dans un programme

Cela peut sembler me contredire. Mais ce qu'un vérificateur de type C ou Java fait, c'est qu'il rejette un programme comme «non grammatical», ou comme il l'appelle «erreur de type» s'il ne réussit pas à 2. Il ne peut pas prouver qu'il ne se produira pas, cela ne signifie pas qu'ils ne se produiront pas, cela signifie simplement que cela ne peut pas le prouver. Il se pourrait très bien qu'un programme qui n'aura pas d'erreur de type soit rejeté simplement parce qu'il ne peut pas être prouvé par le compilateur. Un exemple simple étantif(1) a = 3; else a = "string";, car c'est toujours vrai, la branche else ne sera jamais exécutée dans le programme et aucune erreur de type ne se produira. Mais il ne peut pas prouver ces cas de manière générale, il est donc rejeté. C'est la principale faiblesse de beaucoup de langages typés statiquement, en vous protégeant contre vous-même, vous êtes nécessairement aussi protégé dans les cas où vous n'en avez pas besoin.

Mais, contrairement à la croyance populaire, il existe également des langages typés statiquement qui fonctionnent selon le principe 1. Ils rejettent simplement tous les programmes dont ils peuvent prouver que cela va provoquer une erreur de type et transmettent tous les programmes dont ils ne peuvent pas. Il est donc possible qu'ils autorisent les programmes qui contiennent des erreurs de type, un bon exemple étant Typed Racket, il est hybride entre le typage dynamique et statique. Et certains diront que vous obtenez le meilleur des deux mondes dans ce système.

Un autre avantage du typage statique est que les types sont connus au moment de la compilation et que le compilateur peut donc l'utiliser. Si nous, en Java, faisons "string" + "string"ou 3 + 3, les deux +jetons dans le texte à la fin représentent une opération et une donnée complètement différentes, le compilateur sait lequel choisir parmi les types seuls.

Maintenant, je vais faire une déclaration très controversée ici, mais gardez avec moi: le «typage dynamique» n'existe pas .

Cela semble très controversé, mais c'est vrai, les langages typés dynamiquement sont d'un point de vue théorique non typés . Ce ne sont que des langages typés statiquement avec un seul type. Autrement dit, ce sont des langues qui sont en effet générées grammaticalement par une grammaire sans contexte dans la pratique.

Pourquoi n'ont-ils pas de types? Parce que chaque opération est définie et autorisée sur chaque opérateur, qu'est-ce qu'une «erreur de type d'exécution» exactement? C'est à partir d'un exemple théorique purement un effet secondaire . Si faire print("string")qui imprime une chaîne est une opération, alors length(3)la première a pour effet secondaire d'écrire stringsur la sortie standard, la seconde simplement error: function 'length' expects array as argument., c'est tout. D'un point de vue théorique, une langue typée dynamiquement n'existe pas. Ils ne sont pas typés

Très bien, l'avantage évident du langage «typé dynamiquement» est le pouvoir expressif, un système de type n'est rien d'autre qu'une limitation du pouvoir expressif. Et en général, les langues avec un système de type auraient en effet un résultat défini pour toutes ces opérations qui ne sont pas autorisées si le système de type était simplement ignoré, les résultats n'auraient tout simplement pas de sens pour les humains. De nombreuses langues perdent leur exhaustivité de Turing après avoir appliqué un système de type.

L'inconvénient évident est le fait que des opérations peuvent se produire, ce qui produirait des résultats insensés pour l'homme. Pour se prémunir contre cela, les langages typés dynamiquement redéfinissent généralement ces opérations, plutôt que de produire ce résultat insensé, ils le redéfinissent pour avoir pour effet secondaire d'écrire une erreur, et éventuellement d'arrêter complètement le programme. Ce n'est pas du tout une «erreur», en fait, la spécification de la langue implique généralement cela, c'est autant le comportement de la langue que l'impression d'une chaîne d'un point de vue théorique. Les systèmes de types obligent donc le programmeur à raisonner sur le flux du code pour s'assurer que cela ne se produit pas. Ou bien, raison pour qu'il nese produire peut également être utile à certains égards pour le débogage, montrant que ce n'est pas du tout une «erreur» mais une propriété bien définie du langage. En effet, le seul vestige de «typage dynamique» que la plupart des langues ont se garde contre une division par zéro. C'est ce qu'est la frappe dynamique, il n'y a pas de types, il n'y a pas plus de types que ce zéro est un type différent de tous les autres nombres. Ce que les gens appellent un «type» n'est qu'une autre propriété d'une donnée, comme la longueur d'un tableau ou le premier caractère d'une chaîne. Et de nombreuses langues typées dynamiquement vous permettent également d'écrire des choses comme "error: the first character of this string should be a 'z'".

Une autre chose est que les langages typés dynamiquement ont le type disponible au moment de l'exécution et peuvent généralement le vérifier et le traiter et en décider. Bien sûr, en théorie, ce n'est pas différent que d'accéder au premier caractère d'un tableau et de voir de quoi il s'agit. En fait, vous pouvez créer votre propre C dynamique, n'utilisez qu'un seul type comme long long int et utilisez les 8 premiers bits pour stocker votre `` type '' et écrire des fonctions en conséquence qui le vérifient et effectuent une addition flottante ou entière. Vous avez une langue typée statiquement avec un type ou une langue dynamique.

En pratique, tout cela montre que les langages typés statiquement sont généralement utilisés dans le contexte de l'écriture de logiciels commerciaux, tandis que les langages typés dynamiquement ont tendance à être utilisés dans le contexte de la résolution de certains problèmes et de l'automatisation de certaines tâches. L'écriture de code dans des langages typés prend simplement du temps et est fastidieuse car vous ne pouvez pas faire des choses qui vont bien se passer, mais le système de type vous protège toujours contre vous-même pour les erreurs que vous ne faites pas. De nombreux codeurs ne réalisent même pas qu'ils le font parce que c'est dans leur système, mais lorsque vous codez dans des langages statiques, vous contournez souvent le fait que le système de type ne vous laisse pas faire des choses qui ne peuvent pas mal tourner, car il ne peut pas prouver que ça ne va pas mal.

Comme je l'ai noté, «dactylographié» signifie généralement le cas 2, coupable jusqu'à preuve du contraire. Mais certains langages, qui ne tirent pas du tout leur système de types de la théorie des types, utilisent la règle 1: Innocent jusqu'à preuve du contraire, ce qui pourrait être l'hybride idéal. Alors, peut-être que Typed Racket est pour vous.

De plus, pour un exemple plus absurde et extrême, j'implémente actuellement un langage où les «types» sont vraiment le premier caractère d'un tableau, ce sont des données, des données de «type», «type», qui est lui-même un type et une donnée, la seule donnée qui a elle-même comme type. Les types ne sont pas finis ou limités statiquement, mais de nouveaux types peuvent être générés en fonction des informations d'exécution.

Zorf
la source
1
"De nombreuses langues perdent leur exhaustivité de Turing après avoir appliqué un système de type." ne s'applique pas aux langages de programmation habituels, non? d'après ce que j'ai lu, les langues régulières ne sont pas complètes
Răzvan Flavius ​​Panda
1
@ RăzvanPanda: Lajla faisait probablement référence à des variations du calcul lambda typé ou de certains des langages de programmation qu'ils utilisent sur les prouveurs de théorèmes. Beaucoup d'entre eux ne peuvent exprimer que des programmes dont l'arrêt est garanti et qui ne sont donc pas complets. Des langages de programmation fonctionnels pratiques basés sur ces systèmes de types contournent cette limitation en étendant le calcul de base avec des types récursifs.
hugomg
1
"Cela semble très controversé, mais c'est vrai, les langages typés dynamiquement sont d'un point de vue théorique non typés." - ... et, en un instant, je sais que tu ne sais pas de quoi tu parles. La frappe dynamique signifie simplement que les types appartiennent aux valeurs, pas aux identificateurs. Cela rend les programmes plus difficiles à prouver, mais pas nécessairement impossibles. Le polymorphisme en ligne et paramétrique a déjà conduit au développement de l'optimisation du temps de liaison; qui résout le même type de problème que la compilation de langages typés dynamiquement optimaux: savoir toutes les entrées et sorties possibles.
DeftlyHacked du
25

Le plus grand "avantage" du typage dynamique est peut-être la courbe d'apprentissage moins profonde. Il n'y a pas de système de types à apprendre et pas de syntaxe non triviale pour les cas d'angle tels que les contraintes de type. Cela rend la frappe dynamique accessible à beaucoup plus de personnes et réalisable pour de nombreuses personnes pour lesquelles les systèmes sophistiqués de type statique sont hors de portée. Par conséquent, le typage dynamique a fait son chemin dans les contextes de l'éducation (par exemple Scheme / Python au MIT) et les langages spécifiques au domaine pour les non-programmeurs (par exemple Mathematica ). Les langages dynamiques ont également fait leur apparition dans des niches où ils ont peu ou pas de concurrence (par exemple Javascript).

Les langages à typage dynamique les plus concis (par exemple Perl, APL, J, K, Mathematica ) sont spécifiques à un domaine et peuvent être beaucoup plus concis que les langages à typage général à usage général les plus concis (par exemple OCaml ) dans les niches pour lesquelles ils ont été conçus. .

Les principaux inconvénients de la frappe dynamique sont:

  • Erreurs de type à l'exécution.

  • Il peut être très difficile, voire pratiquement impossible, d'atteindre le même niveau d'exactitude et nécessite beaucoup plus de tests.

  • Aucune documentation vérifiée par le compilateur.

  • Mauvaises performances (généralement au moment de l'exécution mais parfois au moment de la compilation à la place, par exemple Staline Scheme) et performances imprévisibles en raison de la dépendance à des optimisations sophistiquées.

Personnellement, j'ai grandi sur les langages dynamiques mais je ne les toucherais pas avec un poteau de 40 pieds en tant que professionnel à moins qu'il n'y ait pas d'autres options viables.

Jon Harrop
la source
2
Je dirais une barrière d'entrée plus faible, mais la maîtrise n'est pas moins une courbe d'apprentissage.
Erik Reppen
La courbe d'apprentissage n'est-elle pas moindre parce que vous n'avez pas de système de type à apprendre?
Jon Harrop
Il y a toujours un système de type. Vous pouvez faire des suppositions raisonnables sur ce qui se passe lorsque vous ajoutez un booléen et une chaîne, mais cela aide souvent beaucoup à connaître certains détails réels sur la manière dont les types sont forcés dans un langage typé dynamiquement. C'est ce que la plupart des gens strictement réservés n'obtiennent pas. Nous apprenons réellement ce genre de choses.
Erik Reppen du
@ErikReppen: Nous utilisons différentes définitions de "système de type". Je parlais de ne pas avoir à apprendre un système de type statique, par exemple les types de données algébriques, les génériques. Les «types» auxquels vous faites référence ne sont que des données. Le fait que certaines fonctions rejettent certaines données au moment de l'exécution est universel.
Jon Harrop
12

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

un typage fort empêche les opérations de mélange entre des types incompatibles. Pour mélanger les types, vous devez utiliser une conversion explicite

un typage faible signifie que vous pouvez mélanger des types sans conversion explicite

Dans l'article de Pascal Costanza, Dynamic vs. Static Typing - A Pattern-Based Analysis (PDF), il affirme que dans certains cas, le typage statique est plus sujet aux erreurs que le typage dynamique. Certaines langues typées statiquement vous obligent à émuler manuellement la frappe dynamique afin de faire "The Right Thing". Il en est question à Lambda the Ultimate .

Mark Cidade
la source
1
"la frappe statique est plus sujette aux erreurs que la frappe dynamique" - Oui, oui, et DOUBLE oui! J'ai beaucoup d'expérience dans les deux types de langages, et dans tous les cas le langage dynamique "fonctionne juste" alors que le statique nécessite 2x le temps de débogage (voir C ++ et Delphi). Cela est souvent dû à des problèmes de type, en particulier le transfert de données entre les modules et les fonctions avec des types fous. Même s'il existe toutes sortes de bogues théoriques, les langages dynamiques peuvent supposément provoquer, dans la pratique, il est TRÈS rare que je rencontre un bogue causé par la contrainte de type, sauf si vous êtes un mauvais programmeur abusant des types dynamiques.
dallin
7
J'ai lu un projet de document de Costanza il y a quelques années. Partout où il avait écrit "statique", il voulait vraiment dire spécifiquement "Java". Je lui ai donné des dizaines de contre-exemples dans des langues comme OCaml qui ont réfuté ses affirmations, mais il a quand même continué et l'a publié. D'après l'apparence de ce journal, il publie toujours le même vieux non-sens. Par exemple, dans cet article, il affirme que "C # est généralement une mauvaise copie de Java". Cela n'a pas sa place dans un article scientifique ...
Jon Harrop
@dallin mon expérience est tout le contraire: ayant beaucoup à programmer en C, C ++, Java, Python, Perl et autres, je ne commencerais jamais quelque chose de plus grand qu'un petit programme de réglage dans un langage typé dynamiquement à moins d'être forcé. En Python, je frissonne encore en pensant à un projet WSGI: les rappels que j'ai dû sureritr ont été passés dans les références d'objets, et le code a semblé fonctionner correctement, quand il s'est écrasé car il s'est avéré que parfois ce ne sont pas des objets mais certains types élémentaires étant passé. Un langage qui facilite la création de trucs comme ça est tout simplement dangereux.
Michael Beer
@MichaelBeer Vous pourriez également dire qu'un langage comme C / C ++ qui vous permet de gérer directement la mémoire est tout simplement dangereux! J'ai certainement lutté contre des erreurs de mémoire pendant des heures. D'énormes projets Java ne sont pas non plus un pique-nique. Dans n'importe quelle langue, vous devez comprendre les dangers de la langue et les bonnes pratiques. Les pires projets sur lesquels j'ai jamais travaillé étaient des projets PHP en équipe avec peu de structure, mais j'ai également travaillé sur des projets avec des langages dynamiques qui étaient un rêve quand ils utilisaient un bon cadre et de bonnes pratiques de programmation.
dallin
@dallin D'accord, chaque langue a ses pièges. Mais les défauts auxquels j'ai fait référence sont inhérents à tout langage typé dynamiquement, la possibilité de manipuler directement la mémoire n'est pas une propriété inhérente aux langages typés statiquement. Vous pouvez imaginer des langages typés dynamiquement qui vous permettent de manipuler mem directement. Je suis d'accord que le C ++ est un désastre, car l'inventeur du langage lui-même ne croit pas qu'une seule personne sur cette planète puisse connaître toutes les parties du langage. Cependant, cela ne peut pas être imputé au C ++ étant typé statiquement, mais à un monstre qui grandissait depuis 30 ans ...
Michael Beer
3

Cela dépend du contexte. Il y a beaucoup d'avantages qui conviennent au système typé dynamique ainsi qu'au typage fort. Je suis d'avis que le flux de langage de types dynamiques est plus rapide. Les langages dynamiques ne sont pas limités par les attributs de classe et le compilateur pensant à ce qui se passe dans le code. Vous avez un peu de liberté. De plus, le langage dynamique est généralement plus expressif et entraîne moins de code, ce qui est bien. Malgré cela, il est plus sujet aux erreurs, ce qui est également discutable et dépend davantage de la couverture du test unitaire. C'est un prototype facile avec une langue dynamique mais la maintenance peut devenir un cauchemar.

Le principal gain par rapport au système de type statique est le support IDE et sûrement l'analyseur de code statique. Vous devenez plus sûr du code après chaque changement de code. L'entretien est la paix du gâteau avec de tels outils.

AndrewG
la source
0

Il y a beaucoup de choses différentes sur les langages statiques et dynamiques. Pour moi, la principale différence est que dans les langages dynamiques, les variables n'ont pas de types fixes; au lieu de cela, les types sont liés à des valeurs. Pour cette raison, le code exact qui est exécuté est indéterminé jusqu'à l'exécution.

Dans les implémentations précoces ou naïves, cela représente un énorme frein aux performances, mais les JIT modernes se rapprochent énormément du meilleur que vous pouvez obtenir avec l'optimisation des compilateurs statiques. (dans certains cas marginaux, encore mieux que cela).

Javier
la source
0

Il s'agit du bon outil pour le travail. Ni mieux à 100% du temps. Les deux systèmes ont été créés par l'homme et ont des défauts. Désolé, mais on craint et on fait des trucs parfaits.

J'aime la frappe dynamique car elle me gêne, mais oui, des erreurs d'exécution peuvent se produire que je n'avais pas prévues. Alors que le typage statique peut corriger les erreurs susmentionnées, mais rendre fou un programmeur novice (dans les langages typés) qui essaie de passer entre un caractère constant et une chaîne.

JJ
la source
-3

Typage statique: les langages tels que Java et Scala sont typés statiquement.

Les variables doivent être définies et initialisées avant d'être utilisées dans un code.

par ex. int x; x = 10;

System.out.println (x);

Typage dynamique: Perl est un langage typé dynamique.

Les variables n'ont pas besoin d'être initialisées avant d'être utilisées dans le code.

y = 10; utiliser cette variable dans la dernière partie du code

Prakhyat
la source
5
Cela n'a rien à voir avec le système de type.
Thiago Negri