web-dev-qa-db-fra.com

Exiger une déclaration de type dans Julia

Existe-t-il un moyen d'exiger explicitement dans Julia (par exemple, dire dans un module ou un package) que typesdoitêtre déclaré? Est-ce que par exemple PackageCompiler ou Lint.jl avez-vous un support pour ces contrôles? Plus largement, la distribution standard Julia elle-même fournit-elle analyseur de code statique ou équivalent qui pourrait aider à vérifier cette exigence?

Par exemple, disons que nous voulons nous assurer que notre croissance base de code de production accepte uniquement le code qui est toujours type déclaré, sous l'hypothèse que les grandes bases de code avec des déclarations de type ont tendance à être plus maintenables.

Si nous voulons appliquer cette condition, Julia dans sa distribution standard fournit-elle des mécanismes pour exiger la déclaration de type ou aider à faire avancer cet objectif? (par exemple, tout ce qui pourrait être vérifié via des linters, des hooks de validation ou l'équivalent?)

16

La réponse courte est: non, il n'y a actuellement aucun outil pour vérifier le type de votre code Julia. C'est en principe possible, cependant, et un certain travail a été fait dans ce sens dans le passé, mais il n'y a pas de bonne façon de le faire pour le moment.

La réponse la plus longue est que les "annotations de type" sont un hareng rouge ici, ce que vous voulez vraiment, c'est la vérification de type, donc la partie la plus large de votre question est en fait la bonne question. Je peux parler un peu de la raison pour laquelle les annotations de type sont un hareng rouge, d'autres choses qui ne sont pas la bonne solution et à quoi ressemblerait le bon type de solution.

Exiger des annotations de type n'atteint probablement pas ce que vous voulez: on pourrait simplement mettre ::Any sur n'importe quel champ, argument ou expression et il aurait une annotation de type, mais pas une annotation qui vous ou le compilateur vous dirait quelque chose d'utile sur le type réel de cette chose. Il ajoute beaucoup de bruit visuel sans ajouter réellement d'informations.

Qu'en est-il d'exiger des annotations de type concret? Cela exclut simplement de mettre ::Any sur tout (ce que Julia fait implicitement de toute façon). Cependant, il existe de nombreuses utilisations parfaitement valides des types abstraits que cela rendrait illégaux. Par exemple, la définition de la fonction identity est

identity(x) = x

Quelle annotation de type concret mettriez-vous sur x dans le cadre de cette exigence? La définition s'applique à tout x, quel que soit le type — c'est en quelque sorte le point de la fonction. La seule annotation de type correcte est x::Any. Ce n'est pas une anomalie: il existe de nombreuses définitions de fonctions qui nécessitent des types abstraits pour être correctes, donc les forcer à utiliser des types concrets serait assez limitant en termes de type de code Julia que l'on peut écrire.

Il y a une notion de "stabilité de type" dont on parle souvent dans Julia. Le terme semble provenir de la communauté Julia, mais a été repris par d'autres communautés linguistiques dynamiques, comme R. C'est un peu délicat à définir, mais cela signifie en gros que si vous connaissez les types concrets des arguments d'une méthode, vous connaissez également le type de sa valeur de retour. Même si une méthode est de type stable, cela ne suffit pas à garantir qu'elle taperait la vérification car la stabilité de type ne parle pas de règles pour décider si quelque chose vérifie ou non. Mais cela va dans la bonne direction: vous souhaitez pouvoir vérifier que chaque définition de méthode est de type stable.

Beaucoup ne veulent pas exiger la stabilité du type, même si cela est possible. Depuis Julia 1.0, il est devenu courant d'utiliser de petits syndicats. Cela a commencé avec la refonte du protocole d'itération, qui utilise désormais nothing pour indiquer que l'itération est effectuée par rapport au renvoi d'un (value, state) Tuple lorsqu'il y a plus de valeurs à itérer. Le find* les fonctions de la bibliothèque standard utilisent également une valeur de retour de nothing pour indiquer qu'aucune valeur n'a été trouvée. Ce sont des instabilités de type technique, mais elles sont intentionnelles et le compilateur est assez bon pour les raisonner en optimisant autour de l'instabilité. Donc, au moins les petits syndicats doivent probablement être autorisés dans le code. De plus, il n'y a pas de place claire pour tracer la ligne. Bien que l'on puisse peut-être dire qu'un type de retour de Union{Nothing, T} est acceptable, mais rien de plus imprévisible que cela.

Cependant, ce que vous voulez vraiment, plutôt que d'exiger des annotations de type ou la stabilité de type, c'est d'avoir un outil qui vérifiera que votre code ne peut pas générer d'erreurs de méthode, ou peut-être plus largement qu'il ne générera aucune sorte d'erreur inattendue. Le compilateur peut souvent déterminer avec précision quelle méthode sera appelée sur chaque site d'appel, ou au moins la restreindre à quelques méthodes. C'est ainsi qu'il génère du code rapide - la répartition dynamique complète est très lente (beaucoup plus lente que vtables en C++, par exemple). Si vous avez écrit du code incorrect, en revanche, le compilateur peut émettre une erreur inconditionnelle: le compilateur sait que vous avez fait une erreur mais ne vous le dit qu'au moment de l'exécution car ce sont les sémantiques du langage. On pourrait exiger que le compilateur puisse déterminer quelles méthodes peuvent être appelées sur chaque site d'appel: cela garantirait que le code sera rapide et qu'il n'y a pas d'erreurs de méthode. C'est ce qu'un bon outil de vérification de type pour Julia devrait faire. Il y a une bonne base pour ce genre de chose puisque le compilateur fait déjà une grande partie de ce travail dans le cadre du processus de génération de code.

9
StefanKarpinski