type-safety - programmation - static java wiki



Quelle est la différence entre un langage fortement typé et un langage typé statiquement? (6)

Aussi, implique-t-on l'autre?


Quelle est la différence entre un langage fortement typé et un langage typé statiquement?

Un langage typé statiquement a un système de type qui est vérifié au moment de la compilation par l'implémentation (un compilateur ou un interpréteur). La vérification de type rejette certains programmes, et les programmes qui réussissent la vérification ont généralement des garanties; par exemple, le compilateur garantit de ne pas utiliser d'instructions arithmétiques entières sur les nombres à virgule flottante.

Il n'y a pas vraiment d'accord sur ce que signifie "fortement typé", bien que la définition la plus largement utilisée dans la littérature professionnelle soit que dans un langage "fortement typé", le programmeur ne puisse contourner les restrictions imposées par le système de types . Ce terme est presque toujours utilisé pour décrire les langues typées statiquement.

Statique vs dynamique

Le contraire de statiquement typé est "dynamiquement typé", ce qui signifie que

  1. Les valeurs utilisées au moment de l'exécution sont classées en types.
  2. Il existe des restrictions sur la façon dont ces valeurs peuvent être utilisées.
  3. Lorsque ces restrictions sont violées, la violation est signalée comme une erreur de type (dynamique).

Par exemple, Lua , un langage dynamiquement typé, a un type de chaîne, un type de nombre, et un type booléen, entre autres. Dans Lua, chaque valeur appartient à exactement un type, mais ce n'est pas une exigence pour tous les langages typés dynamiquement. Dans Lua, il est permis de concaténer deux chaînes, mais il n'est pas permis de concaténer une chaîne et un booléen.

Fort vs faible

Le contraire de "fortement typé" est "faiblement typé", ce qui signifie que vous pouvez contourner le système de types. C est notoirement faiblement typé parce que n'importe quel type de pointeur est convertible en n'importe quel autre type de pointeur simplement par moulage. Pascal était destiné à être fortement typé, mais un oubli dans la conception (enregistrements de variantes non marqués) a introduit une faille dans le système de types, donc techniquement il est faiblement typé. Des exemples de langues vraiment fortement typées comprennent CLU, Standard ML et Haskell. Le ML standard a en fait subi plusieurs révisions pour supprimer les failles dans le système de types qui ont été découvertes après que le langage ait été largement déployé.

Qu'est-ce qui se passe vraiment ici?

Dans l'ensemble, il s'avère peu utile de parler de «fort» et de «faible». La question de savoir si un système de type a une échappatoire est moins importante que le nombre exact et la nature des failles, la probabilité qu'elles se manifestent dans la pratique et quelles sont les conséquences de l'exploitation d'une faille. En pratique, il vaut mieux éviter complètement les termes "fort" et "faible" , car

  • Les amateurs les confondent souvent avec «statique» et «dynamique».

  • Apparemment, le «typage faible» est utilisé par certaines personnes pour parler de la prévalence relative ou de l'absence de conversions implicites.

  • Les professionnels ne peuvent pas s'entendre exactement sur ce que les termes signifient.

  • Dans l'ensemble, vous avez peu de chances d'informer ou d'éclairer votre auditoire.

La triste vérité est que lorsqu'il s'agit de systèmes de type, «fort» et «faible» n'ont pas de signification technique universellement acceptée. Si vous voulez discuter de la force relative des systèmes de type, il est préférable de discuter exactement quelles garanties sont fournies ou non. Par exemple, une bonne question à poser est la suivante: "est-ce que chaque valeur d'un type donné (ou classe) est garantie avoir été créée en appelant l'un des constructeurs de ce type?" En C, la réponse est non. Dans CLU, F #, et Haskell c'est oui. Pour C ++ je ne suis pas sûr, je voudrais savoir.

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 de démarrer. 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 provoquer l'arrêt du programme ou signaler une erreur au moment de l'exécution. Une des principales raisons de la saisie statique est d'exclure les programmes susceptibles d'avoir de telles "erreurs de type dynamique".

Est-ce que l'un implique l'autre?

Sur un plan pédant, non, car le mot "fort" ne veut rien dire. Mais en pratique, les gens font presque toujours l'une des deux choses suivantes:

  • Ils (incorrectement) utilisent "fort" et "faible" pour signifier "statique" et "dynamique", auquel cas ils (incorrectement) utilisent "fortement typé" et "statiquement typé" de façon interchangeable.

  • Ils utilisent "fort" et "faible" pour comparer les propriétés des systèmes de type statique. Il est très rare d'entendre quelqu'un parler d'un système de type dynamique «fort» ou «faible». À l'exception de FORTH, qui n'a pas vraiment de système de type, je ne peux pas penser à un langage typé dynamiquement où le système de types peut être subverti. Un tri par définition, ces contrôles sont bulit dans le moteur d'exécution, et chaque opération est vérifiée pour la santé mentale avant d'être exécutée.

Quoi qu'il en soit, si une personne appelle une langue «fortement typée», cette personne parle très probablement d'une langue statiquement typée.


Ceci est souvent mal compris, alors permettez-moi de le clarifier.

Typage statique / dynamique

Le typage statique est l'endroit où le type est lié à la variable . Les types sont vérifiés lors de la compilation.

Le typage dynamique est l'endroit où le type est lié à la valeur . Les types sont vérifiés lors de l'exécution.

Donc en Java par exemple:

String s = "abcd";

s sera "pour toujours" une String . Au cours de sa vie, il peut pointer vers des String différentes (puisque s est une référence en Java). Il peut avoir une valeur null mais il ne se référera jamais à un Integer ou à une List . C'est un typage statique.

En PHP:

$s = "abcd";          // $s is a string
$s = 123;             // $s is now an integer
$s = array(1, 2, 3);  // $s is now an array
$s = new DOMDocument; // $s is an instance of the DOMDocument class

C'est un typage dynamique.

Forte / faible typage

(Modifier l'alerte!)

Le typage fort est une phrase sans signification largement acceptée. La plupart des programmeurs qui utilisent ce terme pour désigner autre chose que le typage statique l'utilisent pour indiquer qu'il existe une discipline de type imposée par le compilateur. Par exemple, CLU a un système de type fort qui ne permet pas au code client de créer une valeur de type abstrait, sauf en utilisant les constructeurs fournis par le type. C a un système de type assez fort, mais il peut être "subverti" à un degré parce qu'un programme peut toujours convertir une valeur d'un type de pointeur en une valeur d'un autre type de pointeur. Ainsi, par exemple, en C, vous pouvez prendre une valeur retournée par malloc() et la lancer joyeusement en FILE* , et le compilateur n'essaiera pas de vous arrêter - ou même vous avertira que vous faites quelque chose de louche.

(La réponse originale dit quelque chose à propos d'une valeur "ne changeant pas de type au moment de l'exécution." J'ai connu beaucoup de concepteurs de langages et de compilateurs et je n'en connais pas encore. systèmes, où cela est connu comme le "problème de mise à jour forte".)

Un typage faible implique que le compilateur n'applique pas de ligne de frappe, ou peut-être que l'application peut facilement être subvertie.

L'original de cette réponse confondait le typage faible avec la conversion implicite (parfois aussi appelée «promotion implicite»). Par exemple, en Java:

String s = "abc" + 123; // "abc123";

Ce code est un exemple de promotion implicite: 123 est implicitement converti en chaîne avant d'être concaténé avec "abc" . On peut soutenir que le compilateur Java réécrit ce code comme:

String s = "abc" + new Integer(123).toString();

Considérons un problème classique "commence par" PHP:

if (strpos('abcdef', 'abc') == false) {
  // not found
}

L'erreur ici est que strpos() retourne l'index de la correspondance, étant 0. 0 est forcé dans boolean false et donc la condition est réellement vraie. La solution consiste à utiliser === au lieu de == pour éviter la conversion implicite.

Cet exemple illustre comment une combinaison de conversion implicite et de typage dynamique peut induire les programmeurs en erreur.

Comparez cela à Ruby:

val = "abc" + 123

ce qui est une erreur d'exécution car dans Ruby l' objet 123 n'est pas implicitement converti simplement parce qu'il est passé à une méthode + . Dans Ruby, le programmeur doit rendre la conversion explicite:

val = "abc" + 123.to_s

Comparer PHP et Ruby est une bonne illustration ici. Les deux sont des langages dynamiquement typés mais PHP a beaucoup de conversions implicites et Ruby (peut-être étonnamment si vous n'êtes pas familier avec lui) ne le fait pas.

Statique / Dynamique vs Fort / Faible

Le point ici est que l'axe statique / dynamique est indépendant de l'axe fort / faible. Les gens les confondent probablement en partie parce que le typage fort vs faible est non seulement moins clairement défini, mais il n'y a pas vraiment de consensus sur ce que l'on entend par fort et faible. Pour cette raison, typage fort / faible est beaucoup plus d'une nuance de gris plutôt que noir ou blanc.

Donc, pour répondre à votre question: une autre façon de voir ce qui est le plus correct est de dire que le typage statique est la sécurité de type compilation et que le typage fort est la sécurité du type d'exécution.

La raison en est que les variables dans une langue statiquement typée ont un type qui doit être déclaré et peut être vérifié au moment de la compilation. Un langage fortement typé a des valeurs qui ont un type lors de l'exécution, et il est difficile pour le programmeur de subvertir le système de type sans vérification dynamique.

Mais il est important de comprendre qu'un langage peut être statique / fort, statique / faible, dynamique / fort ou dynamique / faible.


Fortement typé signifie qu'il existe des restrictions entre les conversions entre types. Le type typé signifie que les types ne sont pas dynamiques - vous ne pouvez pas changer le type d'une variable une fois qu'elle a été créée.


L'un n'implique pas l'autre. Pour qu'une langue soit typée statiquement, cela signifie que les types de toutes les variables sont connus ou déduits au moment de la compilation.

Un langage fortement typé ne vous permet pas d'utiliser un type comme un autre. C est un langage faiblement typé et est un bon exemple de ce que les langues fortement typées ne permettent pas. En C, vous pouvez passer un élément de données du mauvais type et il ne se plaindra pas. Dans les langues fortement typées, vous ne pouvez pas.


Les deux sont des pôles sur deux axes différents:

  • fortement typé vs faiblement typé
  • typé statiquement contre typé dynamiquement

Moyens fortement typés , un ne sera pas automatiquement converti d'un type à un autre. Faiblement typé est le contraire: Perl peut utiliser une chaîne comme "123" dans un contexte numérique, en le convertissant automatiquement en int 123 . Un langage fortement typé comme python ne le fera pas.

Les moyens typés statiquement , le compilateur détermine le type de chaque variable au moment de la compilation. Les langues typées dynamiquement ne déterminent que les types de variables à l'exécution.


Une typage fort signifie probablement que les variables ont un type bien défini et qu'il existe des règles strictes concernant 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 stricte à propos de A + B peut être que A est transtypée en un flottant et le résultat renvoyé comme un flottant. Si A est un entier et B est une chaîne, la règle stricte peut être que A + B n'est pas valide.

Le typage statique signifie probablement que les types sont assignés au moment de la compilation (ou son équivalent pour les langages non compilés) et ne peuvent pas changer pendant l'exécution du programme.

Notez que ces classifications ne sont pas mutuellement exclusives, en effet je m'attendrais à ce qu'ils se produisent ensemble fréquemment. De nombreux langages fortement typés sont également typés 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 à partir des réponses jusqu'à présent.