Le code ment !

Romain Berthon

#JobHacker

@RomainTrm

romainberthon.blog

Le code

  • Exprime des intentions (Quoi / Pourquoi)
  • Définit la réalisation des traitements (Comment)

Il peut exister un décalage les intentions et leur réalisations

Récupérer un utilisateur


    public User GetUser(Guid id)
    // ...

Prend un identifiant et retourne l'utilisateur correspondant

Vraiment ?

  • Retournera toujours un utilisateur ?
  • Garantie 100% sans erreur ?
  • 2019 sera-t-elle une année riche en Human Talks ?

Le code est formel


    public User GetUser(Guid id)
    // ...

Prend un identifiant et retourne l'utilisateur correspondant

Après lecture du code source...


    public User GetUser(Guid id)
    // ...

    var user = GetUser(id);
    

    public User GetUser(Guid id)
    // ...

    var user = GetUser(id);
    
    if (user != null)
    {
        // ...
    }

on ne retourne pas toujours un utilisateur

Tony Hoare

Charles Antony Richard Hoare. Pendant les années 60, il invente le pointeur null alors qu'il écrivait le compilateur du langage Algol 60.

 

Pendant une conférence en 2009, il s'en excuse en ces termes : 

« Je l’appelle mon erreur à un milliard de dollars. En 1965, je concevais le premier système de typage complet pour un langage orienté objet et je n'ai pas pu résister à ajouter la référence nulle, simplement parce que c'était si facile à implémenter. Ceci a conduit à un nombre incalculable d'erreurs, … qui ont probablement causé des dommages d'un milliard de dollars dans les quarante dernières années. »

Le null, c'est nul

    
    > string s = null;
    > var result = s is string;
    > result
    
    > string s = null;
    > var result = s is string;
    > result
    false
  • Pas explicite dans la signature
  • Code défensif (sans toujours gérer les cas d'erreur)
  • Comportements parfois inattendus

Une signature plus honnête


    public Maybe<User> GetUser(Guid id)
    // ...

    var maybeUser = GetUser(id);
    

    type Maybe<'T> = 
    | Just of 'T
    | Nothing

Une signature plus honnête


    public Maybe<User> GetUser(Guid id)
    // ...

    var maybeUser = GetUser(id);
    
    maybeUser.Match(
        nothing: () => /*Do something*/,
        just: user => /*Do something else*/);

Tips pour les utilisateurs de C#


    Maybe<int> maybeX = //...
    Maybe<int> maybeY = //...

    // Select
    Maybe<int> result =
        from x in maybeX
        select x * 2;

    // SelectMany
    Maybe<int> result = 
        from x in maybeX
        from y in maybeY
        select x * y;

Maybe / Option

  • Signature de fonction
  • Structure de données
  • Alternative (moins explicite) : empty pattern
  • Méthodes fluent
  • Computation expression

Après lecture du code source...


    public User GetUser(Guid id)
    // ...

    try
    {
        var user = GetUser(id);
        // ...
    }
    catch (Exception ex)
    {
        // ...
    }
    

on peut recevoir une erreur


    public User GetUser(Guid id)
    // ...

    var user = GetUser(id);
    // ...
    
    

La solution proposée par Java


    public User getUser(Guid id) throws Exception {
        // ...
    }

Une signature plus honnête


    public Either<User, Error> GetUser(Guid id)
    // ...

    var result = GetUser(id);
    

    type Either<'TLeft, 'TRight> = 
    | Left of 'TLeft
    | Right of 'TRight

Une signature plus honnête


    public Either<User, Error> GetUser(Guid id)
    // ...

    var result = GetUser(id);

    result.Match(
        left: user => /*Do something*/,
        right: error => /*Do something else*/);

Vous connaissez déjà


    List<int> ids = //...
    List<string> resut = ids
        .Where(id => id > 0)
        .Select(id => $"Id: {id}")
        .ToArray();

    Task<int> task = //...
    Task<string> result = 
        task.ContinueWith(t => $"Id: {t.Result}");

Quelques librairies

Language-Ext

SuccincT

 

Vavr

Functional Java

Merci !

Romain Berthon

#JobHacker

@RomainTrm

romainberthon.blog

Le code ment

By Romain Berthon

Le code ment

  • 220