web-dev-qa-db-fra.com

Statique / Dynamique vs Fort / Faible

Je vois ces termes se retrouver partout dans la programmation et j'ai une vague idée de ce qu’ils signifient. Une recherche me montre que de telles choses ont été demandées dans tous les cas de débordement de pile. Autant que je sache, le typage statique/dynamique dans les langues diffère légèrement du typage fort/faible, mais cette différence m'échappe. Différentes sources semblent utiliser différentes significations ou même utiliser les termes de manière interchangeable. Je n'arrive pas à trouver un endroit qui parle des deux et explique la différence. Ce qui serait bien à Nice, c’est que si quelqu'un puisse, s'il vous plaît, le préciser clairement ici pour moi et le reste du monde.

294
Dan Revell
  • Dactylographie statique/dynamique correspond à lorsque des informations de type sont acquises (à la compilation ou à l'exécution)

  • saisie forte/faible indique comment les types sont distingués de manière stricte (par exemple, si le langage essaie de convertir implicitement des chaînes à des nombres).

Voir le wiki-page pour plus d'informations.

388
Dario

Vous avez découvert un point faible dans la terminologie utilisée par les amateurs pour parler de langages de programmation. N'utilisez pas les termes "fort" et "faible", car ils n'ont pas de signification technique universellement reconnue. En revanche, typage statique signifie que les programmes sont vérifiés avant d'être exécutés, et un programme peut être rejeté avant son démarrage. saisie dynamique signifie que les types de valeurs sont vérifiés pendant exécution, et une opération mal typée peut provoquer l'arrêt du programme ou sinon signaler une erreur au moment de l'exécution. Une des raisons principales du typage statique est d'éliminer les programmes qui pourraient avoir de telles "erreurs de type dynamique".

typage fort signifie généralement qu'il y a pas de meurtrières dans le système de typage, alors que typage faible signifie que le système de typage peut être subverti (annulation de toute garantie) . Les termes sont souvent utilisés à tort pour désigner le typage statique et dynamique. Pour voir la différence, pensez à C: la langue est vérifiée au moment de la compilation (typage statique), mais il existe de nombreuses failles; vous pouvez très bien attribuer une valeur de n'importe quel type à un autre type de la même taille - en particulier, vous pouvez librement utiliser des types de pointeur. Pascal était un langage destiné à être fortement typé, mais il avait une échappatoire imprévue: un enregistrement variant sans étiquette.

Les implémentations de langages fortement typés acquièrent souvent des failles dans le temps, ce qui permet généralement de mettre en œuvre une partie du système d'exécution dans le langage de haut niveau. Par exemple, Objective Caml a une fonction appelée Obj.magic qui a pour effet d’exécuter simplement le renvoi de son argument au moment de l’exécution, mais convertit au moment de la compilation une valeur de tout type en une autre de tout type. Mon exemple préféré est Modula-3, dont les concepteurs ont appelé leur structure de transtypage LOOPHOLE.

Cela dit, vous ne pouvez pas compter sur deux personnes utilisant les mots "fort" et "faible" exactement de la même manière. Alors évitez-les.

201
Norman Ramsey

Pour le dire simplement: dans un langage statiquement typé, le type est statique , ce qui signifie que vous définissez une variable sur un type , vous NE POUVEZ PAS le changer. En effet, la frappe est associée à la variable plutôt qu'à la valeur à laquelle elle fait référence.

Par exemple en Java:

String str = "Hello";  //statically typed as string
str = 5;               //would throw an error since Java is statically typed

Considérant que dans un langage dynamiquement typé, le type est dynamique , ce qui signifie qu'après avoir défini une variable sur un type, vous POUVEZ la modifier. . En effet, la frappe est associée à la valeur plutôt qu'à la variable.

Par exemple en Python:

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

D'autre part, le typage fort/faible dans une langue est lié à des conversions de types implicites (partiellement extraites 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 à typage statique sont généralement compilés et les langages à typage dynamique sont interprétés. Par conséquent, les langages typés de manière dynamique peuvent vérifier la saisie au moment de l'exécution.

65
mehmet

Un typage faible signifie que le type d'un objet peut changer en fonction du contexte. Par exemple, dans un langage faiblement typé, la chaîne "123" peut être traitée comme le nombre 123 si vous lui ajoutez un autre numéro. Bash, awk et PHP sont des exemples de langues à typage faible.

C est un autre type de langage faiblement typé, où les données d’une adresse mémoire peuvent être traitées comme un type différent par transtypage.

Dans un langage fortement typé, le type d'un objet ne change pas - un int est toujours un int et son utilisation sous forme de chaîne entraînera une erreur. Les deux Java et Python sont fortement typés).

La différence entre le typage dynamique et statique est lorsque les règles de type sont appliquées. Dans un langage à typage statique, le type de chaque variable et paramètre doit être déclaré dans la source et est appliqué lors de la compilation. Dans un langage typé dynamiquement, les types ne sont vérifiés que lorsqu'ils sont utilisés au moment de l'exécution. Donc Java est typé de manière statique et Python est typé de manière dynamique.

Cependant, les limites peuvent parfois être un peu floues. Par exemple, bien que Java soit typé de manière statique, chaque fois que vous utilisez une réflexion ou une conversion (par exemple, lorsque vous utilisez des conteneurs d'objets), vous différez la vérification du type au moment de l'exécution.

De la même façon, les langages les plus fortement typés convertissent toujours automatiquement entre les entiers et les flottants (et dans certaines langues une précision approximative BigInts).

19
Dave Kirby

Aujourd'hui, en effectuant des recherches sur ce sujet, je suis tombé sur ce bel article http://blogs.Perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html = Cela a éclairci beaucoup de choses pour moi et j'ai pensé que cela pourrait ajouter certaines des bonnes réponses ci-dessus.

Dactylographie forte et faible:

La manière la plus courante de classer les systèmes de types est probablement "forte" ou "faible". C'est regrettable, car ces mots n'ont presque aucune signification. Il est possible, dans une mesure limitée, de comparer deux langages avec des systèmes de types très similaires et d'en désigner un qui possède le plus fort de ces deux systèmes. Au-delà, les mots ne veulent rien dire du tout.

Types statiques et dynamiques

C’est à peu près la seule classification commune des systèmes de types qui ait une signification réelle. En fait, son importance est souvent sous-estimée [...] Les systèmes de type statique et statique sont deux choses complètement différentes, dont les objectifs se chevauchent partiellement.

Un système de types statiques est un mécanisme par lequel un compilateur examine le code source et attribue des étiquettes (appelées "types") à des éléments de la syntaxe, puis les utilise pour déduire un élément du comportement du programme. Un système de type dynamique est un mécanisme par lequel un compilateur génère un code permettant de garder une trace du type de données (comme par hasard, également appelé son "type") utilisé par le programme. L'utilisation du même mot "type" dans chacun de ces deux systèmes n'est bien entendu pas tout à fait par hasard; cependant, on comprend au mieux qu’il a une sorte de faible signification historique. Une grande confusion résulte de la recherche d’une vision du monde dans laquelle "type" signifie vraiment la même chose dans les deux systèmes. Ce n'est pas.

Types explicites/implicites:

Lorsque ces termes sont utilisés, ils se réfèrent à la mesure dans laquelle un compilateur raisonnera sur les types statiques de parties d'un programme. Tous les langages de programmation ont une forme de raisonnement à propos des types. Certains ont plus que d'autres. ML et Haskell ont des types implicites, en ce sens qu'aucune déclaration de type n'est nécessaire (ou très peu, en fonction du langage et des extensions utilisés). Java et Ada ont des types très explicites, et on déclare constamment les types d'éléments). Tous les systèmes ci-dessus ont (relativement, comparé à C et C++, par exemple) des systèmes de types statiques forts.

13
gonz

De Scott's Pragmatique en Langage de Programmation, 3ème édition page 291, nous avons

La vérification de type est le processus permettant de s’assurer que le programme respecte les règles de compatibilité du type de langage. Une violation des règles est connue sous le nom de conflit de type. Une langue est dite fortement typée si elle interdit, de manière que l'implémentation de la langue puisse l'imposer, l'application de toute opération à un objet qui est pas destiné à soutenir cette opération. Une langue est dite typée de manière statique si elle est fortement typée et que la vérification du type peut être effectuée au moment de la compilation. Dans le sens le plus strict du terme, peu de langues sont typées statiquement. En pratique, les termes sont souvent appliqués aux langages dans lesquels la plupart des vérifications de type peuvent être effectuées au moment de la compilation, le reste pouvant être effectué au moment de l'exécution.

Quelques exemples: Ada est fortement typé et, pour la plupart, de manière statique (certaines contraintes de type doivent être vérifiées au moment de l'exécution). Une implémentation Pascal peut également effectuer l'essentiel de sa vérification de type au moment de la compilation, bien que le langage ne soit pas assez typé: les enregistrements de variantes non étiquetés (à traiter dans la section 7.3.4) constituent sa seule échappatoire. Le C89 est significativement plus typé que ses prédécesseurs, mais toujours moins typé que Pascal. Ses lacunes incluent les unions, les sous-programmes à nombre variable de paramètres et l’interopérabilité des pointeurs et des tableaux (à examiner dans la section 7.7.1). Les implémentations de C vérifient rarement quoi que ce soit au moment de l'exécution.

La vérification de type dynamique (à l'exécution) est une forme de liaison tardive et tend à être trouvée dans des langues qui retardent également d'autres problèmes jusqu'au moment de l'exécution. LISP et Smalltalk sont typés de manière dynamique (bien que forte). La plupart des langages de script sont également typés de manière dynamique. certains (par exemple, Python et Ruby) sont fortement typés. Les langues à portée dynamique sont généralement typées de manière dynamique (ou pas du tout typées): si le compilateur ne peut pas identifier l'objet auquel un nom est attribué fait référence, il ne peut généralement pas déterminer le type de l'objet non plus.

Donc, en termes simples, le typage statique/dynamique fait référence au moment où la vérification de type a lieu: le temps de compilation pour le typage statique et le temps d'exécution pour les langages dynamiques. De même, le typage fort/faible fait référence au degré d'agressivité d'un langage dans l'application de son système de types.

J'ai essayé de traduire la description de Scott en un diagramme de Nice, que j'ai posté ci-dessous.

The Static/Dynamic - Strong/Weak Typing Plane

6
Evan Rosica

Je pense que les autres collègues ont fait du bon travail, esp. expliquer la différence entre le typage statique et dynamique. Mais en ce qui concerne le typage fort et le typage faible, il faut dire qu'il existe des compréhensions/points de vue différents.

Voici deux exemples:

  • Certains disent que Haskell est fortement typé, parce que vous n'êtes pas autorisé à faire des conversions de type tout type.

  • D’autres (par exemple, le point de vue de Dario) disent que le langage qui permet de convertir implicitement une chaîne en chiffres est peu typé, mais d’autres encore appellent cela du simple dactylographie.

Les deux déclarations soulignent non pas les extrêmes opposés d’un système de types, mais des aspects complètement différents. Je rejoins donc l'opinion de M. Ramsey de ne pas utiliser les termes "fort" et "faible" pour distinguer les systèmes de types.

5
Nico

Langues statiquement v/s typées dynamiquement

  • Les langages à typage statique sont ceux dans lesquels la vérification de type est effectuée au moment de la compilation, ce qui signifie également que dans les langages à typage statique, chaque variable a un type et ne change pas au cours du cours. Maintenant , au contraire, les langages à typage dynamique sont ceux dans lesquels la vérification de type est effectuée à l'exécution, et il n'y a pas de vérification de type à la compilation, ce qui signifie également que dans les langages à typage dynamique, un type peut être associé ou non à un type. avec une variable, et si un type est associé, il pourrait s'agir d'un type générique tel que "var" dans JS, qui s'applique à la fois à une chaîne et à un nombre.
    • "Les implémentations de langages vérifiés de type dynamiquement associent généralement chaque objet d’exécution à une balise de type (c’est-à-dire une référence à un type) contenant ses informations de type. Ces informations de type à l'exécution (RTTI) peuvent également être utilisées pour implémenter la répartition dynamique, la liaison tardive, le transtypage, la réflexion et des fonctionnalités similaires. ”
  • Même si la langue est typée de manière statique, elle pourrait néanmoins avoir une fonctionnalité typée de manière dynamique, ce qui signifie en gros une sorte de vérification du type au moment de l'exécution. Ceci est utile pour la conversion des types.
    • "Un certain nombre de fonctionnalités utiles et communes du langage de programmation ne peuvent pas être vérifiées statiquement, telles que le down casting. Ainsi, de nombreuses langues auront à la fois une vérification de type statique et dynamique; le vérificateur de type statique vérifie ce qu'il peut et les vérifications dynamiques vérifient le reste. ”
  • “Certaines langues autorisent l'écriture de code non typé. Par exemple, en C, les programmeurs peuvent librement convertir une valeur entre deux types quelconques de même taille. ”
  • L'avantage des langages typés "statiquement" est que:
    • Comme la plupart des vérifications de types sont effectuées au moment de la compilation, interprète ou runtime peut fonctionner à toute vitesse, sans se soucier des types.
    • Cela entraîne moins d'exceptions ou d'erreurs d'exécution liées au type, car la plupart du temps, la vérification du type est effectuée au moment de la compilation.
  • L'avantage des langages typés "dynamiquement" est que:
    • Ils pourraient aider au prototypage extrêmement rapide, car les développeurs n'ont pas besoin de comprendre le système de types. Dev peut donc créer des variables et les exécuter, ce qui conduit à un prototypage très rapide.
  • Liste des langages typés statiquement et dynamiquement:
    • Statiquement:
      • Java
      • C (C is a statically typed language but lesser “strongly” typed as compared to Java because it allows more implicit conversions)
      • C++
      • C #
    • Dynamiquement:
      • Perl
      • PHP
      • Python
      • JavaScript
      • Ruby
  • La vérification de type est une fonction de sécurité importante. Supposons qu'il n'y ait pas de vérification de type et qu'une méthode accepte un objet de type "BankAccount" qui possède une méthode appelée "creditAccount (BankAccountDetails)", maintenant au moment de l'exécution, s'il n'y a pas de vérification de type, je peux passer un objet de ma propre classe qui a la même méthode "creditAccount (BankAccountDetails)" et il sera exécuté, étant donné que nous parlons de langage orienté objet car OOP prend en charge le "polymorphisme" et nous ne discutons ici que du "polymorphisme". Ainsi, un langage orienté objet (ce qui signifie fondamentalement qu'il prend en charge le "polymorphisme") qui n'a pas de vérification de type stricte peut poser des problèmes de sécurité. .

Langages fortement typés v/s

  • Les langages fortement typés sont ceux dans lesquels les conversions implicites ne sont pas autorisées en cas de perte de précision. Par exemple, en Java, vous pouvez convertir un "int en long" car il n'y a pas de perte de précision, mais vous ne pouvez pas "implicitement" transtyper un "long pour int" car il y aurait une perte de précision. En revanche, dans les langages faiblement typés, les conversions implicites sont autorisées même en cas de perte de précision.
  • Je pense qu'un langage à typage dynamique peut également être un langage à typage fort si "au moment de l'exécution" il ne permet pas les conversions implicites dans lesquelles il y a une perte de précision.

Bonnes lectures

4
hagrawal

Les langages à typage statique nécessitent généralement de déclarer les types de variables, qui sont ensuite vérifiées lors de la compilation pour réduire les erreurs. Le mot "statique" dans "de type statique" fait référence à "l'analyse de code statique", processus qui consiste à examiner le code avant de l'exécuter. Bien qu’un langage à typage statique puisse déduire le type de la variable à partir du côté droit d’une expression ou de paramètres réels, dans la pratique, la plupart des langages à typage statique exigent que les types de variable soient explicitement déclarés.

Les langages à typage dynamique n'exigent généralement pas que les déclarations de variable aient des types, et ils déduisent des types de variable en fonction du type calculé à la suite de l'évaluation du côté droit de chaque instruction d'affectation ou des paramètres réels à un appel de fonction. Étant donné que la variable peut recevoir plusieurs affectations au cours de sa vie, son type peut changer avec le temps. C'est pourquoi on l'appelle "typé dynamiquement". En outre, l'environnement d'exécution doit suivre le type actuel pour chaque variable, de sorte que le type est lié à la valeur plutôt qu'à la déclaration de variable. Ceci peut être considéré comme un système d'informations de type à l'exécution (RTTI).

Des éléments de langages typés dynamiquement et statiquement peuvent être combinés. Par exemple, C # prend en charge les variables à la fois statiques et dynamiques, tandis que les langages orientés objet prennent généralement en charge la rétrogradation de la hiérarchie des types. Les langages à typage statique offrent généralement différents moyens de contourner la vérification de type, par exemple en utilisant le transtypage, la réflexion et l'appel dynamique.

Caractère fort ou faible Le typage fait référence à un continuum de la mesure dans laquelle le langage tente d'empêcher les bogues dus à l'utilisation d'une variable comme s'il s'agissait d'un type alors qu'il s'agit en fait d'un autre type. Par exemple, C et Java sont des langages à typage statique, mais Java utilise une vérification de type beaucoup plus puissante que celle de C. Le code C suivant est très simple à compiler et à exécuter , et mettra une valeur aléatoire dans la variable b au moment de l’exécution, causant très probablement un bogue:

char *a = "123";
int b = (int)a;

Le code équivalent Java générera une erreur de compilation, ce qui est généralement préférable:

String a = "123"
int b = (int)a;
1
Danger

J'ai récemment écrit un article expliquant ce sujet précis:

https://dev.to/jiangh/type-systems-dynamic-versus-static-strong-versus-weak-b6c

0
Hong Jiang