- John Carmack a partagé son point de vue personnel sur l’usage des variables mutables (mutable variables)
- Il explique qu’en utilisant Python, il a eu tendance à négliger le principe de la “single assignment”, et qu’il faut selon lui s’en méfier consciemment
- Il souligne qu’en dehors des calculs itératifs dans les boucles, il faut éviter de réaffecter ou de mettre à jour les variables
- Lorsque toutes les étapes intermédiaires du calcul sont conservées, cela aide au débogage et permet d’éviter qu’une ancienne valeur soit utilisée involontairement lors du déplacement d’un bloc de code
- Il explique qu’en C/C++, c’est une bonne habitude de déclarer presque toutes les variables en
const dès leur initialisation
- Enfin, il insiste sur le fait qu’il aimerait que
mutable soit un mot-clé, afin que l’immuabilité devienne la valeur par défaut
1 commentaires
Avis Hacker News
Après avoir utilisé Clojure pendant 2 ans, j’ai constaté qu’il était vraiment difficile d’expliquer à d’autres développeurs la clarté apportée par l’immutabilité
Les personnes habituées à penser en termes d’effets produits via des changements d’état ont du mal à le comprendre tant qu’elles ne l’ont pas expérimenté directement
Par exemple, si on écrit
x = 7; x = x + 3; x = x / 2, changer l’ordre ne provoque pas d’erreur mais donne un résultat différentEn revanche, si on utilise de nouvelles variables comme
x1,x2, un mauvais ordre provoque une erreur et met clairement le problème en évidenceAu fond, l’affectation unique (single assignment) est une manière d’exprimer explicitement ces dépendances
Même en expliquant à des collègues qui n’avaient jamais utilisé de langage fonctionnel à quel point une approche centrée sur les fonctions est facile à tester et propre, ça ne leur parlait pas vraiment
En Python, il est difficile d’écrire un style fonctionnel de manière lisible, et j’ai l’impression que JS s’en sort mieux
Au final, seuls les développeurs curieux essaient des langages comme Clojure
La fonction n’a pas besoin de connaître l’état externe, et l’extérieur n’a pas besoin de connaître l’intérieur de la fonction
Sans connaître l’état global du programme, on peut tester ou déboguer indépendamment une fonction précise
Il est intéressant de voir que la communauté Haskell finit par tenter de réinventer la mutabilité à l’intérieur du système de types
L’essentiel est de contrôler les effets de bord au moindre coût
Haskell avait une barrière d’entrée élevée à cause de son système de types, et F# était trop conciliant, au point qu’on finissait par coder avec une syntaxe de C#
Grâce à l’homoiconicité de Clojure et à la puissance de ses structures de données, l’idée de « travailler avec des valeurs » m’est apparue clairement pour la première fois
Je ne l’utiliserai probablement pas dans un cadre professionnel, mais je le recommande vivement à toute personne n’ayant ni expérience en langage fonctionnel ni avec Lisp
J’aimerais que les variables soient immuables par défaut et que tout soit une expression
Mais dans la réalité, en tant que développeur Clojure, je subis l’invasion de Python
Maintenant, je subis l’invasion de TypeScript, donc je compatis
Cette approche est vraiment utile pour limiter la portée des modifications
Pas besoin de se laisser entraîner dans des guerres de chapelle entre langages
À l’ère des gains de productivité, ces frontières n’ont plus vraiment de sens
Je recommande l’article Don’t Call Yourself a Programmer
J’essaie de minimiser les réaffectations de variables, mais j’utilise parfois le masquage de variables
J’aime bien les motifs comme
result = result.process()parce qu’ils sont concisPar exemple, si
process()est une fonction de validation, on peut ne plus savoir clairement à quel moment une valeur a été traitéeIl vaut donc mieux distinguer explicitement les états par leur nom
Exemple :
result = x |> foo |> bar |> bazou(-> x foo bar baz)result.process(), d’accord, mais quel result et quel process au juste ? »La personne qui lira le code plus tard risque d’être perdue
result), le retraiter (process) paraît logiquement étrangeLe terme même de « variable » m’a toujours dérangé
Si c’est immuable, pourquoi appeler ça une variable ?
En Rust, il faut l’indiquer explicitement avec
mutpour pouvoir la modifierEn C, au contraire, il faut passer par le préprocesseur pour créer des constantes, ce qui prête à confusion
xd’une fonction reçoit une valeur différente à chaque appel, c’est donc en soi une valeur variableOn peut donc parler de variable même sans réaffectation
La programmation a repris ce concept tel quel
Une constante, elle, a la même valeur dans toutes les exécutions
Voir Variable (mathematics)
Ce serait bien que l’IDE indique visuellement si une variable est modifiée
Par exemple en marquant légèrement les variables modifiées
Utiliser autant de
finalque possible rend le code plus lisible et plus facile à maintenirL’IDE devrait avertir, et n’autoriser la modification que lorsqu’elle est vraiment nécessaire
Comme dans la réflexion de Rich Hickey sur set vs list, il faut choisir des structures qui expriment clairement le sens
J’ai autrefois travaillé sur un projet où l’immutabilité était appliquée strictement pour assurer la sécurité des threads
Grâce à cela, le code était plus facile à lire et il était plus simple de suivre ce qui pouvait changer
Depuis, je suis devenu un grand fan de l’immutabilité
Après avoir travaillé sur une grosse codebase Haskell puis être revenu au C, je me suis dit qu’il vaudrait mieux que l’immutabilité soit la norme
constne suffit pasPour modifier, il faut utiliser des pointeurs, et en C++, un simple appel de fonction peut aussi changer les arguments, ce qui manque de transparence
Je suis d’accord avec l’idée que « déclarer presque toutes les variables en const est une bonne pratique »
Il est logique de mentionner Rust
J’imagine une syntaxe où l’immutabilité est la règle, et où le mutable n’est autorisé qu’à l’intérieur d’un bloc précis
Par exemple comme un bloc
withen PythonUne fois sorti du bloc, tout redeviendrait immuable
Le borrow checker de Rust montre à quel point cette idée est complexe
Il y a ce dicton : « State is the enemy »
Plus l’état augmente, plus les conditions à tester augmentent de manière exponentielle
L’immutabilité est une façon d’éviter cette explosion des états
Separation of Church and State