Cette affirmation d' Aleks Bromfield déclare:
Presque toutes les langues avec un système de type statique ont également un système de type dynamique. Mis à part C, je ne peux pas penser à une exception
Est-ce une réclamation valide? Je comprends qu'avec les classes Reflection ou Loading au moment de l'exécution, Java ressemble un peu à cela - mais cette idée de «typage progressif» peut-elle être étendue à un grand nombre de langues?
languages
dynamic-typing
static-typing
oeil de faucon
la source
la source
Réponses:
Tweeter original ici. :)
Tout d'abord, je suis quelque peu amusé / choqué que mon tweet soit pris si au sérieux! Si j'avais su que ça allait être aussi largement diffusé, j'aurais passé plus de 30 secondes à l'écrire!
Thiago Silva a raison de souligner que «statique» et «dynamique» décrivent plus précisément la vérification de type , plutôt que les systèmes de type . En fait, il n'est pas vraiment exact de dire qu'une langue est typée de manière statique ou dynamique. Au contraire, une langue a un système de types, et une implémentation de cette langue peut imposer le système de types à l'aide de la vérification statique, de la vérification dynamique, ou des deux, ou des deux (bien que ce ne soit pas une implémentation de langage très attrayante!).
En fait, il existe certains systèmes de types (ou caractéristiques de systèmes de types) qui se prêtent mieux à la vérification statique, et il existe certains systèmes de types (ou caractéristiques de systèmes de types) qui se prêtent mieux à la vérification dynamique. Par exemple, si votre langue vous permet de spécifier dans le texte d'un programme qu'une valeur particulière doit toujours être un tableau d'entiers, il est alors assez simple d'écrire un vérificateur statique pour vérifier cette propriété. Inversement, si votre langue a un sous-typage, et si elle autorise le downcasting, alors il est raisonnablement simple de vérifier la validité d'un downcast au moment de l'exécution, mais il est extrêmement difficile de le faire au moment de la compilation.
Ce que je voulais vraiment dire par mon tweet, c'est simplement que la grande majorité des implémentations de langage effectuent une certaine quantité de vérification de type dynamique. Ou, de manière équivalente, la grande majorité des langues ont des fonctionnalités qui sont difficiles (voire impossibles) à vérifier statiquement. Le downcasting en est un exemple. D'autres exemples incluent le débordement arithmétique, la vérification des limites du tableau et la vérification nulle. Certains d'entre eux peuvent être vérifiés statiquement dans certaines circonstances, mais dans l'ensemble, vous auriez du mal à trouver une implémentation de langage qui ne fait aucune vérification au moment de l'exécution.
Ce n'est pas une mauvaise chose. C'est juste une observation qu'il existe de nombreuses propriétés intéressantes que nous aimerions que nos langues appliquent, et que nous ne savons pas vraiment comment vérifier statiquement. Et c'est un rappel que les distinctions comme les "types statiques" par rapport aux "types dynamiques" ne sont pas aussi nettes que certains le voudraient. :)
Une dernière remarque: les termes «fort» et «faible» ne sont pas vraiment utilisés dans la communauté de recherche en langage de programmation, et ils n'ont pas vraiment de sens cohérent. En général, j'ai trouvé que lorsque quelqu'un dit qu'une langue a un "typage fort" et qu'une autre langue a un "typage faible", ils disent vraiment que leur langue préférée (celle avec "typage fort") les empêche de faire une erreur que l'autre langue (celle avec "typage faible") ne fait pas - ou inversement, que leur langue préférée (celle avec "typage faible") leur permet de faire quelque chose de cool que l'autre langue (le celui avec "typage fort") ne le fait pas.
la source
Hé bien oui. Vous pouvez avoir des sacs de propriété dans n'importe quelle langue tapée statiquement. La syntaxe sera terrible alors qu'en même temps vous gagnerez tous les inconvénients d'un système typé dynamiquement. Il n'y a donc pas vraiment d'avantage à moins que le compilateur ne vous permette d'utiliser une syntaxe plus agréable, comme le fait C #
dynamic
.Vous pouvez également le faire assez facilement en C aussi.
En réaction à d'autres réponses: je pense que les gens confondent le typage statique / dynamique avec le typage fort / faible. La frappe dynamique consiste à pouvoir modifier la structure des données lors de l'exécution et le code à utiliser des données qui correspondent exactement aux besoins du code. Cela s'appelle Duck Typing .
Mentionner la réflexion ne raconte pas toute l'histoire, car la réflexion ne vous permet pas de modifier la structure existante des données. Vous ne pouvez pas ajouter de nouveau champ à une classe ou une structure en C, C ++, Java ou C #. Dans les langages dynamiques, l'ajout de nouveaux champs ou attributs aux classes existantes est non seulement possible, mais en fait assez courant.
Par exemple, regardez Cython , le compilateur Python-to-C. Il crée du code C statique, mais le système de type conserve sa nature dynamique. C est un langage typé statiquement, mais il est capable de prendre en charge le typage dynamique à partir de Python.
la source
ExpandoObject
, bien que ce soit un processus opt-in, contrairement à JavaScript ou Ruby. Pourtant, vous avez fait une remarque très importante, qui est que la saisie de canard (ce que 99% des développeurs veulent réellement dire quand ils disent "typé dynamiquement") et la réflexion ne sont pas du tout les mêmes choses.True
pour dire "cet objet fou est une instance de la classe que je définis"). OCaml a cette fonctionnalité pour autant que je sache, mais je ne sais pas vraiment.Les langues dynamiques sont des langues statiques . Ce qui est communément appelé "typage dynamique" est vraiment un cas particulier de typage statique - le cas où vous vous êtes limité à n'avoir qu'un seul type. Comme une expérience de réflexion, imaginez écrire un programme en Java ou C # en utilisant uniquement des
Object
variables / champs / paramètres et en effectuant une conversion immédiatement avant d'appeler une méthode. Il serait plus précis d'appeler des langages tels que Python ou Javascript "unie". (Cette affirmation va probablement dérouter / déranger beaucoup de gens, étant donné qu'un tel programme Java ou C # utiliserait de nombreux sous-types, mais c'est parce que le langage OOP moyen confond les types et les classes. Lisez le billet de blog pour plus de détails.)Notez que même C a un typage "dynamique" - vous pouvez convertir n'importe quel pointeur en un pointeur
void
(et si la mémoire me sertchar
) et inversement. Et notez également qu'il n'y a pas de vérification d'exécution là-bas; si vous vous trompez, profitez de votre comportement indéfini!la source
String foo = (String) bar
cela ne signifie pas quebar
c'est en fait unString
. Vous ne pouvez le savoir qu'au moment de l'exécution, donc je ne vois pas comment le cast est fait "statiquement".dynamic
objet pour ce faire. Si vous essayez d'ajouter une propriété à unobject
... eh bien, vous ne pouvez pas.La différence entre le typage statique et dynamique est lorsque le type d'une valeur est vérifié: temps de compilation vs temps d'exécution. Dans les langages où les valeurs portent leur type avec eux (par exemple les objets Java), vous pouvez toujours recourir au typage dynamique même lorsque le langage préfère réellement le typage statique. Voici un exemple en Java, avec une méthode typée dynamiquement:
Remarquez comment le type de chaque élément est vérifié lors de l'exécution. La méthode équivalente typée statiquement est:
En C, les valeurs (et en particulier les pointeurs) ne conservent pas leur type lors de l'exécution - chaque pointeur est équivalent à a
void *
. Au lieu de cela, les variables et les expressions ont un type. Pour obtenir une frappe dynamique, vous devez transporter vous-même les informations de type (par exemple, en tant que champ dans une structure).la source
frobnicate
méthode ici sans le savoirSpecificType
.dynamic
mot - clé). Assimiler statique à la compilation et dynamique à l' exécution ne fait généralement qu'embrouiller les eaux.[1,2].Add([3,4])
céder[1,2,3,4]
,[1,2,[3,4]]
ou[4,6]
?Add
méthode sur le tableau qui accepte un tableau car une telle méthode serait ambiguë. Duck typing ne vous excuse pas d'écrire des types et des fonctions compréhensibles.Le typage statique ou dynamique fait essentiellement référence à la façon dont les types sont vérifiés. Le typage statique signifie que la vérification des types de diverses variables ou expressions est vérifiée sur la base du code réel (généralement par le compilateur) tandis que dans un système de type dynamique, cette vérification n'est effectuée qu'au moment de l'exécution, par l'environnement d'exécution.
Ce que je crois que le texte fait référence, c'est que même si les types sont effectivement vérifiés statiquement, ils sont également vérifiés au moment de l'exécution, c'est-à-dire dynamiquement. Vous avez correctement mentionné Java Reflection; la réflexion ne se produit qu'au moment de l'exécution et Java Runtime Environment (JVM) effectue en fait la vérification de type lorsque la réflexion est utilisée, ce qui signifie essentiellement une vérification de type dynamique.
la source
L'exception est fausse: C possède également un système de type dynamique important. Il ne le vérifie tout simplement pas ("C est fortement typé, faiblement vérifié"). Par exemple, le traitement d'une structure comme un
double
(reinternpret_cast
-style) produit un comportement non défini - une erreur de type dynamique.la source