Application des principes du Clean Code aux langages fonctionnels


16

Je lis actuellement le code propre de Robert Martin . Je pense que c'est génial, et quand j'écris du code OO, je prends ses leçons à cœur. En particulier, je pense que son conseil d'utiliser de petites fonctions avec des noms significatifs rend mon code beaucoup plus fluide. Il est mieux résumé par cette citation:

[Nous] voulons pouvoir lire le programme comme s'il s'agissait d'un ensemble de paragraphes TO, chacun décrivant le niveau d'abstraction actuel et référençant les paragraphes TO suivants au niveau suivant.

( Code propre , page 37: un "paragraphe TO" est un paragraphe qui commence par une phrase exprimée à l'infinitif. "Pour faire X, nous effectuons les étapes Y et Z." "Pour faire Y, nous ..." etc. ) Par exemple:

À RenderPageWithSetupsAndTeardowns, nous vérifions si la page est une page de test et si oui, nous incluons les configurations et les démontages. Dans les deux cas, nous rendons la page en HTML

J'écris également du code fonctionnel pour mon travail. Les exemples de Martin dans le livre se lisent certainement comme s'il s'agissait d'un ensemble de paragraphes, et ils sont très clairs - mais je ne suis pas sûr que «se lit comme un ensemble de paragraphes» soit une qualité souhaitable pour que le code fonctionnel ait .

Prenons un exemple de la bibliothèque standard de Haskell :

maximumBy               :: (a -> a -> Ordering) -> [a] -> a
maximumBy _ []          =  error "List.maximumBy: empty list"
maximumBy cmp xs        =  foldl1 maxBy xs
                        where
                           maxBy x y = case cmp x y of
                                       GT -> x
                                       _  -> y

C'est à peu près aussi loin que possible de l'avis de Martin, mais c'est Haskell concis et idiomatique. Contrairement aux exemples Java de son livre, je ne peux imaginer aucun moyen de refactoriser cela en quelque chose qui a le genre de cadence qu'il demande. Je soupçonne que Haskell écrit selon la norme de Clean Code serait considéré comme long et non naturel.

Ai-je tort de considérer (au moins une partie) du code propre en contradiction avec les meilleures pratiques de programmation fonctionnelle? Existe-t-il un moyen sensé de réinterpréter ce qu'il dit dans un paradigme différent?


1
Les programmeurs fonctionnels ont tendance à écrire du code trop laconique, c'est vrai. Je ne considérerais pas cela à distance comme une meilleure pratique, même dans cet environnement.
Telastyn

Pardonnez l'ignorance, mais qu'est-ce qu'un paragraphe TO?
Shashank Gupta,

4
Comme cela a été mentionné dans une autre question récemment, Dijkstra a écrit sur la folie de la «programmation en langage naturel» et j'ai tendance à être d'accord avec lui que le code qui se lit comme de la prose est un rêve de pipe. Je pense que cela est particulièrement vrai dans Haskell qui, étant pur, exprime symboliquement des égalités entre les valeurs plutôt que des séquences d'étapes pour produire des effets. Je pense que l'important est que le code cité soit idiomatique. Par exemple, xsc'est une sorte de mauvais nom, mais c'est aussi courant dans les langages fonctionnels que ipour les variables de boucle.
Doval

@ShashankGupta J'ai édité la question avec un lien vers la page spécifique du livre ainsi que ma propre compréhension de ce que l'oncle Bob a écrit.

@ShashankGupta Il donne quelques exemples, mais l'idée est qu'elle devrait se lire comme de la prose. "Pour trouver le maximum de la liste, vous vérifiez chaque élément ..."
Patrick Collins

Réponses:


11

Clean Code est avant tout un manuel de style. Strunk and White ne s'applique pas lorsque vous écrivez en klingon. L'idée est que vous souhaitiez être clair pour les programmeurs qui liront probablement votre code. Vous voulez un code modulaire et facile à restructurer. Il existe des moyens de le faire dans Haskell, tout comme il existe des moyens de le faire dans n'importe quelle autre langue, mais les détails précis varieront.

Cela étant dit, il existe un certain nombre de directives de style pour Haskell. Stack Overflow propose également un guide assez complet . Garder la logique de codage simple et brève semble être assez constant. La généralisation des fonctions est également soulignée car elle conduit à la modularité. Le code DRY est également souligné, comme avec Clean Code.

En fin de compte, les directives de codage de Clean Code et de Haskell visent la même chose, mais finissent par prendre leur propre chemin pour y arriver.


1
J'ai l'impression que cette réponse réduit les principes que Clean Code enseigne qui sont très applicables dans toutes les langues, et qui sont au cœur de la question posée. Je peux voir pourquoi les gens pensent que Clean Code est un manuel de style, et je pense que c'est en partie vrai, mais pas assez vrai pour rejeter le livre entier comme un seul.
Allan

Je ne pense pas que le livre de Martin's Clean Code soit un manuel de style. Je pense que les enseignements du livre se situent en fait quelque part entre un guide de style et des modèles de conception.
Michael R

15

Je ne suis pas sûr de suivre ce que vous entendez par votre exemple. Les paragraphes, comme il les décrit, ne nécessitent pas de longue haleine. Il ne veut pas dire que le code doit se lire comme l'anglais. L'important est le regroupement des fonctionnalités au même niveau d'abstraction, dans une progression logique. C'est un concept structurel théorique qui transcende les paradigmes de programmation.

Exprimé au format "TO paragraph" de Bob Martin, je lis votre exemple comme:

  • Pour calculer le maximumBy , vous avez besoin d'une fonction de classement et d'une liste, et le résultat est un élément de cette liste.
  • Pour calculer le maximumBy liste vide et toute fonction de classement est une erreur.
  • Pour calculer la maximumByliste xs, vous repliez cette liste à l'aide dumaxBy fonction.
  • Pour calculer les maxBydeux éléments de liste, vous les comparez à l'aide de la fonction de classement donnée. Si le premier élément est supérieur, choisissez-le. Sinon, choisissez le second.

Vous commencez avec les concepts les plus généraux et progressez plus en détail, comme dans les exemples impératifs. L'idée des "paragraphes TO" est que vous pouvez arrêter la lecture à un certain moment lorsque vous avez obtenu suffisamment de détails, sans avoir à sauter de haut en bas de la page. C'est certainement le cas ici.

Quelques noms pourraient peut-être être meilleurs, mais ce sont des conventions courantes du langage, en particulier lors de l'écriture de fonctions génériques d'ordre supérieur. Les noms de fonction d'ordre supérieur ne se traduisent pas non plus bien en phrases verbales impératives comme les exemples du livre, car ils décrivent davantage les relations entre les verbes.

Il existe des moyens de l'implémenter qui ne respectent pas les directives "TO paragraphe". Laisser de côté la signature de type explicite omettrait la phrase "aperçu" de niveau supérieur. Vous pouvez utiliser une expression if pour la gestion des erreurs au lieu de la mise en correspondance de modèles, ce qui embrouillerait de manière inappropriée un autre niveau d'abstraction. Vous pourriez inlinemaxBy tant que fonction anonyme au lieu de lui donner un nom qui peut être décrit plus tard plus en détail.

En fait, je pense que les constructions comme en wherefait conviennent mieux au format de paragraphe, car vous pouvez les utiliser pour donner un nom à un détail plus profond d'une manière qui est proche de la façon dont nous l'exprimons en anglais, et limiter de manière similaire sa portée dans un manière claire au contexte du «paragraphe».

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.