Quelle est la différence entre les langages typés statiquement et les langages dynamics?

J’entends beaucoup dire que les nouveaux langages de programmation sont typescripts de manière dynamic, mais que signifie-t-il réellement quand on dit qu’une langue est typée de manière dynamic par rapport à une saisie statique?

Langages typés statiquement

Un langage est statiquement typé si le type d’une variable est connu au moment de la compilation. Pour certaines langues, cela signifie que vous, en tant que programmeur, devez spécifier quel type est chaque variable (par exemple: Java, C, C ++); d’autres langages offrent une forme d’ inférence de type , la capacité du système de types à déduire le type d’une variable (ex: OCaml, Haskell, Scala, Kotlin)

Le principal avantage est que toutes les vérifications peuvent être effectuées par le compilateur et que de nombreux bogues sortingviaux sont détectés très tôt.

Langages typés dynamicment

Une langue est typée dynamicment si le type est associé à des valeurs d’exécution et non à des variables / champs / etc. Cela signifie que vous, en tant que programmeur, pouvez écrire un peu plus rapidement car vous n’avez pas besoin de spécifier des types à chaque fois (à moins d’utiliser un langage de type statique avec inférence de type ). Exemple: Perl, Ruby, Python

La plupart des langages de script ont cette fonctionnalité car il n’y a de toute façon pas de compilateur pour effectuer une vérification de type statique, mais vous pouvez vous retrouver à chercher un bogue dû à une mauvaise interprétation du type d’une variable par l’interpréteur. Heureusement, les scripts ont tendance à être petits, de sorte que les bogues n’ont pas beaucoup d’endroits où se cacher.

La plupart des langages typés dynamicment vous permettent de fournir des informations de type, mais ne l’exigent pas. Un langage en cours de développement, Rascal , adopte une approche hybride permettant le typage dynamic au sein des fonctions mais imposant le typage statique pour la signature de la fonction.

Les langages de programmation typés statiquement font la vérification de type (le processus de vérification et de mise en application des contraintes des types) au moment de la compilation, par opposition à l’exécution.

Les langages de programmation typés dynamicment font la vérification de type à l’exécution, par opposition à la compilation.

Voici un exemple contrastant comment Python (typé dynamicment) et Go (typé statiquement) traitent une erreur de type:

def silly(a): if a > 0: print 'Hi' else: print 5 + '3' 

Python effectue une vérification de type au moment de l’exécution, et par conséquent:

 silly(2) 

Fonctionne parfaitement et produit la sortie attendue: Hi . L’erreur n’est déclenchée que si la ligne problématique est atteinte:

 silly(-1) 

Produit

 TypeError: unsupported operand type(s) for +: 'int' and 'str' 

parce que la ligne pertinente a été réellement exécutée.

Allez par contre faire une vérification de type à la compilation:

 package main import ("fmt" ) func silly(a int) { if (a > 0) { fmt.Println("Hi") } else { fmt.Println("3" + 5) } } func main() { silly(2) } 

Ce qui précède ne comstackra pas, avec l’erreur suivante:

 invalid operation: "3" + 5 (mismatched types ssortingng and int) 

En termes simples: dans un langage de type statique , les types de variables sont statiques , ce qui signifie qu’une fois que vous définissez une variable sur un type, vous ne pouvez pas la modifier. En effet, la saisie est associée à la variable et non à la valeur à laquelle elle fait référence.

Par exemple en Java:

 Ssortingng str = "Hello"; //variable str statically typed as ssortingng str = 5; //would throw an error since str is supposed to be a ssortingng only 

D’un autre côté: dans un langage typé dynamicment, les types de variables sont dynamics , ce qui signifie qu’après avoir défini une variable sur un type, vous POUVEZ la modifier. En effet, la saisie est associée à la valeur qu’elle prend plutôt qu’à la variable elle-même.

Par exemple en Python:

 str = "Hello" # variable str is linked to a ssortingng value str = 5 # now it is linked to an integer value; perfectly OK 

Il est donc préférable de considérer les variables dans des langages à typage dynamic comme des pointeurs génériques à des valeurs typées.

En résumé, le type décrit (ou aurait dû décrire) les variables dans la langue plutôt que la langue elle-même. Il aurait pu être mieux utilisé comme langage avec des variables statiquement typées par rapport à un langage avec des variables typées dynamicment IMHO.

Les langages typés statiquement sont généralement des langages compilés, les compilateurs vérifient donc les types (tout à fait logique, car les types ne sont plus autorisés à être modifiés ultérieurement).

Les langages typés dynamicment sont généralement interprétés, ainsi la vérification de type (le cas échéant) se produit au moment de l’exécution lorsqu’ils sont utilisés. Cela apporte bien sûr un coût de performance et est l’une des raisons pour lesquelles les langages dynamics (par exemple, python, ruby, php) ne sont pas aussi évolutifs que les langages typés (java, c #, etc.). D’un autre sharepoint vue, les langages statiquement typés ont un coût de démarrage plus élevé: cela vous permet d’écrire plus de code, plus de code. Mais cela paie plus tard.

La bonne chose est que les deux parties empruntent des caractéristiques de l’autre côté. Les langages typés intègrent des fonctionnalités plus dynamics, par exemple les génériques et les bibliothèques dynamics en c #, et les langages dynamics incluent plus de vérification de type, par exemple, les annotations de type python ou les variantes HACK de PHP demande.

En ce qui concerne le choix de la technologie, aucune des deux parties n’a une supériorité insortingnsèque sur l’autre. Que vous souhaitiez plus de contrôle au départ ou de la flexibilité, c’est une question de préférence. Il suffit de choisir le bon outil pour le travail, et assurez-vous de vérifier ce qui est disponible en termes d’inverse avant d’envisager un changement.

http://en.wikipedia.org/wiki/Type_system

Dactylographie statique

On dit qu’un langage de programmation utilise le typage statique lorsque la vérification de type est effectuée au moment de la compilation, par opposition à l’exécution. En typage statique, les types sont associés à des variables et non à des valeurs. Les langages typés statiquement incluent Ada, C, C ++, C #, JADE, Java, Fortran, Haskell, ML, Pascal, Perl (en ce qui concerne les scalaires, les tableaux, les hachages et les sous-routines) et Scala. Le typage statique est une forme limitée de vérification de programme (voir sécurité de type): en conséquence, il permet de détecter de nombreuses erreurs de type au début du cycle de développement. Les vérificateurs de types statiques n’évaluent que les informations de type pouvant être déterminées au moment de la compilation, mais peuvent vérifier que les conditions vérifiées sont valables pour toutes les exécutions possibles du programme, ce qui évite de répéter les vérifications de type à chaque exécution du programme. L’exécution du programme peut également être plus efficace (c.-à-d. Accélérer ou réduire la mémoire) en omettant les vérifications de type à l’exécution et en autorisant d’autres optimisations.

Étant donné qu’ils évaluent les informations de type lors de la compilation et qu’ils manquent donc d’informations de type uniquement disponibles au moment de l’exécution, les vérificateurs de type statique sont conservateurs. Ils rejetteront certains programmes susceptibles de se comporter correctement au moment de l’exécution, mais ils ne peuvent pas être déterminés statistiquement correctement. Par exemple, même si une expression est toujours évaluée à true au moment de l’exécution, un programme contenant le code

 if  then 42 else  

sera rejeté comme mal typé, car une parsing statique ne peut pas déterminer que la twig else ne sera pas prise. [1] Le comportement conservateur des vérificateurs de types statiques est avantageux lorsque la valeur false est évaluée: Un vérificateur de type statique peut détecter des erreurs de type dans des chemins de code rarement utilisés. Sans vérification de type statique, même les tests de couverture de code avec une couverture à 100% du code peuvent être incapables de trouver de telles erreurs de type. Les tests de couverture de code peuvent ne pas détecter de telles erreurs de type, car la combinaison de tous les endroits où des valeurs sont créées et de tous les endroits où une certaine valeur est utilisée doit être prise en compte.

Les langues les plus couramment utilisées ne sont pas formellement sécurisées. Ils ont des «lacunes» dans la spécification du langage de programmation, ce qui permet aux programmeurs d’écrire du code qui contourne la vérification effectuée par un vérificateur de type statique et ainsi de résoudre un large éventail de problèmes. Par exemple, Java et la plupart des langages de style C ont un type de punition, et Haskell a des fonctionnalités telles que unsafePerformIO: de telles opérations peuvent être dangereuses au moment de l’exécution, car elles peuvent provoquer un comportement indésirable.

Typage dynamic

Un langage de programmation est dit typescript dynamicment, ou simplement «dynamic», lorsque la majorité de sa vérification de type est effectuée à l’exécution plutôt qu’à la compilation. En typage dynamic, les types sont associés à des valeurs et non à des variables. Les langages à typage dynamic incluent Groovy, JavaScript, Lisp, Lua, Objective-C, Perl (en ce qui concerne les types définis par l’utilisateur mais pas les types intégrés), PHP, Prolog, Python, Ruby, Smalltalk et Tcl. Par rapport au typage statique, le typage dynamic peut être plus flexible (par exemple, en permettant aux programmes de générer des types et des fonctionnalités basés sur des données d’exécution), mais au prix de moins de garanties a priori. En effet, un langage typé dynamicment accepte et tente d’exécuter des programmes pouvant être considérés comme non valides par un vérificateur de type statique.

La saisie dynamic peut entraîner des erreurs de type à l’exécution, c’est-à-dire qu’au moment de l’exécution, une valeur peut avoir un type inattendu et qu’une opération non sensée pour ce type est appliquée. Cette opération peut se produire longtemps après l’endroit où l’erreur de programmation a été commise, c’est-à-dire l’endroit où le mauvais type de données est passé à un endroit qu’il ne devrait pas avoir. Cela rend le bug difficile à localiser.

Les systèmes de langage à typage dynamic, comparés à leurs cousins ​​typés statiquement, effectuent moins de contrôles à la compilation sur le code source (mais vérifient, par exemple, que le programme est syntaxiquement correct). Les contrôles d’exécution peuvent potentiellement être plus sophistiqués, car ils peuvent utiliser des informations dynamics ainsi que toute information présente lors de la compilation. D’autre part, les contrôles d’exécution ne permettent d’affirmer que les conditions sont respectées dans une exécution particulière du programme, et ces contrôles sont répétés pour chaque exécution du programme.

Le développement dans des langages typés dynamicment est souvent pris en charge par des pratiques de programmation telles que les tests unitaires. Les tests sont une pratique clé dans le développement de logiciels professionnels et sont particulièrement importants dans les langages à typage dynamic. En pratique, les tests effectués pour garantir le bon fonctionnement du programme peuvent détecter une plage d’erreurs beaucoup plus étendue que la vérification statique, mais inversement, ils ne peuvent pas rechercher de manière aussi complète les erreurs détectables par les tests et les vérifications statiques. Les tests peuvent être incorporés dans le cycle de construction du logiciel, auquel cas il peut être considéré comme une vérification au moment de la compilation, car l’utilisateur du programme n’aura pas à exécuter manuellement de tels tests.

Les références

  1. Pierce, Benjamin (2002). Types et langages de programmation. MIT Press. ISBN 0-262-16209-1.

La terminologie “typée dynamicment” est malheureusement trompeuse. Toutes les langues sont typées statiquement et les types sont des propriétés d’expressions (pas de valeurs comme certains le pensent). Cependant, certaines langues n’ont qu’un seul type. Celles-ci sont appelées des langues uni-typées. Un exemple d’un tel langage est le lambda calcul non typé.

Dans le lambda calcul non typé, tous les termes sont des termes lambda, et la seule opération pouvant être effectuée sur un terme est de l’appliquer à un autre terme. Par conséquent, toutes les opérations se traduisent toujours par une récursion infinie ou un terme lambda, mais ne signalent jamais une erreur.

Cependant, si nous devions augmenter le calcul lambda non typé avec des nombres primitifs et des opérations arithmétiques, alors nous pourrions effectuer des opérations non sensuelles, telles que l’ajout de deux termes lambda: (λx.x) + (λy.y) . On pourrait dire que la seule chose saine à faire est de signaler une erreur lorsque cela se produit, mais pour ce faire, chaque valeur doit être étiquetée avec un indicateur qui indique si le terme est un terme lambda ou un nombre. L’opérateur d’addition vérifiera alors que les deux arguments sont bien marqués en tant que nombres et, s’ils ne le sont pas, signalent une erreur. Notez que ces balises ne sont pas des types, car les types sont des propriétés des programmes, pas des valeurs produites par ces programmes.

Un langage uni-typé qui le fait est appelé typé dynamicment.

Des langages tels que JavaScript, Python et Ruby sont tous uni-typés. Encore une fois, l’opérateur typeof en JavaScript et la fonction de type en Python ont des noms trompeurs; ils renvoient les balises associées aux opérandes, pas à leurs types. De même, dynamic_cast en C ++ et instanceof en Java ne font pas de vérifications de type.

Les langues typées statiquement vérifient au moment de la compilation et le type ne peut PAS changer. (Ne soyez pas mignon avec les commentaires de type, une nouvelle variable / référence est créée).

Les langages à typage dynamic vérifient à l’exécution et le type d’une variable peut être modifié au moment de l’exécution.

Des définitions douces et simples, mais adaptées au besoin: les langages typés statiquement lient le type à une variable pour toute son étendue (Seg: SCALA) Les langages à typage dynamic lient le type à la valeur réelle référencée par une variable.

  • Dans un langage typé statiquement, une variable est associée à un type connu au moment de la compilation, et ce type rest inchangé tout au long de l’exécution d’un programme. De manière équivalente, la variable ne peut être affectée qu’une valeur qui est une instance du type connu / spécifié.
  • Dans un langage typé dynamicment, une variable n’a pas de type et sa valeur pendant l’exécution peut être n’importe quelle forme et forme.

Compilé vs interprété

“Quand le code source est traduit”

  • Code source : code original (généralement saisi par un humain dans un ordinateur)
  • Traduction : convertir le code source en quelque chose qu’un ordinateur peut lire (code machine)
  • Run-Time : période pendant laquelle le programme exécute des commandes (après compilation, si compilé)
  • Langage compilé : code traduit avant l’exécution
  • Langage interprété : code traduit à la volée, pendant l’exécution

Dactylographie

“Quand les types sont cochés”

5 + '3' est un exemple d’erreur de type dans les langages fortement typés tels que Go et Python, car ils n’autorisent pas la “contrainte de type” -> la possibilité pour une valeur de changer de type dans certains contextes tels que la fusion de deux les types. Les langages faiblement typés , tels que JavaScript, ne génèrent pas d’erreur de type (avec pour résultat '53' ).

  • Statique : types vérifiés avant l’exécution
  • Dynamic : Types vérifiés à la volée, pendant l’exécution

Les définitions de “Static & Comstackd” et “Dynamic & Interpreted” sont assez similaires … mais rappelez-vous que “lorsque les types sont vérifiés” vs “lorsque le code source est traduit”.

Vous obtiendrez les mêmes erreurs de type, que la langue soit compilée ou interprétée ! Vous devez séparer ces termes conceptuellement.


Exemple Python

Dynamique, Interprété

 def silly(a): if a > 0: print 'Hi' else: print 5 + '3' silly(2) 

Python étant à la fois interprété et typé dynamicment, il ne fait que traduire et taper le code qu’il exécute. Le bloc else ne s’exécute jamais, donc on ne regarde même pas 5 + '3' !

Et si c’était typé statiquement?

Une erreur de type serait lancée avant même que le code ne soit exécuté. Il effectue toujours une vérification de type avant l’exécution, même si elle est interprétée.

Et si c’était compilé?

Le bloc else serait traduit / examiné avant l’exécution, mais parce qu’il est tapé dynamicment, cela ne provoquerait pas d’erreur! Les langages typés dynamicment ne vérifient pas les types jusqu’à l’exécution et cette ligne ne s’exécute jamais.


Go Exemple

Statique, compilé

 package main import ("fmt" ) func silly(a int) { if (a > 0) { fmt.Println("Hi") } else { fmt.Println("3" + 5) } } func main() { silly(2) } 

Les types sont vérifiés avant exécution (statique) et l’erreur de type est immédiatement détectée! Les types seraient toujours vérifiés avant l’exécution si elle était interprétée, ayant le même résultat. Si elle était dynamic, elle ne renverrait aucune erreur même si le code serait examiné lors de la compilation.


Performance

Un langage compilé aura de meilleures performances au moment de l’exécution s’il est typé statiquement (vs dynamicment); la connaissance des types permet une optimisation du code machine.

Les langages typés statiquement ont de meilleures performances au moment de l’exécution insortingnsèquement car ils n’ont pas besoin de vérifier les types dynamicment lors de l’exécution (ils vérifient avant de lancer).

De même, les langages compilés sont plus rapides lors de l’exécution car le code a déjà été traduit au lieu de devoir “interpréter” / traduire à la volée.

Notez que les langages compilés et statiquement typés auront respectivement un délai avant leur exécution pour la traduction et la vérification de type.


Plus de différences

Le typage statique détecte rapidement les erreurs au lieu de les trouver lors de l’exécution (particulièrement utile pour les programmes longs). Il est plus “ssortingct” dans le sens où il ne permet aucune erreur de type dans votre programme et empêche souvent les variables de changer de type, ce qui permet de se défendre contre les erreurs involontaires.

 num = 2 num = '3' // ERROR 

La saisie dynamic est plus flexible, ce que certains apprécient. Cela permet généralement aux variables de modifier les types, ce qui peut entraîner des erreurs inattendues.

Un typage fort signifie probablement que les variables ont un type bien défini et qu’il existe des règles ssortingctes sur la combinaison de variables de types différents dans les expressions. Par exemple, si A est un entier et B est un flottant, la règle ssortingcte concernant A + B pourrait être que A est converti en un flottant et que le résultat est renvoyé sous forme de flottant. Si A est un entier et B une chaîne, la règle ssortingcte pourrait être que A + B n’est pas valide.

Le typage statique signifie probablement que les types sont affectés au moment de la compilation (ou son équivalent pour les langues non compilées) et ne peuvent pas être modifiés pendant l’exécution du programme.

Notez que ces classifications ne s’excluent pas mutuellement, en effet, je m’attendrais à ce qu’elles se produisent fréquemment. De nombreuses langues fortement typées sont également typées statiquement.

Et notez que lorsque j’utilise le mot «probablement», c’est parce qu’il n’y a pas de définitions universellement acceptées de ces termes. Comme vous l’avez déjà vu dans les réponses jusqu’à présent.

En termes simples: dans un langage typé statiquement, le type est statique , ce qui signifie qu’une fois que vous définissez une variable sur un type, vous ne pouvez PAS la modifier. En effet, la saisie est associée à la variable et non à la valeur à laquelle elle fait référence.

Par exemple en Java:

 Ssortingng str = "Hello"; //statically typed as ssortingng str = 5; //would throw an error since java is statically typed 

Alors que dans un langage typé dynamicment, le type est dynamic , ce qui signifie qu’après avoir défini une variable sur un type, vous POUVEZ le modifier. En effet, la saisie est associée à la valeur plutôt qu’à la variable.

Par exemple en Python:

 str = "Hello" # it is a ssortingng str = 5 # now it is an integer; perfectly OK 

Par contre, le typage fort / faible dans un langage est lié aux conversions de types implicites (en partie issues de la réponse de @ Dario):

Par exemple en Python:

 str = 5 + "hello" # would throw an error since it does not want to cast one type to the other implicitly. 

alors qu’en PHP:

 $str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0 // PHP is weakly typed, thus is a very forgiving language. 

Le typage statique permet de vérifier l’exactitude du type au moment de la compilation. Les langages typés statiquement sont généralement compilés et les langages typés dynamicment sont interprétés. Par conséquent, les langages typés de manière dynamic peuvent vérifier la saisie au moment de l’exécution.

Langages typés statiquement : chaque variable et expression est déjà connue à la compilation.

(int a; a ne peut prendre que des valeurs de type entier à l’exécution)

Par exemple: C, C ++, Java

Langages typés dynamicment : varialbes peut recevoir différentes valeurs à l’exécution et son type est défini au moment de l’exécution.

(var a; a peut prendre n’importe quel type de valeurs à l’exécution)

Par exemple: Ruby, Python.

Les langages typés statiquement comme C ++, Java et les langages typés dynamicment comme Python ne diffèrent que par l’exécution du type de la variable. Les langages typés statiquement ont un type de données statique pour la variable, ici le type de données est vérifié pendant la compilation, donc le débogage est beaucoup plus simple … alors que les langages à typage dynamic ne font pas la même chose, le type de données est exécuté le débogage est un peu difficile.

En outre, ils ont une très petite différence et peuvent être liés à des langages fortement typés et faiblement typés . Un langage fortement typé ne vous permet pas d’utiliser un type comme un autre, par exemple. C et C ++ … alors que les langages faiblement typés autorisent eg.python

le langage typé dynamicment permet de prototyper rapidement des concepts d’algorithme sans avoir à réfléchir aux types de variables à utiliser (ce qui est une nécessité dans une langue typée statiquement ).

Dans un langage typé statiquement , chaque nom de variable est lié à la fois à un type (à la compilation, au moyen d’une déclaration de données) à un object. La liaison à un object est facultative – si un nom n’est pas lié à un object, le nom est dit nul. Dans un langage typé dynamicment , chaque nom de variable est (sauf s’il est nul) lié uniquement à un object.

Les noms sont liés aux objects au moment de l’exécution au moyen d’instructions d’affectation, et il est possible de lier un nom à des objects de types différents lors de l’exécution du programme.

Dactylographie statique: Les langages tels que Java et Scala sont de type statique.

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);

Dactylographie dynamic: Perl est un langage typé dynamic.

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