Le XXIème sera typé ou ne sera pas

ou Comment j’ai appris à aimer les types

Arnaud Bailly - @dr_c0d3

2018-04-12

Plan

  • Introduction
  • Voyage au pays des types
  • Travaux pratiques
  • Conclusion

Introduction

Motivation

  • Discussions sur le canal #beginners dans le slack elm-lang: Beaucoup du questions sur le type de List a
  • Making Impossible States Impossible
  • Lien entre types et formalisation de domaines métiers

Objectif

  • Faire découvrir la richesse des systèmes de types des langages fonctionnels
  • Donner envie d’aller y voir de plus près
  • Comprendre comment utiliser ces systèmes pour des programmes “normaux”

Voyage au pays des types

Elm

Fonctions pures

Fonctions pures

  • Des fonctions sans effets de bord
  • De préférences totales…
  • De première classe dans le langage…
  • Qui sont interprétées par le runtime qui encapsule l’ensemble des effets

Fonctions pures

init : ( Model, Cmd Msg )

update : Msg -> Model -> ( Model, Cmd Msg )

view : Model -> H.Html Msg

Types de données algébriques

Types de données algébriques

  • Décrit les données comme engendrées par une structure algébrique
  • Types construits par composition au moyen d’opérateurs union et produit
  • Un type est une fonction dans le domaine des types, un constructeur de types
  • Permet au compilateur de “garantir” la totalité d’une fonction

Types de données algébriques

type Msg
    = SubmitResponse (Maybe String)
    | UpdateResponse String
    | NoOp

Types de données algébriques récursifs

data Nat = S Nat | Z

Haskell

Classes de types

Classes de types

  • Interface offerte par un type de données
  • Permet d’encapsuler l’implémentation concrète
  • Peut exprimer des relations complexes entre plusieurs types de données

Classes de types

class (Eq (Answer q)) => Questionable q where
  question :: q -> Text
  expected :: q -> Answer q
  response :: q -> Maybe (Answer q)
  answered :: q -> Maybe (Answer q) -> q

  isCorrectAnswer :: q -> Bool
  isCorrectAnswer q = Just (expected q) == response q

Familles de types

Familles de types

  • Relation entre types
  • Rend le domaine d’une fonction dépendant du codomaine
  • Peut être ouvert (relation extensible) ou fermé (le codomaine est fini)

type family Answer q = a | a -> q where
  Answer QCM          = Int
  Answer Grade        = Double
  Answer OpenQuestion = Text

Types existentiels

Types existentiels

  • Encapsuler un ensemble de types dans un autre type de données
  • Renforce la distinction entre type abstrait et concret en rendant l’implémentation inaccessible
  • Garantit la localité des opérations sur un type: la variable de type est nécessairement locale

Types existentiels

data Question where
  Question :: (Questionable q)
           => q
           -> (Text -> Maybe (Answer q))
           -> Question

Idris

Types algébriques de données généralisés

Types algébriques de données généralisés

  • Applicable aux types paramétrés
  • Chaque constructeur d’un type peut retourner une type différent
  • Permet de spécialiser le paramètre en fonction du contexte dans lequel le type est appelé à s’insérer

Types algébriques de données généralisés

data Command : Type -> Type where
  Prompt         : Question -> Command Input
  AnswerQuestion : String -> Command Bool
  Back           : Command ()
  Quit           : Command ()

Hole-Driven Development

Hole-Driven Development

  • Utiliser l’inférence de type pour compléter le code par la structure attendue par le compilateur
  • Permet de s’assurer dés le départ qu’une fonction est totale
  • Permet à l’éditeur de compléter automatiquement le code

Hole-Driven Development

runQuizz : Quizz n -> IO ()
runQuizz quizz@(MkQuizz answered current next) = do
  (input, quizz') <- runCommand quizz (Prompt current)
  case input of
     GoBack         => ?hole_1
     QuitGame       => ?hole_2
     (GiveAnswer x) => ?hole_3
     Garbage        => ?hole_4

Types dépendants

Types dépendants

  • Faire tomber la barrière entre les types et les valeurs
  • Un type peut être définit par une fonction dépendant de la valeur d’un paramètre
  • Introduit une hiérarchie potentiellement infinie de types (quel est le type de Type ?)
  • Le vérificateur de types utilise la même sémantique que le runtime

Types dépendants

data Quizz : (numQuestions : Nat) -> Type where
  MkQuizz :  (answered : Vect n Answered) ->
             (current  : Question) ->
             (next : Vect m Question) ->
             Quizz (n + m)

Paires dépendantes

Paires dépendantes

  • Empaqueter une valeur et un type dépendant de cette valeur dans une paire
  • Généralisation des types existentiels
  • Permet de conserver de l’information pour le compilateur

Paires dépendantes

data Answered : Type where
  MkAnswered : (question ** Answer question) -> Answered

Type égalité

Type égalité

  • Exprimer l’égalité entre deux types dans le système de types
  • Le type devient une assertion logique, une proposition qui doit être vérifiée par l’implémentation
  • La seule valeur qui habite ce type est Refl qui est donc une preuve que l’égalité est vérifiée

Type égalité

plusOneCommutes :  (n : Nat)
                -> (m : Nat)
                -> (n + S m = S n + m)

Types = Proposition

Types = Proposition

  • Mise en oeuvre concrète de Curry-Howard
  • Les types sont des propositions, les programmes des preuves
  • Écrire un programme c’est démontrer que les types sont habités, que l’on peut effectivement construire des valeurs des types donnés
  • De la conception de logiciels considérée comme l’énonciation de théorèmes…

Travaux Pratiques

Conclusion

  • Le système de type est un outil essentiel dans la conception du logiciel
  • Les systèmes de types fonctionnels sont de plus en plus sophistiqués et permettent de modéliser des contraintes de plus en plus proches du métier
  • Le XXIème sera typé !

Colophon

(Quelques) Références

(Quelques) Références

Credits

Credits

Feedback

Questionnaire