Archives de l’auteur : Raphaël Lemaire

Litterate programming 2017

J’ai récemment lu l’article de Donald Knuth sur la programmation lettrée. C’est un de ces paradigmes un peu oubliés, avec pourtant un potentiel très cool.

C’est quoi la programmation lettrée ?

L’idée original de Donald Knuth est d’écrire un programme sous la forme d’un essai en langage naturel, expliquant ce que le programme fait, avec entre les lignes des morceaux de code exécutable.

Le programme est écrit sous la forme d’un essai en langage naturel, avec du code exécutable entre les lignes.

Il est ainsi possible de générer à partir du même fichier une documentation en langue naturelle (par exemple sous la forme d’un fichier latex, html, etc…) et un programme exécutable par une machine.

Vous me direz « c’est javadoc » : Eh bien non !

Les outils de génération auxquels nous sommes habitués permettent de générer une documentation à partir de texte annoté sur la structure du programme. C’est toujours le langage machine qui donne la contrainte de où est placé le texte. On documente une classe ou une fonction.

Avec la programmation lettrée, le texte est au premier plan, et c’est lui qui impose la structure du programme, pas le langage machine.

Avec la programmation lettrée, le texte est au premier plan.

Personnellement je trouve l’idée assez cool. Pour plein de raisons.

Déjà, on ne raconte pas assez nos vies, ou plutôt la vie du projet dans nos programmes. Il est rare que les gens placent le contexte, le pourquoi fonctionnel, politique, historique de tel ou tel morceau de code. Et souvent on se pose des questions longtemps après, même si le code est clair sur ce qu’il fait, sur pourquoi ça a été fait.

Ensuite, écrire du texte en français (ou en anglais, c’est un autre débat) permet de structurer sa pensée. On peut penser à des choses que l’on aurait oublié (pour moi qui suit un intuitif et un éternel distrait c’est intéressant), mieux comprendre un concept, une fonctionnalité, et donc mieux l’implémenter, etc…

Et aussi, j’aime assez tout ce qui s’écarte de l’habituel et permet de voir la programmation autrement. Avouons que le changement est rafraîchissant.

Comme ce paradigme est un peu oublié, il y a peu d’outils à disposition pour en faire, et pas vraiment d’envie de le voir arriver dans les projets (contrairement à la programmation fonctionnelle, qui a le vent en poupe).

Je me suis demandé ce que cela donnerait si on essayait d’appliquer cette idée dans un langage mainstream actuel. Voici un exemple en Java, tiré d’un programme réel, et un peu retravaillé :

Le code complet :

/**
* Interroge le service infos pour récupérer les informations, et les stocke
* dans redis.
* On ne garde que les infos en cours de validité.
*/

public F.Promise<List<GLZoneInfo>> poll() {
   // En avril 2016, la direction des renards a demandé à intégrer les
   // informations aviaires à l'application, afin de [...].
   // On commence par récupérer la liste des contenus auprès du service infos.
   return infosClient.getContentList().flatMap((contentList) -> {
       // On a alors une liste d'objets qui contiennent les ids et date
       // de validité des contenus existants.
       List<F.Promise<GLZoneInfo>> promises = contentList.stream()
               // On ne conserve que les publications en cours de validité.
               .filter(InfosService::mustBeDisplayedNow)
               // pour chacun des contenus non filtrés, on va chercher le
               // détail (avec le titre, le texte, etc...) en appelant
               // le service infos avec l'identifiant donné dans la liste,
               // et on traduit le résultat dans notre modèle.
               .map((content) -> infosClient
                   .getContent(content.getContentId())
                   .map(InfosService::convert))
               .collect(Collectors.toList());

       // Note : on va chercher les détails en parrallèle, pour plus d'efficacité.
       return F.Promise.sequence(promises).map((informations) -> {
           // Une fois les contenus récupérés, on les stocke dans redis
           storeInCache(informations);
           // Par commodité, on renvoie les contenus stockés, ce qui permet
           // pour un poll fait à la main de voir ce qui a été stocké.
           return informations;
       });
   });
}

On voit qu’il y a beaucoup de commentaires, qui peuvent parfois paraître un peu redondant avec le code en dessous, mais pas non plus complètement inutiles.

Si on enlève les commentaires qui ne sont pas de la documentation de méthode ça donne :

/**
* Interroge le service infos pour récupérer les informations, et les stocke
* dans redis.
* On ne garde que les infos en cours de validité.
*/

public F.Promise<List<GLZoneInfo>> poll() {
   return infosClient.getContentList().flatMap((contentList) -> {
       List<F.Promise<GLZoneInfo>> promises = contentList.stream()
               .filter(InfosService::mustBeDisplayedNow)
               .map((content) -> infosClient
                   .getContent(content.getContentId())
                   .map(InfosService::convert))
               .collect(Collectors.toList());
       return F.Promise.sequence(promises).map((informations) -> {
           storeInCache(informations);
           return informations;
       });
   });
}

C’est le genre de chose qu’on est habitué à voir tous les jours. C’est assez lisible, si on est familier avec la syntaxe du langage et les API du framework play!.

Si on garde seulement les commentaires d’explication inséré au milieu du code ça donne :

En avril 2016, la direction des renards a demandé à intégrer les informations aviaires à l’application, afin de […].
On commence par récupérer la liste des contenus auprès du service infos.
On a alors une liste d’objets qui contiennent les ids et date de validité des contenus existants. On ne conserve que les publications en cours de validité.
Pour chacun des contenus non filtrés, on va chercher le détail (avec le titre, le texte, etc…) en appelant le service infos avec l’identifiant donné dans la liste, et on traduit le résultat dans notre modèle.
Note : on va chercher les détails en parrallèle, pour plus d’efficacité.
Une fois les contenus récupérés, on les stocke dans redis.
Par commodité, on renvoie les contenus stockés, ce qui permet pour un poll fait à la main de voir ce qui a été stocké.

On le voit ce petit texte ne ressemble pas du tout à une description de méthode, et il explique très bien ce que fait le petit bout de programme et pourquoi.

On a donc un essai qui décrit le programme.

Les avantages de cette démarche :

  • Le programme produit est plein d’explications, et donc plus documenté et plus clair.
  • Ecrire le texte permet de penser plus longtemps le programme et aussi un peu différemment, on pense donc à plus de choses, et cela permet d’éviter des oublis, des cas particuliers, etc…
  • Les commentaires ajoutés permettent de donner du contexte, d’expliciter des choses et de justifier des choix techniques, même micros.

Les inconvénients :

  • C’est assez verbeux et un peu redondant.

Une opinion tranchée sur les formats de rétro.

Voici une opinion bien tranchée sur les rétrospectives, que je donne après en avoir suivi et animé des dizaines dans différents contextes, et après avoir échangé des collègues qui sont du même avis.

Garder le même format à chaque sprint

Garder le même format à chaque sprint permet aux participants de se concentrer sur le fond (les points d’amélioration) et non sur la forme. Les membres de l’équipes ont leurs repères, visualisent comment amener les points qu’ils ont repérés pendant le sprint, voire même revoient la rétrospective précédente et ses actions.

Changer de format à chaque sprint crée une habitude de l’imprévisibilité, chaque rétro est une découverte, sans repères pour les participants. On perd du temps en discussion sur la forme, les participants ne savent où et comment remonter leurs idées, etc…

Briser la routine de temps à autre avec un format différent est intéressant, mais cela doit être exceptionnel, par exemple tous les quatre ou cinq sprints. L’effet positif de la nouveauté ne peut être ressenti que s’il y a une routine à briser.

Rester sur les classiques

Je préfère les formats simples et classiques (type KALM, ou 4L, qui d’ailleurs se ressemblent beaucoup). Ils sont faciles à comprendre, permettent aux participants de remonter toute sorte de choses (problèmes, suggestions, améliorations, blagues…) et peuvent être adaptés en direct en ajoutant des votes, des étapes, ou en timeboxant si besoin.

D’ailleurs, un autre inconvénient du changement de format régulier est que l’on tombe parfois sur des formats qui ne permettent pas tous les types de retours, ou pas facilement, ou qui peuvent paraitre infantilisants (voir par exemple la montgolfière ou les petits cochons) (mais peut-être que c’est moi qui suis ennuyeux ?).

Historisation

Toutes les rétrospectives devraient être sauvegardées (dans le wiki de l’équipe ou outil équivalent), et on devrait commencer chaque séance en projetant la rétrospective précédente pour vérifier que les actions ont bien été menées, que l’équipe a progressé.

Le rappel permet également de renforcer le sentiment de continuité : on progresse de semaine en semaine, on se souvient d’où on en était avant, et en quoi c’était moins bien.

En résumé, un animateur de cérémonies doit mettre en place une routine de l’amélioration continue, ce qui passe par de la stabilité, de la simplicité et du suivi. Il peut amener de l’air en changeant parfois les choses, mais cela ne peut être intéressant que s’il y a une routine à briser.

Ma gestion des tâches

Au fil des ans, je me suis construit une façon de m’organiser et de gérer mes tâches, à partir de plusieurs sources. Je suis pour le moment satisfait du résultat, au point de l’avoir partagé avec quelques personnes de mon entourage. J’ai même fait un google doc pour ma soeur, détaillant mon process.

Je reprends ici ce document, en enlevant les privates jokes et en reformulant un peu.

TLDR; Ma gestion des tâches est globalement une implémentation de GTD, matinée de Kanban, de préférence paperless, avec l’outil Trello.

Trello

Trello est un outil gratuit (avec une version payante) qui permet de gérer des listes et des cartes. On peut l’utiliser à plusieurs, faire des checklists, des votes, …

C’est vraiment pratique, dessus, j’ai mes todo lists, mais aussi ma liste de films à regarder, de musique à creuser, etc…

L’avantage d’un outil de ce type par rapport à des listes papier, c’est que l’on peut facilement déplacer les éléments dans une liste ou entre les listes, chose que l’on ne peut pas faire sur un cahier. On peut aussi faire cela avec des post-its, mais cela impose un tableau physique assez grand.

Un autre avantage c’est qu’un tableau électronique est dématérialisé, donc disponible partout, sur tous les appareils : laptop, smartphone, etc… Ce qui n’est pas possible avec un tableau physique à base de post-its.

Mind like water

GTD, pour « Getting things done », c’est la méthode de David Allen, qui est décrite dans le bouquin éponyme, qui a été traduit en français sous le titre pourri « s’organiser pour réussir »

J’ai lu le bouquin il y a longtemps, et depuis j’utilise une variante de ce système tous les jours.

Un système pour les gouverner tous.

L’idée de getting things done est que le manque d’organisation est une source de stress et de perte de productivité. Les gens oublient des tâches, s’inquiètent pour des choses qui sont encore lointaines, etc…

David Allen préconise de mettre en place un système dans lequel toutes les tâches, absolument toutes, sont stockées. Le but est de se sortir ces tâches de l’esprit. Si on ne stocke pas les tâches à l’extérieur de l’esprit, elles reviennent inopinément : « Ah il faut que je fasse truc pour machin », « ah il ne faut pas que j’oublie.. », causant distraction (de la tâche présente ou d’un moment agréable qui n’a rien à voir), et stress.

La promesse de GTD : une fois tous les petits trucs bouclant dans l’esprit sortis, on est Zen. L’esprit est comme un lac, calme, plat, … (il utilise vraiment cette image).

Moi ça me fait penser à la pensine de Dumbledore, où il sort les pensées anxiogènes pour les mettre dans un bassin en aluminium.

Flux vs calendrier

Beaucoup de gens bloquent du temps pour une tâche dans leur calendrier. Genre « Lundi de 14h à 16h je m’occupe de Xx ».

Cela ne fonctionne pas tout le temps, parce qu’on a souvent des imprévus qui changent les priorités, par exemple un pré-requis manquant, un client qui a besoin de quelque chose en urgence, etc… Du coup il faut refaire tout le calendrier.

GTD préconise d’avoir une liste de trucs à faire (Next actions), avec toutes tes tâches, organisées par priorité, que l’on vide quand on a le temps de travailler.

On a donc plus des plages de temps bloquées pour des tâches, on a une pile de tâches que l’on dépile. On a un flux de travail, de TODO à DONE, et plus un planning.

GTD utilise le calendrier, mais seulement pour des choses qui sont forcément, par définition, fixées dans le temps, typiquement un rendez vous ou une conférence.

Je ne peux m’empêcher de comparer ce passage du calendrier à la liste de tâches, à la transition entre un planning avec des estimations et périodes fixées, et un backlog priorisé avec la gestion des flux et de la prédictibilité, que l’on a en kanban par exemple. D’ailleurs GTD s’allie très bien à Kanban.

Inbox zéro et process GTD



Définition : une inbox est une source de trucs (stuff). Typiquement la boîte mail, les notes qu’on prend en pensant à quelque chose dans le métro, etc…

Il faut minimiser les inbox, moins on en a, plus il est facile de dépiler.

Régulièrement on vide les inbox, selon un processus donné par par le flowchart GTD :

  • S’il n’y a rien à faire pour cet élément on l’archive comme information pour plus tard, ou on supprime s’il est vraiment inutile.
  • Règle des deux minutes : si l’action à accomplir prend moins de deux minutes, on l’exécute, sans chercher à déléguer ou reporter. En effet, gérer une tâche (la déléguer, la mettre dans une liste, etc…) prend du temps, si la tâche en elle même est rapide, autant la faire tout de suite. (le but : on dépile, on dépile).
  • Est-ce que c’est vraiment à moi de le faire ? Si on n’est pas la meilleure personne pour exécuter une tâche, on la délègue. Il faut alors garder une liste des tâches déléguées, pour suivre l’avancement.
  • Enfin, on place la tâche dans la liste des prochaines actions, ou dans le calendrier si c’est un rendez vous.

Dans la liste des prochaines actions, on ne doit avoir que des choses immédiatement actionables, on ne doit pas avoir besoin de réfléchir pour l’exécuter, cela ne doit pas être vague. « Projet Sigma » par exemple n’est pas une action valable, au contraire de « Faire une proposition chiffrée au client pour Sigma ». En général, s’il y a un verbe dans la tâche, c’est bon signe. Une tâche vague doit être reformulée ou découpée, sinon elle risque plus que les autres d’être procrastinée.

La liste de prochaines actions doit être revue régulièrement pour toujours être ordonnée par priorité. C’est là qu’un outil comme Trello, qui permet de déplacer les cartes, est supérieur à une liste papier.

GTD préconise aussi d’avoir une liste « En attente / à suivre » pour les trucs qui attendent un élément de quelqu’un ou quelque chose d’autre.

A la fin du process l’inbox doit être vide.

Mon inbox (mail personnels, cherry think, best of web, etc…) est vide. Tout part dans trello.

inbox

Limiter le travail en cours

Kanban est un système de gestion de tâches. C’est une méthodologie sur laquelle beaucoup de choses ont été écrites, et dont on pourrait parler longtemps. Je ne vais présenter ici que ce qui est nécessaire pour une (ma) gestion des tâches personnelle.

Management visuel : Kanban est basé sur des boards (tableaux), avec des cartes (qui sont des tâches, pour ce qui nous intéresse). Le tableau représente chaque étape dans lesquelles passent les cartes. Il peut y avoir tout plein de colonnes. En regardant le tableau on peut voir l’état du projet, s’il y a des tâches bloquées, s’il y a beaucoup ou pas beaucoup de choses terminées, etc…

Un point important est la gestion des flux : le parcours d’une tâche dans le tableau doit être fluide, prévisible, sans blocage. En particulier, chaque colonne (sauf la première qui est le backlog de chose à faire et la dernière, qui contient ce qui est fini) a un nombre limité d’éléments. On limite le travail en cours, pour ne pas commencer plein de choses sans les terminer.

Pour la même raison, il faut éviter le multitasking : on est forcément plus efficace en étant bien concentré.

Done list

Un point dont GTD ou Kanban ne parlent pas, mais qui est source de joie et de contentement : la satisfaction de voir les choses accomplies, d’avoir produit, réalisé, terminé des tâches et des corvées.

Ce n’est pas vital, on pourrait juste supprimer les tâches terminées et les faire disparaitre du board, mais je trouve agréable d’avoir une liste des choses, done, accomplies, que je peux regarder.

Les gens qui préfèrent le papier ont la satisfaction de pouvoir barrer d’un grand coup de crayon l’élément dans leur liste. C’est plus gratifiant encore, on a un soulagement physique.

Amélioration continue

Au coeurs de la philosophie agile et de kanban, il y a l’amélioration continue : régulièrement se demander ce qui marche, ce qui ne marche pas, pour s’améliorer.
Amélioration continue     kaizen     roue de demming