Statique / Dynamique vs Fort / Faible

319

Je vois ces termes circuler 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é posées partout en débordement de pile en fait. Pour autant que je sache, le typage statique / dynamique dans les langues est subtilement différent du typage fort / faible, mais quelle est cette différence m'échappe. Différentes sources semblent utiliser des significations différentes ou même utiliser les termes de manière interchangeable. Je ne trouve pas un endroit qui parle des deux et qui explique la différence. Ce qui serait bien, c'est que quelqu'un puisse expliquer cela clairement ici pour moi et le reste du monde.

Dan Revell
la source

Réponses:

423
  • La frappe statique / dynamique concerne le moment où les informations de type sont acquises (soit au moment de la compilation soit au moment de l'exécution)

  • Le typage fort / faible concerne la distinction stricte entre les types (par exemple, si le langage essaie de faire une conversion implicite des chaînes en nombres).

Voir la page wiki pour des informations plus détaillées.

Dario
la source
7
Wikipédia a toutes les réponses. Pourquoi je ne suis pas déjà tombé dessus, je ne sais pas.
Dan Revell
31
C'est dommage que beaucoup ne soient pas conscients que statique / dynamique est autre chose que fort / faible ... Cela sauverait vraiment des biais et des discussions.
Dykam
10
Il existe différents degrés de «faiblesse de type». Une langue fortement typée pourrait tenter des conversions de chaînes en nombres. D'un autre côté, HyperTalk (un langage que j'utilisais il y a des décennies) était si faiblement typé qu'il "12" + "34"serait égal "46", mais "12" + "34Q"égal "1234Q"[heureusement, on pourrait écrire "12" & "34"si l'on voulait la concaténation]. Curieusement, les variables contenant des nombres les stockaient sous forme de flottants à double précision, et les mathématiques sur ces variables utilisaient les valeurs à virgule flottante sans fusion de chaîne, mais il n'y avait aucun moyen de demander si une variable était une chaîne ou un nombre.
supercat
9
@kittylyst Je ne vois pas où cette réponse suggère que fort est synonyme de statique
Pete
4
++ pour (grossièrement) les définitions d'une seule ligne.
JamesFaix
211

Vous avez découvert un point faible dans la terminologie que les amateurs utilisent pour parler des langages de programmation. N'utilisez pas les termes «fort» et «faible» , car ils n'ont pas une signification technique universellement acceptée. En revanche, le typage statique signifie que les programmes sont vérifiés avant d'être exécutés et qu'un programme peut être rejeté avant son démarrage. Le typage dynamique signifie que les types de valeurs sont vérifiés pendant l' exécution et qu'une opération mal typée peut entraîner l'arrêt du programme ou signaler une erreur au moment de l'exécution . Une raison principale du typage statique est d'exclure les programmes qui pourraient avoir de telles "erreurs de type dynamique".

Un typage fort signifie généralement qu'il n'y a pas de failles dans le système de typage , tandis qu'un typage faible signifie que le système de typage peut être inversé (annulant toute garantie). Les termes sont souvent utilisés de manière incorrecte pour désigner une frappe statique et dynamique. Pour voir la différence, pensez à C: le langage est vérifié au moment de la compilation (typage statique), mais il y a beaucoup de failles; vous pouvez à peu près convertir une valeur de n'importe quel type en un autre type de la même taille --- en particulier, vous pouvez convertir librement les types de pointeurs. Pascal était une langue qui devait être fortement typée mais qui avait une faille imprévue: une variante d'enregistrement sans étiquette.

Les implémentations de langages fortement typés acquièrent souvent des failles au fil du temps, généralement de sorte qu'une partie du système d'exécution peut être implémentée dans le langage de haut niveau. Par exemple, Objective Caml a une fonction appelée Obj.magicqui a pour effet au moment de l'exécution de simplement renvoyer son argument, mais au moment de la compilation, elle convertit une valeur de n'importe quel type en une autre. Mon exemple préféré est Modula-3, dont les concepteurs ont appelé leur construction de type-casting LOOPHOLE.

Cela dit, vous ne pouvez pas compter sur deux personnes utilisant exactement les mêmes mots "fort" et "faible". Alors évitez-les.

Norman Ramsey
la source
31
(+1) pour votre suggestion d'éviter les termes "fort" et "faible".
Nico
1
D'accord, je lisais simplement le livre de Jon Skeet, et c'est la même réponse qui y est notée.
Bennett Yeates
Pour autant que je sache, Java a également ces lacunes, mais il est toujours considéré comme un langage fortement typé, donc je suppose que cela donne plus de poids à vos conseils d'éviter les termes "fort" et "faible".
doubleOrt
74

Autrement dit, dans un langage de type statique , le type est statique , ce qui signifie qu'une fois que vous définissez une variable sur un type, vous NE POUVEZ PAS la changer. En effet, la saisie est associée à la variable plutôt qu'à la valeur à laquelle elle se réfère.

Par exemple en Java:

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

Alors que dans un langage typé dynamiquement, le type est dynamique , ce qui signifie qu'après avoir défini une variable sur un type, vous POUVEZ le changer. En effet, la saisie 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'un autre côté, le typage fort / faible dans une langue est lié à des conversions de type implicites (en partie tirées 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 langues typées statiquement sont généralement compilées et les langues typées dynamiquement sont interprétées. Par conséquent, les langues typées dynamiquement peuvent vérifier la frappe au moment de l'exécution.

mehmet
la source
2
excellente réponse, et bravo pour l'utilisation d'exemples concrets.
Julian A.
3
C'est pourquoi PHP doit être utilisé avec grand soin.
Ali Gajani
1
Les exemples de langue sont vraiment utiles. Très appréciée.
J Mullen
Dans ce sens, Java serait-il si légèrement faiblement typé parce que vous pouvez concaténer des non-chaînes avec des chaînes et à cause de la décompression automatique / de la boxe?
Stephen Paul
1
@StephenPaul vous avez raison, ma réponse peut être comprise de cette façon, et ce n'est pas le cas. J'ai utilisé la concaténation par souci de simplicité, mais en fait, force / faiblesse concerne la conversion de type implicite de la variable elle-même.
mehmet
20

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

Un autre type de langage faiblement typé est C, où les données à 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 essayer de l'utiliser comme chaîne entraînera une erreur. Java et Python sont fortement typés.

La différence entre la frappe dynamique et statique est lorsque les règles de type sont appliquées. Dans un langage typé statiquement, le type de chaque variable et paramètre doit être déclaré dans la source et est appliqué au moment 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. Java est donc typé statiquement et Python est typé dynamiquement.

Cependant, les limites peuvent parfois être un peu floues. Par exemple, bien que Java soit typé de façon statique, chaque fois que vous utilisez une réflexion ou un transtypage (par exemple lorsque vous utilisez des conteneurs d'objets), vous reportez la vérification de type à l'exécution.

De même, la plupart des langages fortement typés seront toujours automatiquement convertis entre des entiers et des flottants (et dans certains langages, une précision approximative BigInts).

Dave Kirby
la source
1
Je ne peux pas être d'accord avec cette phrase -. "Dans un langage à typage statique, le type de chaque variable et paramètre doit être déclaré dans la source" - en SML, les types de variables n'ont pas à être déclarés (quelle que soit la manière dont ils sont vérifiés). Disons que la fonction fprend l'argument x( fun f(x)) [** donc aucun type n'est déclaré **] et le corps de la fonction l'est x+1. Sans types déclarés, le compilateur découvrira qu'il xdoit s'agir d'un entier. - fun f x = x + 1; val f = fn : int -> int
Filip Bartuzi
En ce qui concerne C, le casting n'est pas contre le typage fort, mais C permet d'ajouter différents types sans casting aussi, par exemple:5 + 'c' // OK
mehmet
3
@mehmet: en C, les valeurs de caractères sont dans le domaine entier, de sorte que cet exemple particulier ne viole pas la sécurité des types. 'c' est juste du sucre syntaxique pour 99. C n'a pas de type de caractère dédié.
Peter Lewerin
Peter Lewerin: oui, j'aurais dû donner un meilleur exemple. Malheureusement, cela fait presque 20 ans que je n'ai pas touché C :)
mehmet
1
C pas une langue faiblement typée . C'est juste que Java, C # etc. sont des langages plus fortement typés par rapport à C. Lire la suite ici - en.wikipedia.org/wiki/Strong_and_weak_typing Si vous vérifiez la définition de langage typé "faiblement" puis les langages typés "faiblement" sont ceux dans lesquels vous pouvez effectuer n'importe quel type de conversion, par exemple un int peut être "implicitement" converti ou converti en une chaîne, pensez-vous maintenant que cela est possible en C ou non?
hagrawal
15

Aujourd'hui, faisant des recherches sur ce sujet, je suis tombé sur cet excellent article http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html Il a éclairci beaucoup de des choses pour moi et je pensais que cela pourrait ajouter à certaines des bonnes réponses ci-dessus.

Typage fort et faible:

La classification des systèmes de types les plus courants est probablement «forte» ou «faible». C'est regrettable, car ces mots n'ont presque aucun sens. Il est possible, dans une mesure limitée, de comparer deux langues avec des systèmes de type très similaires et d'en désigner une comme ayant la plus forte de ces deux systèmes. Au-delà de cela, les mots ne signifient rien du tout.

Types statiques et dynamiques

Il s'agit presque de la seule classification commune des systèmes de types qui ait un sens réel. En fait, sa signification est souvent sous-estimée [...] Les systèmes de type dynamique et statique sont deux choses complètement différentes, dont les objectifs se chevauchent partiellement.

Un système de type statique est un mécanisme par lequel un compilateur examine le code source et attribue des étiquettes (appelées "types") à des morceaux de la syntaxe, puis les utilise pour déduire quelque chose sur le comportement du programme. Un système de type dynamique est un mécanisme par lequel un compilateur génère du code pour garder une trace du type de données (par coïncidence, également appelé son "type") utilisé par le programme. L'emploi du même mot "type" dans chacun de ces deux systèmes n'est bien sûr pas vraiment une pure coïncidence; pourtant, il vaut mieux le comprendre comme ayant 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 le cas.

Types explicites / implicites:

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

gonz
la source
8

D'après Scott's Programming Language Pragmatics , 3e édition, page 291, nous avons

La vérification de type est le processus permettant de s'assurer qu'un programme respecte les règles de compatibilité de type du langage. Une violation des règles est connue sous le nom de conflit de types. Un langage est dit fortement typé s'il interdit, d'une manière que l'implémentation du langage peut imposer, l'application de toute opération à tout objet qui n'est pas destiné à prendre en charge cette opération. Une langue est dite typée statiquement si elle est fortement typée et que la vérification de type peut être effectuée au moment de la compilation. Au sens strict du terme, peu de langues sont typées statiquement. Dans la pratique, le terme est souvent appliqué aux langues dans lesquelles la plupart des vérifications de type peuvent être effectuées au moment de la compilation, et le reste peut être effectué au moment de l'exécution.

Quelques exemples: Ada est fortement typé, et pour la plupart statiquement typé (certaines contraintes de type doivent être vérifiées au moment de l'exécution). Une implémentation Pascal peut également effectuer la plupart de ses vérifications de type au moment de la compilation, bien que le langage ne soit pas assez fortement typé: les enregistrements de variantes non balisés (à discuter dans la section 7.3.4) sont sa seule faille. C89 est significativement plus fortement typé que ses dialectes précédents, mais toujours beaucoup moins fortement typé que Pascal. Ses lacunes incluent les unions, les sous-programmes avec un nombre variable de paramètres et l'interopérabilité des pointeurs et des tableaux (à discuter 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 (au moment de l'exécution) est une forme de liaison tardive, et a tendance à être trouvée dans les langues qui retardent également d'autres problèmes jusqu'au moment de l'exécution. Lisp et Smalltalk sont typés dynamiquement (mais fortement). La plupart des langages de script sont également typés dynamiquement; certains (par exemple, Python et Ruby) sont fortement typés. Les langages avec portée dynamique sont généralement typés dynamiquement (ou pas du tout): si le compilateur ne peut pas identifier l'objet auquel se réfère un nom, il ne peut généralement pas non plus déterminer le type de l'objet.

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

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

Le plan de frappe statique / dynamique - fort / faible

Evan Rosica
la source
5

Je pense que les autres collègues ont fait du bon travail esp. expliquant 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 différentes compréhensions / vues.

Voici deux exemples:

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

  • D'autres (par exemple le point de vue de Dario) disent qu'un langage qui permet de convertir implicitement de la chaîne en nombre à dessein est faiblement typé, mais même d'autres appellent cela juste du typage canard.

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

Nico
la source
5

Langages typiquement v / s dynamiquement typés

  • Les langues à typage statique sont celles dans lesquelles la vérification de type est effectuée au moment de la compilation, cela signifie donc également que dans les langues à typage statique, chaque variable a un type et ne change pas au cours du cours. Maintenant, en revanche, les langages typés dynamiquement sont ceux dans lesquels la vérification de type est effectuée au moment de l'exécution, et il n'y a pas de vérification de type au moment de la compilation, donc cela signifie également que dans les langages typés dynamiquement, il peut y avoir ou non un type associé à une variable , et si un type est associé, il peut s'agir d'un type générique comme «var» dans JS qui convient à la fois à une chaîne et à un nombre.
    • «Les implémentations de langages à vérification de type dynamique 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 d'exécution (RTTI) peuvent également être utilisées pour implémenter la répartition dynamique, la liaison tardive, la conversion descendante, la réflexion et des fonctionnalités similaires. »
  • Même si le langage est typé de manière statique, il pourrait toujours avoir une fonctionnalité typée dynamiquement, ce qui signifie essentiellement qu'une sorte de vérification de type au moment de l'exécution est également effectuée. Ceci est utile lors de la conversion de types.
    • «Un certain nombre de fonctionnalités de langage de programmation utiles et courantes ne peuvent pas être vérifiées statiquement, comme la conversion vers le bas. Ainsi, de nombreuses langues auront 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 permettent d'écrire du code qui n'est pas sûr pour le type. Par exemple, en C, les programmeurs peuvent librement convertir une valeur entre deux types de même taille. »
  • Les avantages des langages typés «statiquement» sont les suivants:
    • Étant donné que la plupart des vérifications de type sont effectuées au moment de la compilation, l'interpréteur ou l'exécution peut s'exécuter à pleine vitesse, sans se soucier des types.
    • Cela conduit à moins d'exceptions d'exécution ou d'erreurs liées au type, car la plupart des vérifications de type sont effectuées au moment de la compilation.
  • L'avantage des langages typés «dynamiquement» est que:
    • Ils pourraient aider à un prototypage extrêmement rapide, car le développeur n'a pas besoin de comprendre le système de type pour que le développeur puisse créer des variables de manière lâche et l'exécuter, ce qui conduit à un prototypage très rapide.
  • Liste des langues typées statiquement et dynamiquement :
    • Statiquement:
      • Java
      • C (C est un langage typé statiquement mais moins typé «fortement» par rapport à Java car il permet des conversions plus implicites)
      • C ++
      • C #
    • Dynamiquement:
      • PERL
      • PHP
      • Python
      • Javascript
      • Rubis
  • La vérification de type est une caractéristique 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 a 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 à moi classe qui a la même méthode «creditAccount (BankAccountDetails)» et il sera exécuté, étant donné que nous parlons de langage orienté objet parce que la POO prend en charge le «polymorphisme» et ici ce dont nous discutons n'est rien d'autre que du «polymorphisme». Donc, fondamentalement, un langage orienté objet (ce qui signifie qu'il prend en charge le «polymorphisme») qui n'a pas de vérification de type forte peut entraîner des problèmes de sécurité.

Langues fortement typées v / s faiblement typées

  • Les langues fortement typées sont celles dans lesquelles les conversions implicites ne sont pas autorisées en cas de perte de précision. Par exemple, en Java, vous pouvez transtyper un "int en long" car il n'y a pas de perte de précision mais vous ne pouvez pas "implicitement" transtyper un "long en int" car il y aurait une perte de précision. En revanche, dans les langues faiblement typées, les conversions implicites sont autorisées même en cas de perte de précision.
  • Je pense qu'un langage typé dynamiquement peut également être un langage fortement typé si «à l'exécution» il ne permet pas les conversions implicites dans lesquelles il y a perte de précision.

Bonnes lectures supplémentaires

hagrawal
la source
vous avez cité "maintenant à l'exécution s'il n'y a pas de vérification de type alors je peux passer un objet de ma propre classe qui a la même méthode" creditAccount (BankAccountDetails) "- si vous avez déjà dépassé le mécanisme qui aurait pu vous empêcher de passer un objet alors comment la vérification de type vous empêchera d'appeler cette méthode dans le cas d'un langage typé?
Aseem Yadav
@AseemYadav Que voulez-vous dire par "* si vous avez déjà dépassé le mécanisme qui aurait pu vous empêcher de passer un objet *"?
hagrawal
comme vous l'avez mentionné, c'est une fonctionnalité de sécurité importante, et aussi que vous pourriez passer un objet de votre propre classe avec la même méthode, donc cela implique pour moi que cela ne semble être une vulnérabilité que lorsque vous essayez de pénétrer dans le code de quelqu'un d'autre et si vous parlez dans le contexte du code qui vous appartient plutôt que d'un problème de performances plutôt que celui lié à la sécurité, n'est-ce pas?
Aseem Yadav
Il n'y a aucun aspect de performance, vous devez le voir dans un contexte de polymorphisme, vous pourrez alors comprendre l'aspect sécurité de celui-ci, je l'ai mentionné dans le même paragraphe.
hagrawal
1

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

Les langages typés dynamiquement n'ont généralement pas besoin de déclarations de variables pour avoir des types, et ils déduisent des types de variables 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 d'un appel de fonction. Étant donné que la variable peut recevoir plusieurs affectations au cours de sa durée de vie, son type peut changer avec le temps et c'est pourquoi elle est appelée "typée dynamiquement". En outre, l'environnement d'exécution doit garder une trace du type actuel pour chaque variable, de sorte que le type est lié à la valeur plutôt qu'à la déclaration de variable. Cela peut être considéré comme un système RTTI (runtime type information).

Les éléments des langages typés statiquement et dynamiquement peuvent être combinés. Par exemple, C # prend en charge les variables typées statiquement et dynamiquement, et les langages orientés objet prennent généralement en charge la conversion de la hiérarchie des types. Les langages typés statiquement offrent généralement diverses manières de contourner la vérification de type, par exemple en utilisant la conversion, la réflexion et l'invocation dynamique.

Typage fort vs faible fait référence à un continuum de combien le langage essaie 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 typés statiquement, mais Java utilise une vérification de type beaucoup plus forte que C. Le code C suivant est heureux de compiler et d'exécuter, et mettra une valeur aléatoire dans la variable b lors de l'exécution, provoquant très probablement un punaise:

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

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

String a = "123"
int b = (int)a;
Danger
la source