Need for speed : UX vs. DX
Passé l'engouement que suscite l'apprentissage de la programmation fonctionnelle vient généralement la question :
Euh… et les performances ?
C'est une très bonne question : qui dit programmation fonctionnelle dit fonctions pures, donc immutabilité. Programmer de manière immutable consiste à créer de nouveaux objets à partir des anciens plutôt que de modifier ces derniers. Cela entraîne nécessairement des performances moindres à l'exécution.
Faut-il pour autant délaisser la programmation fonctionnelle ?
Rappelons déjà la règle d'or de l'optimisation : on n'optimise pas s'il n'y a pas de problème. Certes, on évite d'écrire du code totalement naïf, mais on ne met pas en place des usines à gaz pour rien (poke les #microservices 😉).
Pour le reste, c'est en fait une question bien plus large dans le monde de l'ingénierie logicielle : la question UX vs. DX.
Hein ?
Dans l'informatique de gestion, les sujets de performance ne sont pas si fréquents. Et quand ils arrivent, le sujet est rarement le paradigme de programmation (on regardera plus souvent du côté des dépendances ou de la base de données). Pour des applications de tous les jours, des performances "standard" sont a priori suffisantes et l'expérience utilisateur (User eXperience) est préservée.
En revanche, le développement est un sujet à part entière, dans 100% des produits. Il faut des années d'expérience — une vie ? — pour arriver à une expérience de développement fluide (Developer eXperience), seul ou, a fortiori, en équipe.
Il s'agit notamment de la capacité à mettre en œuvre rapidement une demande de changement (Mean Lead Time for Changes), du taux de bugs constatés en production (Change Failure Rate) ou bien encore du temps nécessaire pour revenir à un système fonctionnel (Mean Time to Recovery). L'œil averti aura reconnu ici 3 des 4 DORA Metrics dont tout le monde parle, à raison.
La programmation fonctionnelle, justement, est un facteur clé dans l'atteinte de ces objectifs. Les fonctions pures sont appréciées des développeurs car elles diminuent la charge cognitive. Pas d'effet de bord, donc peu de risque à modifier une fonction pure ; un comportement déterministe, donc des fonctions faciles à tester — et à écrire en Test-driven development tant qu'à faire. Si je fais une erreur, je m'en rends compte immédiatement. Donc un système plus facile à faire évoluer et moins de bugs. On nage dans le bonheur 🤤.
C'est vrai de la programmation fonctionnelle comme de React, pour ne citer qu'une technologie parmi d'autres. React, c'est avant tout un DOM Virtuel, qui permet d'écrire dans un style déclaratif ("je veux une liste avec 3 items"), la traduction en instructions (style impératif) se faisant automatiquement en fonction de l'état du système. Cet algorithme dit "de réconciliation" sera nécessairement moins performant que ce que vous pourriez faire en vanilla JS (l'ordre de grandeur est de 1 à 10). Pourtant, aucun développeur censé n'envisagerait de se lancer en 2023 dans une application d'ampleur sans librairie ni framework améliorant l'expérience de développement.
Au final, des développeurs heureux, ce sont des utilisateurs heureux !