2010-10-28 37 views
50

Certains prétendent que le système de type Scala est complet à Turing. Mes questions sont:Le système de types de Scala est complet à Turing. Preuve? Exemple? Avantages?

  1. Y at-il une preuve formelle pour cela? A quoi ressemblerait un calcul simple dans le système de type Scala?

  2. Est-ce un avantage pour Scala - la langue? Cela rend-il Scala plus "puissant" d'une certaine manière comparé aux langages sans un système de type complet de Turing?

Je suppose que cela s'applique aux langages et systèmes de types en général.

+4

Je préférerais avoir un système de type non universel et un compilateur rapide à la place. – ziggystar

+0

@ziggystar ce que vous gagneriez en vitesse de compilation vous perdriez probablement en dev et en temps de débogage. – BAR

Répondre

35

Il existe un billet de blog quelque part avec une implémentation de niveau-type du calculateur SKI combinator, qui est connu pour être Turing-complet.

Les systèmes de type Turing-complet présentent essentiellement les mêmes avantages et inconvénients que les langages complets de Turing: vous pouvez tout faire, mais vous pouvez prouver très peu. En particulier, vous ne pouvez pas prouver que vous finirez par faire quelque chose. Un exemple de calcul au niveau du type est le nouveau transformateur de collection préservant le type dans Scala 2.8. Dans Scala 2.8, des méthodes comme map, filter et ainsi de suite sont garantis pour retourner une collection du même type à laquelle ils ont été appelés. Donc, si vous filter un Set[Int], vous obtenez un Set[Int] et si vous map un List[String] vous obtenez un List[Whatever the return type of the anonymous function is]. Maintenant, comme vous pouvez le voir, map peut réellement transformer le type d'élément. Alors, que se passe-t-il si le nouveau type d'élément ne peut pas être représenté avec le type de collection d'origine? Exemple: un BitSet ne peut contenir que des entiers à largeur fixe. Alors, que se passe-t-il si vous avez un BitSet[Short] et que vous mappez chaque nombre à sa représentation sous forme de chaîne?

someBitSet map { _.toString() } 

Le résultat serait un BitSet[String], mais c'est impossible. Ainsi, Scala choisit le supertype le plus dérivé de BitSet, qui peut contenir un String, qui dans ce cas est un Set[String].

Tout ce calcul se passe pendant la compilation , ou plus précisément lors de la vérification de type temps, en utilisant des fonctions de niveau de type. Ainsi, il est statiquement garanti d'être de type sécurisé, même si les types sont réellement calculés et donc pas connus au moment du design.

+14

J'imagine que c'est l'article que vous recherchez? http://michid.wordpress.com/2010/01/29/scala-type-level-encoding-of-the-ski-calculus/. Scala semblait être une langue nette quand je l'ai regardé pour la première fois; cette superclasse-inférence est une fonctionnalité * vraiment * cool. –

+6

Excellente réponse, bien que l'exemple des collections soit un peu court. Alors que le vérificateur de type fait certainement des heuristiques intéressantes pour obtenir le meilleur type de collection résultante au moment de la compilation, ce n'est pas un bon exemple de calcul au niveau du type puisque le système type * lui-même ne fait aucun travail. Malheureusement (ou peut-être, heureusement), il n'y a pas beaucoup d'exemples de code du monde réel qui font de la programmation au niveau du type, simplement parce que c'est tellement difficile, maladroit et impossible à maintenir. –

+0

Merci Jörg pour le bon exemple et Daniel pour la clarification. Maintenant, j'ai peur de demander si le vérificateur de type Turing Complete ... – Adrian

33

Mon blog post sur l'encodage du calcul SKI dans le système de type Scala montre l'exhaustivité de Turing.

Pour certains calculs simples de niveau de type, il existe également des exemples de codage des nombres naturels et d'addition/multiplication.

Enfin, il y a un excellent series of articles sur la programmation au niveau du type sur le blog d'Apocalisp.

+0

michid, qui semble impressionnant. Je promets de mieux regarder quand je serai grand ... Ce n'est peut-être pas une preuve FORMELLE, mais ça peut appartenir à cette liste? http://en.wikipedia.org/wiki/Computer-assisted_proof#List_of_theorems_proved_with_the_help_of_computer_programs – Adrian

+2

@Adrian, la seule preuve officielle connue de complétude complète est la capacité à implémenter autre chose qui est en train de se terminer. Typiquement, cela signifie une machine à polymériser universelle mais la théorie est valable même si vous utilisez quelque chose d'autre qui est connu pour être complet comme le calcul de SKI ou Perl ou Javascript. Par conséquent, je dirais que c'est une preuve formelle. – slebetman

+2

Il convient également de noter que rien de concrètement réalisable n'est vraiment complet car il est impossible d'avoir une mémoire infinie. Même si vous utilisez toute la matière dans l'univers pour construire votre CPU/interprète, cela ne serait pas vraiment terminé. Ce que nous appelons pratiquement achever, c'est vraiment la réalité - complète - dans les limites de la mémoire disponible. – slebetman