web-dev-qa-db-fra.com

Julia est-elle typée dynamiquement?

Beaucoup de blogs, et le manuel lui-même , disent que Julia est typé dynamiquement . Mais d'après ma lecture du manuel, il me semble plus que c'est typé statiquement avec inférence de type , comme F # .

  • Julia est-elle tapée statiquement avec l'inférence de type?
  • Est-il typé dynamiquement?
  • Je suppose qu'il est typé dynamiquement, il semble peu probable que le manuel soit incorrect.
  • L'inférence de type est-elle impliquée dans Julia?
65
Lyndon White

La réponse de Tim Holy est tout à fait correcte, mais je vais développer un peu. Définissons d'abord quelques termes - vous pouvez être en désaccord avec mes définitions, mais au moins vous saurez ce que je dis. À mon avis, la principale différence entre les langages statiques et dynamiques est la suivante: dans les langages statiques, les expressions ont des types; dans les langages dynamiques, les valeurs ont des types.

Dans un langage statique, il existe des règles pour déterminer le type de chaque expression dans un programme. Les types d'expressions dictent le comportement du programme. Un programme qui n'admet pas un type cohérent à déterminer pour chaque expression est considéré comme incorrect et ne sera pas compilé. En présence de polymorphisme, le type d'une expression peut ne pas être un seul type concret: le polymorphisme paramétrique peut être pensé comme un moyen de laisser le même code décrire toute une famille d'algorithmes concrètement typés, indexés par les paramètres des types; Le polymorphisme de sous-type peut être considéré comme introduisant une quantité limitée de comportement dynamique dans un langage par ailleurs statique.

Les langages dynamiques, en revanche, n'ont pas de règles pour affecter des types aux expressions: les types sont impliqués par la façon dont les données circulent dans le programme lors de son exécution. En général, les expressions peuvent potentiellement produire des valeurs de tout type. Pour cette raison, les théoriciens des types décrivent parfois les langages dynamiques comme "à unité" - c'est-à-dire du point de vue statique, où un "type" est intrinsèquement la propriété d'une expression, toutes les expressions dans un langage dynamique ont le type Any. Bien sûr, cela applique la notion statique de type - qui n'a de sens que pour les expressions - à un langage où la notion de type n'a de sens que pour les valeurs.

Julia est carrément dans le camp dynamique: les types sont une propriété de valeurs et non d'expressions. Le type de code de résultat est déterminé par la façon dont les valeurs le traversent lors de son exécution; le langage n'inclut aucune règle pour affecter des types aux expressions avant de les exécuter. Contrairement à de nombreux langages dynamiques, cependant, Julia dispose d'un langage assez sophistiqué pour parler de types, et vous pouvez annoter des expressions avec des types. Par exemple, x::T est une affirmation que x est une valeur de type T; si c'est vrai, x::T correspond à la valeur de x, sinon une erreur est déclenchée et l'expression ne renvoie aucune valeur. Les annotations de type dans les signatures de méthode ont une signification légèrement différente: au lieu d'affirmer le type d'une valeur existante, elles indiquent que la méthode ne s'applique que si l'argument correspondant est du type indiqué. Dans les deux cas, le code suivant peut supposer en toute sécurité que la valeur de x est de type T.

[Mis à part: dans certaines langues avec une saisie "progressive" ou "facultative", les annotations de type font passer la langue du mode dynamique au mode statique: les méthodes sans annotations de type sont dynamiques; les méthodes avec des annotations de type sont statiques. Dans le code statique, il existe des règles pour attribuer des types à toutes les expressions et le code doit les satisfaire. Ce n'est pas ainsi que Julia fonctionne - le code avec des annotations de type est toujours dynamique et a la même sémantique que le code sans annotations de type.]

L'inférence de type dans des langages comme F #, OCaml ou Haskell fait partie de la façon dont les types d'expressions sont déterminés. Si le compilateur ne peut pas déduire le type d'une expression, votre programme est interrompu et ne compilera pas. Ces langages utilisent tous une forme d'inférence de type Hindley-Milner, ce qui est un moyen très intelligent de dériver les types d'expressions de la structure du code sans avoir à écrire des types explicites (comparez cela aux langages dynamiques où les types sont impliqués par exécution du code). La plupart du temps, aucune annotation de type n'est requise, ce qui est assez agréable par rapport aux déclarations de type verbeuses qui peuvent être nécessaires dans des langages comme C++, C # et Java. Ceci est cependant très différent des langages dynamiques comme Julia et Python où aucune annotation de type n'est requise simplement parce qu'il est parfaitement acceptable que les expressions n'aient pas un type prédéterminé. Dans les langues Hindley-Milner, il se peut que vous n'ayez pas à écrire autant de types qu'en C++ ou Java, mais chaque expression a un type prédéterminé que le compilateur peut calculer.

Le compilateur de Julia fait l'inférence de type, mais c'est très différent: il n'est pas nécessaire que chaque expression ait un type inférable. Le compilateur analyse le code pour essayer de prédire les types d'expressions et utilise ces informations pour générer un code machine plus efficace. Mais s'il ne peut pas déterminer le type d'une expression, ce n'est pas grave: le compilateur émet simplement du code générique qui fonctionnera de toute façon, en utilisant des informations de type au moment de l'exécution. Pour l'essentiel dans Julia, l'inférence de type n'est qu'une optimisation - votre code fonctionnera de la même manière avec ou sans lui - mais avec une inférence de type réussie, elle s'exécutera beaucoup plus rapidement.

99
StefanKarpinski

Les deux sont vrais. Julia est typée dynamiquement, mais dans un code Julia bien écrit, les types peuvent généralement être déduits. Vous obtenez souvent une amélioration majeure des performances lorsque cela est possible.

Il y a une discussion à ce sujet dans la FAQ .

27
tholy

Il est typé dynamiquement, mais si vous spécifiez un type comme variable :: type, vous pouvez penser que cette variable est typée statiquement (et cela améliorera les performances dans les cas où le compilateur ne pourrait pas déduire automatiquement le type)

2
Chris Rackauckas

Voici un extrait du livre Getting Started with Julia Programming Language :

Il peut également être utile d'indiquer les types d'arguments pour restreindre le type de paramètres transmis lors de l'appel. Notre en-tête de fonction pour les nombres à virgule flottante ressemblerait alors à la fonction mult (x :: Float64, y :: Float64). Lorsque nous appelons cette fonction avec mult (5, 6), nous recevons une erreur, ERREUR: 'mult' n'a pas de méthode correspondant à mult (:: Int64, :: Int64), prouvant que Julia est en effet un langage fortement typé. Il n'accepte pas les paramètres entiers pour les arguments à virgule flottante.

Voici l'exemple de fonction dans le livre:

function mult(x::Float64, y::Float64)
  x * y
end
mult(5, 6) # raises an error
mult(5.0, 6.0) # => 30.0

Je ne sais pas si le livre est bon, mais il contredit toutes les autres réponses.

0
Powers