Inférence de type pour les déclarations impératives autres que l'affectation


10

Dans ma recherche d'articles de recherche sur les systèmes de types pour les langages impératifs, je ne trouve que des solutions pour un langage avec des références mutables mais sans véritables structures de contrôle impératif telles que des opérateurs composés, des boucles ou des conditionnelles.

Il n'est donc pas clair comment un langage impératif avec inférence de type partielle tel que http://rust-lang.org peut être implémenté.

Les articles ne mentionnent pas les types paramétrés tels que List of aparce que les types paramétrés sont une extension triviale du système de type Hindley-Milner - seul l'algorithme d'unification doit être étendu, et le reste de l'inférence fonctionne tel quel. Cependant, les affectations ne peuvent pas être ajoutées de manière triviale car des paradoxes surviennent, donc des techniques spéciales telles que la restriction de la valeur ML doivent être appliquées.

Pouvez-vous recommander des articles ou des livres décrivant un système de types pour une langue avec des boucles impératives, des conditions, des entrées-sorties et des instructions composées?


4
Je ne suis pas sûr de comprendre la source de votre question, en partie parce que Standard ML a en fait des opérateurs composés, des boucles et des conditions (un exemple de ligne:) let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end. Donc, au niveau d'une question de recherche, la réponse que vous recherchez est-elle «d'appliquer des techniques développées en Caml / SML, y compris la restriction de valeur»?
Rob Simmons

La question était "quels articles sur les techniques développées pour Caml / SML recommandez-vous?"
nponeccop

Ok - je l'avais compris, et j'étais sur le point d'essayer de modifier ma dernière phrase pour dire "Est-ce que vous cherchez une référence accessible pour l'inférence de type Hindley-Milner telle qu'elle est utilisée en ML?" Et puis j'ai atteint la limite de montage de 5 minutes :-)
Rob Simmons

Réponses:


14

Si vous recherchez une référence fonctionnelle et soignée à l'inférence de type, je suis un peu partial à Gundry, McBride et McKinna 2010 " Type Inference in Context ", bien que cela ne soit pas un bon guide pour les implémentations existantes réelles .

Je pense qu'une partie de la réponse est que, au-delà de la restriction de valeur, il n'y a vraiment pas beaucoup de difficulté à adapter l'inférence de type Hindley-Milner aux langues impératives: si vous définissez e1; e2comme sucre syntaxique pour (fn _ => e2) e1et définissez while e1 do e2comme sucre syntaxique pour whiledo e1 (fn () => e2), où whiledoest un régulier fonction récursive

fun whiledo g f = if g then (f (); whiledo g f) else ();

alors tout fonctionnera bien, y compris l' inférence de type.

Quant à la restriction de valeur étant une technique spéciale, j'aime l'histoire suivante; Je suis presque sûr de l'avoir récupéré auprès de Karl Crary. Considérez le code suivant, dont la restriction de valeur vous empêchera d'écrire en ML:

let
   val x: 'a option ref = ref NONE
in
   (x := SOME 5; x := SOME "Hello")  
end

Comparez-le au code suivant, ce qui ne pose aucun problème:

let
   val x: unit -> 'a option ref = fn () => ref NONE
in
   (x () := SOME 5; x () := SOME "Hello")  
end

Nous savons ce que fait le deuxième exemple: il crée deux nouvelles cellules ref contenant NONE, puis met SOME 5dans le premier (an int option ref), puis met SOME "Hello"dans le second (a string option ref).

Mais réfléchissez au premier exemple en termes de représentation xdans le système F (le lambda-calcul polymorphe). Dans un tel paramètre, xserait une valeur de type " ", ce qui signifie que, comme terme, la valeur de doit être un (type) lambda: "α.ref(option(α))xΛα.ref[α](NONE) ".

Cela suggérerait qu'un «bon» comportement du premier exemple consiste à se comporter exactement de la même manière que le deuxième exemple - instancier le lambda de niveau type à deux moments différents. La première fois que nous instancions xavec int, ce qui entraînera x [int]d'évaluer une tenue de cellule de référence NONEpuis SOME 5. La deuxième fois, nous instancions xavec string, ce qui sera le cas x [string]pour évaluer une cellule de référence ( différente! ) NONEEt ensuite SOME "Hello". Ce comportement est "correct" (type-safe), mais ce n'est certainement pas ce à quoi un programmeur s'attendrait, et c'est pourquoi nous avons la restriction de valeur en ML, pour éviter aux programmeurs de gérer ce type de comportement inattendu.


1
Votre version désugarée de e1; e2contient une parenthèse non appariée et un point-virgule (qu'elle est censée définir). Vous vouliez dire (fn _ => e2) e1?
Tsuyoshi Ito

Right-o, Tsuyoshi: fixe.
Rob Simmons

Votre dernier paragraphe dit essentiellement: la sémantique (opérationnelle) et le système de type ne correspondent pas, il faut être corrigé, et nous choisissons de corriger ce dernier.
Radu GRIGore

Radu: bien sûr, je suis d'accord avec ce résumé.
Rob Simmons

3

La thèse de Xavier Leroy est un bon début.


1
La thèse ne couvre pas les boucles impératives, les conditions, les entrées-sorties et les instructions composées, n'est-ce pas? La raison principale de ma question était que je n'ai pas pu trouver de papiers couvrant ces sujets. Les articles sur les tâches de frappe sont abondants.
nponeccop

0

Je suis désolé d'avoir répondu à ma propre question, mais la référence en question est

Une proposition de norme ML , Milner, 1983

La partie 6 "Formes dérivées standard" couvre assez largement le désuchage des constructions impératives. Et jusqu'à présent, c'est la première référence de ces transformations largement évidentes que j'ai pu trouver.

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.