L'intérêt du
typage statique
Jeroen Engels (Yeuroune)
L'intérêt du
typage statique avec
Jeroen Engels (Yeuroune)
Pourquoi ?
Langage fonctionnel pur
Garantit aucun crash
Pour applications web
C'est quoi le typage ?
Type = Ensemble de valeurs possibles
age : Int
age = 30
nom : String
nom = "Jeroen Engels"
Typage dynamique
Dynamique : Vérification au cours de l'exécution (JavaScript, Python, Clojure, ...)
# Python
>>> "string" + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
Typage statique
Statique : Vérifiés avant l'exécution
(Elm, Haskell, Java, C, ...)
Syntaxe Elm
Déclaration de fonctions
maFonction : TypeParametre1 -> TypeParametre2 -> TypeDeRetour
maFonction parametre1 parametre2 =
valeurDeLaFonction
Appel de fonctions
variable : Type
variable =
maFonction argument1 argument2
Définition de type
type alias Prenom = String
type alias Nom =
{ prenom : Prenom
, age : Int
}
type Sexe
= Homme
| Femme
| Autre String
Intérêts du typage statique
Trouver des erreurs tôt
quantite : Int
quantite = "100" -- NON!
Trouver des erreurs tôt
Maintenabilité
"Ça compile, donc ça marche"
Moins de tests
Seulement sur la logique métier
Documentation
Toujours à jour
prenom : String -- Garanti par le compilateur
prenom =
"Jeroen"
-- Si jamais on change
prenom : String
prenom =
1000 -- Erreur de compilation
Fournit une documentation minimale, même si le code est compliqué
a : (Nom -> Nom) -> User -> User
a b c =
d (b (e c)) c
Délimite les possibilités
addition : Int -> Int -> Int
nomUtilisateur : User -> String
modifiePrenom : Prenom -> User -> User
Créer des garanties
Créer nos propres types
Créer nos propres contraintes
=
Garantie
Contrainte
=
Contrainte : pas de null en Elm
Garantie : Toute valeur annoncée est vraiment présente et utilisable
=
(pas de NullPointerException)
Modélisation de données
type alias RequeteAuServeur data =
{ enCours : Bool
, enErreur : Bool
, données : Maybe data
}
maRequete : RequeteAuServeur String
maRequete =
{ enCours = True
, enErreur = True
, données = Just "Jeroen"
}
Custom types
type RequeteAuServeur data
= NonDemarree
| EnCours
| EnErreur
| EnSucces data
Making Impossible States Impossible
par Richard Feldman
"Ça ne résoud pas mes
problèmes de logique métier"
Problèmes de logique métier
Problèmes de types
type alias User =
{ nom : String
-- "admin" ou "user"
, role : String
}
peutSupprimerBaseDeDonnees : User -> Bool
peutSupprimerBaseDeDonnees user =
if user.role == "user" then
False
else
True
user : User
user =
{ nom = "Jeroen Engels"
, role = "User"
}
type alias User =
{ nom : String
, role : Role
}
type Role
= Admin
| User
peutSupprimerBaseDeDonnees : User -> Bool
peutSupprimerBaseDeDonnees user =
case user.role of
Admin -> True
User -> False
Mélanger des valeurs similaires
type alias User =
{ login : String
, motDePasse : String
}
modifieMotDePasse : String -> User -> User
modifieMotDePasse motDePasse user =
{ user | login = motDePasse }
Éviter "primitive obsession"
type alias User =
{ login : Login
, motDePasse : MotDePasse
}
type Login
= Login String
type MotDePasse
= MotDePasse String
modifieMotDePasse : MotDePasse -> User -> User
modifieMotDePasse motDePasse user =
{ user | login = motDePasse } -- Erreur
Valeurs de types primitifs
Garantir un mot de passe fort
type alias User =
{ motDePasse : MotDePasse
}
type MotDePasse
= MotDePasse String
modifieMotDePasse : MotDePasse -> User -> User
modifieMotDePasse motDePasse user =
{ user | motDePasse = motDePasse }
utilisateurAvecMotDePasse =
modifieMotDePasse (MotDePasse "a") utilisateur
module MotDePasse exposing
(MotDePasse, fromString, comparer)
-- Ne pas faire MotDePasse(..)
type MotDePasse
= MotDePasse String
{-| Si mdp est fort, alors retourne Just mdp, sinon Nothing -}
fromString : String -> Maybe MotDePasse
comparer : String -> MotDePasse -> Bool
Mot de passe fort avec des types opaques
Mot de passe fort avec des types opaques
import MotDePasse exposing (MotDePasse)
modifieMotDePasse : MotDePasse -> User -> User
modifieMotDePasse motDePasse user =
{ user | motDePasse = motDePasse }
utilisateurAvecMotDePasse =
case MotDePasse.fromString "a" of
Just mdp ->
modifieMotDePasse mdp utilisateur
Nothing ->
utilisateur
Types opaques
Permet aussi de limiter les
opérations permises sur un type
Exiger des données
-- Rendre Preuve opaque
type Preuve = Preuve
type Role
= Admin Preuve
| User
supprimerBaseDeDonnees : Preuve -> DemandeDeSuppression
etc...
Jeroen Engels (Yeuroune)
jfmengels sur le Slack Elm
https://slides.com/jeroenengels/typage-statique-esgi
https://guide.elm-lang.org/
Apprendre
Slides :
elm-radio.com
L'intérêt du typage statique - ESGI
By Jeroen Engels
L'intérêt du typage statique - ESGI
- 417