web-dev-qa-db-fra.com

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

Aussi, l'un implique-t-il l'autre?

392
JDelage

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

Un langage à typage statique possède un système de types 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 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 pas contourner les restrictions imposées par le système de types. . Ce terme est presque toujours utilisé pour décrire des langages statiquement typés.

Statique vs dynamique

Le contraire de typé statiquement est "dynamiquement", 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 manière 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 à typage dynamique, possède un type de chaîne, un type de nombre et un type booléen, entre autres. En Lua, chaque valeur appartient à exactement un type, mais ce n'est pas obligatoire pour tous les langages à typage dynamique. En Lua, il est permis de concaténer deux chaînes, mais il est interdit 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é car tout type de pointeur est convertible en un autre type de pointeur simplement par transtypage. Pascal était destiné à être fortement typé, mais un oubli dans la conception (enregistrements de variantes non étiquetés) a introduit une faille dans le système de types, donc techniquement, il est faiblement typé. CLU, Standard ML et Haskell sont des exemples de langages très fortement typés. La ML standard a en fait fait l’objet de plusieurs révisions visant à éliminer les failles du système de typage découvertes après un déploiement généralisé de la langue.

Qu'est-ce qui se passe vraiment ici?

Dans l’ensemble, il n’est pas utile de parler de "fort" et de "faible". Qu'un système de types comporte une échappatoire importe moins que le nombre et la nature exacts de ces échappatoires, leur probabilité de se concrétiser dans la pratique et les conséquences de l'exploitation d'une échappatoire. En pratique, il vaut mieux éviter les termes "fort" et "faible" , car

  • Les amateurs les confondent souvent avec "statique" et "dynamique".

  • Apparemment, certaines personnes utilisent le "typage faible" pour parler de la prévalence relative ou de l'absence de conversions implicites.

  • Les professionnels ne peuvent s'accorder sur la signification exacte des termes.

  • Globalement, il est peu probable que vous informiez ou éclairiez votre public.

La triste vérité est qu’en ce qui concerne les systèmes de typage, "fort" et "faible" n’ont pas de sens technique convenu de manière universelle. Si vous veulent discuter de la force relative des systèmes de types, il est préférable de discuter exactement quelles garanties sont fournies et non fournies. Par exemple, une bonne question à poser est la suivante: "chaque valeur d'un type (ou classe) donné est-elle garantie d'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 le C++, je ne suis pas sûr - j'aimerais 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. La saisie dynamique signifie que les types de valeurs sont vérifiés pendant l'exécution , et une opération mal typée peut provoquer l'arrêt du programme ou signaler une erreur lors 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".

L'un implique-t-il l'autre?

Au niveau pédant, non, car le mot "fort" ne veut rien dire. Mais dans la pratique, les gens font presque toujours l’une des deux choses suivantes:

  • Ils utilisent (incorrectement) "fort" et "faible" pour signifier "statique" et "dynamique", auquel cas ils utilisent (incorrectement) indifféremment "fortement typé" et "statiquement typé".

  • Ils utilisent "fort" et "faible" pour comparer les propriétés des systèmes de type statique. Il est très rare d’entendre 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 type peut être subverti. En quelque sorte, par définition, ces contrôles sont intégrés dans le moteur d’exécution et chaque opération est vérifiée avant d’être exécutée.

Quoi qu’il en soit, si une personne appelle une langue "fortement typée", elle parlera très probablement d’une langue à typage statique.

483
Norman Ramsey

Ceci est souvent mal compris alors laissez-moi éclaircir.

Dactylographie Statique/Dynamique

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

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

Donc dans Java par exemple:

String s = "abcd";

s sera "pour toujours" un String. Au cours de sa vie, il peut indiquer différentes Strings (puisque s est une référence en Java). Il peut avoir une valeur null mais il ne fera jamais référence à un Integer ou à un List. C'est 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 la frappe dynamique.

Dactylographie forte/faible

(Modifier l'alerte!)

Stronginging 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 types fort qui n'autorise pas le code client à créer une valeur de type abstrait sauf en utilisant les constructeurs fournis par le type. C a un système de types un peu fort, mais il peut être "subverti" dans une certaine mesure, car 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 renvoyée par malloc() et la jetter gaiement sur FILE*, et le compilateur n'essaiera pas de vous arrêter - ou même de vous avertir que vous faites quelque chose de louche .

(La réponse originale disait quelque chose à propos d'une valeur "ne changeant pas de type au moment de l'exécution". J'ai connu de nombreux concepteurs de langage et rédacteurs de compilateur, et aucun ne parlait de valeurs changeant de type au moment de l'exécution, à l'exception peut-être de recherches très avancées en matière de type. systèmes, où cela est connu comme le "problème de mise à jour forte".)

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

L'original de cette réponse combinait typage faible avec 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 converti implicitement en chaîne avant d'être concaténé avec "abc". On peut faire valoir que le compilateur Java réécrit ce code comme suit:

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

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

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

L'erreur ici est que strpos() renvoie l'index de la correspondance, étant 0. 0 est forcé dans booléen 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 parce que dans Ruby l'objet 123 est pas converti implicitement simplement parce qu'il est passé à une méthode +. Dans Ruby, le programmeur doit expliciter la conversion:

val = "abc" + 123.to_s

La comparaison de PHP et de Ruby en est une bonne illustration. Les deux sont des langages à typage dynamique, mais PHP comporte de nombreuses conversions implicites, contrairement à Ruby (peut-être même si vous ne le connaissez pas bien).

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, il n’ya pas de réel consensus sur ce que l’on entend exactement par fort et faible. Pour cette raison, le typage fort/faible est beaucoup plus grisâtre que noir ou blanc.

Donc, pour répondre à votre question: une autre façon de regarder ceci qui est généralement est correcte est de dire que le typage statique est un type de sécurité à la compilation et le typage puissant est à l'exécution tapez sécurité.

La raison en est que les variables dans un langage à typage statique 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 au moment de l'exécution et il est difficile pour le programmeur de subvertir le système de types sans vérification dynamique.

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

230
cletus

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

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

fortement typé signifie qu'un fichier ne sera pas automatiquement converti d'un type à un autre. L'inverse est faiblement typé: Perl peut utiliser une chaîne telle que "123" dans un contexte numérique, en la convertissant automatiquement en int 123. Un langage fortement typé comme python ne le fera pas.

Statiquement typé signifie que le compilateur détermine le type de chaque variable au moment de la compilation. Les langages à typage dynamique ne comprennent que les types de variables au moment de l'exécution.

15
Daren Thomas

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

12
Svetlozar Angelov

La coercition de données ne signifie pas nécessairement faiblement typée car parfois son sucre syntaxique:

L'exemple ci-dessus de Java étant faiblement typé à cause de

String s = "abc" + 123;

N’est pas un exemple faiblement typé car c’est vraiment en train de faire:

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

La coercition de données n'est pas non plus faiblement typée si vous construisez un nouvel objet. Java est un très mauvais exemple de typage faible (et tout langage ayant une bonne réflexion ne sera probablement pas typé faiblement). Parce que le runtime de la langue sait toujours quel est le type (l'exception peut être des types natifs).

Ceci est différent de C. C est l’un des meilleurs exemples de faiblement typés. Le moteur d'exécution n'a aucune idée si 4 octets est un entier, une structure, un pointeur ou 4 caractères.

Le temps d’exécution du langage définit vraiment si son type est faiblement typé, sinon c’est vraiment une opinion juste.

EDIT: Après mûre réflexion, cela n’est pas forcément vrai, car le moteur d’exécution n’a pas besoin de faire réifier tous les types dans le système d’exécution pour devenir un système fortement typé. Haskell et ML ont une analyse statique si complète qu’ils peuvent utiliser des informations de type ommit à partir du moteur d’exécution .

11
Adam Gent

Le 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 des expressions. Par exemple, si A est un entier et B un float, la règle stricte concernant A + B peut être que A est converti en float et le résultat renvoyé sous la forme d'un float. Si A est un entier et B 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 affecté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'elles apparaissent fréquemment ensemble. 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 dans les réponses jusqu'à présent.

8

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

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

6
Joe Cannatti

La réponse est déjà donnée ci-dessus. Essayer de différencier le concept fort vs semaine du concept statique vs dynamique.

Qu'est-ce que Strongly typed VS Faible typed?

fortement typé: ne sera pas automatiquement converti d'un type à un autre

Dans Go ou Python, comme les langages fortement typés, "2" + 8 générera une erreur de type, car ils ne permettent pas la "coercition de type".

faiblement (faiblement) typé: sera automatiquement converti d'un type à l'autre: Les langages faiblement typés tels que JavaScript ou Perl ne renverront pas d'erreur et dans ce cas, javascript sera considéré comme '28' et Perl dix.

Exemple Perl:

my $a = "2" + 8;
print $a,"\n";

Enregistrez-le sur main.pl et lancez Perl main.pl et vous obtiendrez le résultat 10.

Quel est le type statique VS Dyamic?

En programmation, progammer définit le typage statique et le typage dynamique en fonction du point de contrôle des types de variable. Les langages à typage statique sont ceux dans lesquels la vérification de type est effectuée lors de la compilation, tandis que les langages à typage dynamique sont ceux dans lesquels la vérification de type est effectuée à l'exécution.

  • Statique: types vérifiés avant l'exécution
  • Dynamique: types vérifiés à la volée, en cours d'exécution

Qu'est-ce que cela signifie?

Dans Go, il vérifie la saisie avant l’exécution (vérification statique). Cela signifie non seulement qu’il traduit et vérifie le code qu’il exécute, mais qu’il scanne l’ensemble du code et que l’erreur de type est renvoyée avant même que le code ne soit exécuté. Par exemple,

package main

import "fmt"

func foo(a int) {
    if (a > 0) {
        fmt.Println("I am feeling lucky (maybe).")
    } else {
        fmt.Println("2" + 8)
    }
}

func main() {
    foo(2)
}

Enregistrez ce fichier dans main.go et lancez-le, vous obtiendrez un message d'échec de la compilation à cet effet.

go run main.go
# command-line-arguments
./main.go:9:25: cannot convert "2" (type untyped string) to type int
./main.go:9:25: invalid operation: "2" + 8 (mismatched types string and int)

Mais ce cas n'est pas valable pour Python. Par exemple, le bloc de code suivant sera exécuté pour le premier appel foo (2) et échouera pour le deuxième appel foo (0). C’est parce que Python est typé de manière dynamique, il ne traduit que le code de vérification de type sur lequel il est exécuté. Le bloc else ne s'exécute jamais pour foo (2), donc "2" + 8 n'est même jamais regardé et pour l'appel de foo (0), il tentera d'exécuter ce bloc et échouera.

def foo(a):
    if a > 0:
        print 'I am feeling lucky.'
    else:
        print "2" + 8
foo(2)
foo(0)

Vous verrez la sortie suivante

python main.py
I am feeling lucky.
Traceback (most recent call last):
  File "pyth.py", line 7, in <module>
    foo(0)
  File "pyth.py", line 5, in foo
    print "2" + 8
TypeError: cannot concatenate 'str' and 'int' objects
0
Balkrishna