Quel fragment de la théorie des types dépendants de Martin-Löf peut être exprimé en utilisant des types génériques en Java?


8

Je suis venu récemment pour se rendre compte que d' un certain nombre de problèmes , j'ai eu il y a quelques années à essayer de mettre en œuvre diverses théories mathématiques en Java est venu au fait que le système de frappe en Java est pas suffisamment forte pour modéliser l' ensemble de la théorie de type dépendant Martin-Löf .

Avant Java 5 et génériques, la seule théorie du type que vous pouvez faire est à travers des cours et des interfaces, qui vous donnent des types arbitraires construits sur les types de sol int, double, charet ainsi sur l' utilisation de types de produits et de fonction. Vous pouvez également créer des types récursifs tels que Lists, mais pas de manière uniforme.

En utilisant des génériques, vous pouvez faire un peu plus. Vous pouvez maintenant définir List<T>comme une fonction et nous obtenons donc des types d'ordre supérieur.

TypeType

Ce n'est pas la fin de l'histoire, cependant. En utilisant une astuce générique, nous pouvons modéliser certains types de produits dépendants. Par exemple, nous pouvons définir des types de la forme utilisant la syntaxe

T:Typef(T)
public interface f<T extends f<T>>
{
  // We can now refer to T as much as we like
  // inside the class.  T has type f<T>.
}

À titre d'exemple, nous pouvons modéliser la structure sous-jacente de base d'un monoïde (mais pas les conditions d'associativité et d'unité) en utilisant un terme de type ( c'est-à-dire un ensemble avec un élément unité désigné et une opération binaire sur ). En utilisant des génériques Java, nous pouvons modéliser ce type:

T:TypeT×(TTT)
TT
public interface MonoidElement<T extends MonoidElement<T>>
{
  public T unit();

  public T mul(T op1, T op2);
}

Cependant, lorsque nous essayons de modéliser des concepts plus compliqués, la théorie des types tombe en panne.

Existe-t-il une description simple du fragment de MLTT correspondant aux types pouvant être construits dans le système de typage Java?

Réponses:


12

Il y a beaucoup d'idées fausses ici. Pour commencer, MLTT n'a pas de sous-types, donc Java ne sera pas simplement un fragment de celui-ci. Il ne nécessite pas de types dépendants pour créer l'un des types que vous avez donnés. Un système de type dépendant n'a pas besoin d'avoir un "type" de types (un univers) en général (MLTT a cependant des univers), pas plus que vous n'avez besoin de types dépendants pour exprimer ces types. Dans un système comme le calcul lambda polymorphe / Système F , vous pouvez dire . Java n'a pas d'équivalent à Type. Un type dépendant sans analogue comme type polymorphe serait quelque chose comme par exemple ouT.T×(TTT)n:NatMatrix(n,n+1)b:BooljeF b then Nunet else Bool .

Il est plus logique de considérer Java comme un fragment de SystemF<: qui n'est pas du tout un système de type dépendant. Même alors, il en est un fragment plutôt faible. Il existe une variante du système F appelée System Fωqui prend en charge les fonctions de niveau complet, essentiellement lambda au niveau type (à ne pas confondre avec type-lambdas qui relient les niveaux de valeur et de type et que System F a déjà). Ni Java ni Haskell ne peuvent le faire. Les seules "fonctions" de niveau type que Haskell ou Java peuvent créer sont des compositions de fonctions non interprétées. Il n'y a pas de comportement de calcul au niveau du type. Java est encore plus restreint car il n'a pas (ni n'a besoin) d'un système de type car il manque des types de type supérieur. Autrement dit, vous ne pouvez pas avoir une "fonction" de niveau type avec "type" (c'est-à-dire kind) par exemple. C'est pourquoi vous ne pouvez pas créer de méthodes qui fonctionnent sur des monades arbitraires en Java. En revenant uniquement au système F, le système F a des types de rang arbitraires.(TypeType)Type aussi profondément que vous le souhaitez - vous pouvez l'utiliser librement. Ni Java ni Haskell (sans extensions) ne le supportent. Je crois que les deux peuvent capturer indirectement certains types de rang supérieur, mais aucun ne peut exprimer le type de qui nécessite des extensions et est .runSTune.(s.ST s une)une

Java est donc plus expressif que les types de rang 1 tels que capturés par le système de type Hindley-Milner, mais beaucoup moins expressif que System . Il ne prend en charge aucune forme de frappe dépendante. Featherweight Java tel qu'introduit dans Featherweight Java: A Minimal Core Calculus for Java and GJ par Igarashi, Pierce et Wadler fournit un calcul simplifié et idéalisé spécifiquement adapté à Java. Il existe presque certainement un article qui compare / réduit directement le poids plume de Java à System . Le résultat est que le système de type Java n'est même pas à distance proche de la puissance de MLTT. En termes de cube lambda , en ignorant le sous-typage, Java serait quelque part à la frontière entreF<:F<:λ, le lambda calcul simplement tapé, et , System F. MLTT (ou spécifiquement le Calcul des Constructions) est , le coin opposé de . Donc, pour décrire Java en termes de MLTT, il faudrait d'abord ignorer tout ce qui rend MLTT différent de System F , puis ignorer presque tout ce qui rend System F différent de System F.λ2λPωλωω


Je ne sais pas quelles sont les idées fausses, mais merci - cela a à peu près répondu à ma question.
John Gowers
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.