La simplicité améliore-t-elle toujours la lisibilité?

32

Récemment, je développais un ensemble de normes de codage pour notre entreprise. (Nous sommes une nouvelle équipe se ramifiant dans une nouvelle langue pour l'entreprise.)

Lors de ma première ébauche, j'ai défini l'objectif de nos normes de codage comme l'amélioration de la lisibilité, de la maintenabilité, de la fiabilité et des performances. (J'ai ignoré l'écriture, la portabilité, le coût, la compatibilité avec les normes précédentes, etc.)

L'un de mes objectifs lors de la rédaction de ce document était de faire passer l'idée de simplicité du code. L'idée était qu'il ne devait y avoir qu'un seul appel de fonction ou opération par ligne. J'espérais que cela augmenterait la lisibilité. C'est une idée que j'ai reprise de notre langue précédente.

Cependant, j'ai remis en question l'hypothèse derrière cette poussée:

La simplicité améliore-t-elle toujours la lisibilité?

Existe-t-il un cas où l'écriture de code plus simple diminue la lisibilité?

Cela devrait être évident, mais par "plus simple", je ne veux pas dire "plus facile à écrire", mais moins de choses en cours par ligne.

Richard
la source
16
Si l'alternative est un code "intelligent", alors oui ...
Oded
2
oui - selon le rasoir d'Occam - en.wikipedia.org/wiki/Occam%27s_razor
aggietech
17
Essayez d'éviter d'utiliser des termes rigides comme toujours et jamais. Il s'agit d'éviter de se concentrer sur les cas marginaux et de se concentrer sur les problèmes les plus courants auxquels nous sommes confrontés. C'est à cela que servent les meilleures pratiques.
P.Brian.Mackey
en fait, vous voulez 2 fonctions / opérations par ligne. a = best une opération, b + cest une seconde, ce qui signifie a = b + cest 2 opérations. Le chaînage de 2 fonctions / opérateurs est toujours lisible:, foo(bar())ou a = foo().
zzzzBov
2
Ne vous inquiétez pas trop. Si vous essayez d'éliminer chaque élément de subjectivité de vos explications, tout comme si vous essayez de spécifier tous les détails possibles du style de codage dans un million ou plus de règles, vos normes seront trop complexes, illisibles, ignorées et donc inutiles.
Steve314

Réponses:

47

"Simple" est un mot galvaudé. «Lisible» peut être défini de manière rentable comme «simple à comprendre», auquel cas l'augmentation de cette mesure par définition augmente la lisibilité, mais je ne pense pas que ce soit ce que vous voulez dire. J'ai écrit à ce sujet ailleurs , mais généralement quelque chose peut être appelé "plus simple" soit en étant plus abstrait (auquel cas moins de concepts peuvent exprimer plus de phénomènes) soit en étant plus concret (auquel cas un concept ne nécessite pas autant de contexte connaissances à comprendre en premier lieu). Je soutiens que, selon la perspective, un concept plus abstrait peut raisonnablement être appelé plus simple qu'un concept plus concret, ou vice versa . Ceci, même si "abstrait" et "

Je vais utiliser comme exemple du code Haskell que j'ai écrit il y a quelque temps. J'ai posé une question sur stackoverflow à propos de l'utilisation de la monade List pour calculer un compteur dans lequel chaque chiffre pourrait avoir une base différente. Ma solution éventuelle (ne connaissant pas grand-chose à Haskell) ressemblait à:

count :: [Integer] -> [[Integer]]
count [] = [[]]
count (x:xs) =
  -- get all possible sequences for the remaining digits
  let
    remDigits :: [[Integer]]
    remDigits = count xs
  in
  -- pull out a possible sequence for the remaining digits
  do nextDigits <- remDigits
     -- pull out all possible values for the current digit
     y <- [0..x]
     -- record that "current digit" : "remaining digits" is
     -- a valid output.
     return (y:nextDigits)

L'une des réponses a réduit cela à:

count = mapM (enumFromTo 0)

Laquelle de celles-ci est "plus simple" à comprendre (c'est-à-dire plus lisible) dépend entièrement de la facilité avec laquelle le lecteur est devenu avec les opérations monadiques (abstraites) (et, en l'occurrence, le code sans point). Un lecteur très à l'aise avec ces concepts abstraits préférera lire la version (courte) plus abstraite, tandis qu'un lecteur qui ne sera pas à l'aise avec ces opérations préférera lire la version (longue) plus concrète. Il n'y a pas de réponse unique sur la version la plus lisible qui conviendra à tout le monde.

Aidan Cully
la source
11
Certains développeurs progresseront jusqu'à ce qu'ils comprennent et préfèrent le one-liner. Difficile d'imaginer un développeur qui comprend le one-liner venant préférer la version longue. Par conséquent, l'OMI le one-liner est clairement meilleur.
Kevin Cline du
7
@kevincline - en supposant que le développeur travaille de manière isolée, je suis d'accord, la version courte est (probablement) meilleure. Si elle travaille au sein d'une équipe, et que l'équipe n'est pas au niveau où elle comprend et préfère le one-liner, et ils doivent tous être en mesure de maintenir le code, alors la version longue est (probablement) meilleure dans ce cas. .
Aidan Cully
6
En contrepoint: étant donné que vous êtes un Haskeller expérimenté, vous pouvez lire la deuxième version en un coup d'œil. La première version, en revanche, nécessiterait la lecture et la compréhension de beaucoup plus de code; vous ne pouviez pas le faire en un coup d'œil. Je pense que cela rend la deuxième version plus simple.
Tikhon Jelvis
6
@ Steve314: mapMest assez idiomatique et enumFromTofait exactement ce qu'il dit sur l'étain. En général, je trouve qu'il est en fait plus facile de faire des erreurs individuelles si vous développez du code - il y a simplement plus de code pour faire une erreur. Cela est particulièrement évident avec des choses comme pour les boucles par rapport aux procédures d'ordre supérieur dans d'autres langues. , mais je trouve que c'est un principe général.
Tikhon Jelvis
1
@Tikhon - mais cela ne signifie pas nécessairement lire autant de code, et le code est là. Cela signifie qu'il peut y avoir des compromis. Habituellement fortement unilatéral en faveur de l'utilisation des fonctions existantes plutôt que de réinventer la roue, mais il existe des exceptions. Cela devient très évident en C ++, avec certains des "algorithmes" les plus triviaux de la bibliothèque standard - les utiliser peut parfois être plus verbeux et moins clair que l'écriture directe du code.
Steve314
13

Si votre norme de codage concerne la «lisibilité, la maintenabilité, la fiabilité et les performances», dites-le simplement .

N'essayez pas de prescrire comment réaliser ces choses car il y aura toujours des situations où il y aura un contre-exemple.

Ce que vous devez prescrire, ce sont des choses qui entraîneront la rupture du code si elles ne sont pas également respectées. Les traits stylistiques ne briseront pas le code et devraient être des suggestions (tant que la majorité de l'équipe convient qu'il s'agit de lisibilité, le reste devrait être la préférence du développeur (avec une révision du code afin que la pression des pairs rappelle aux gens que d'autres personnes doivent lire le code)) .

Martin York
la source
C'était le but que je visais et c'était l'objet déclaré. La simplicité (ou plutôt la seule fonction / opération par ligne) semblait naturellement découler de cet objectif. J'essaie de vérifier si ma compréhension n'était pas valide. Lorsque vous élaborez des normes de codage, l'établissement d'un ensemble de règles et de lignes directrices constitue tout l'intérêt de l'exercice. Fixer des règles et des directives trop vagues est inutile. En tant que telle, cette réponse n'aide vraiment pas.
Richard
5
Mon argument est que fixer des règles trop strictes est pire qu'inutile et est en fait nuisible. Définir des règles comme une instruction par ligne est stylistique. C'est la chose qui ne devrait certainement PAS figurer dans les directives du code. Il n'offre aucun avantage réel et peut nuire à la lisibilité et à la maintenabilité s'il est appliqué sans réfléchir.
Martin York
3
+1 (parce que je ne peux pas +10) Une erreur courante que je vois avec les nouveaux gestionnaires de programmation est qu'ils essaient de codifier les moindres détails. Les meilleures normes de codage ressemblent plus à des biscuits de fortune qu'à des recettes.
JohnFx
"Styles et normes de codage" était le nom du document. Évidemment, ce n'est pas un standard (comme dans "Ne jamais utiliser GoTo" ou "Ne jamais utiliser de petits caractères") mais un style. Le style unificateur est important pour la lisibilité et la maintenabilité.
Richard
1
Guide de style: "Ce projet utilise des tabulations / espaces (choisissez-en un). Ce projet utilise le style d'accolade K & R / Allman / BSD / GNU (choisissez-en un). Veuillez ne pas ajouter d'espaces vides à la fin des lignes. Veuillez conserver votre code propre et lisible. Tout sera révisé par deux membres de l'équipe et vous-même: pour la lisibilité / maintenabilité, vous avez besoin d'une majorité 2/3 pour vérifier le code, pour la fiabilité et les performances dont vous avez besoin 3/3 (veuillez fournir les tests appropriés pour prouver Plus de règles seront ajoutées en cas d’abus :-) "Terminé.
Martin York
7

Moins de "trucs par ligne", de simplicité et de lisibilité ne sont pas la même chose. On peut prendre un algorithme non documenté incroyablement compliqué et le coder avec 1 instruction par ligne au lieu de 2, et cela ne deviendra pas beaucoup plus lisible.

Moins de "trucs par ligne" pourrait également nécessiter de fournir aux développeurs de grands grands écrans pour voir les blocs de code maintenant répartis plus verticalement. Ou causez une fatigue oculaire en lisant des polices plus petites.

La lisibilité est sa propre métrique, qui nécessite souvent un compromis entre plusieurs autres métriques plus facilement mesurables. Pré-contraignez toutes ces autres métriques, et le compromis ne devient plus possible, ce qui entraîne un code moins lisible.

hotpaw2
la source
5

Toujours? - NON

Ironiquement, atteindre le bon niveau de simplicité peut être une entreprise complexe. Je pense que la clé est avec modération. La simplicité peut également être dans l'œil du spectateur, donc si vous vous surprenez à y penser, laissez-la tranquille ou revenez-y plus tard.

Personnellement, lorsque j'essaie de revenir en arrière et de simplifier quelque chose que j'ai écrit, je me concentre sur les domaines où j'ai changé d'avis ou essayé deux ou trois choses pour obtenir ce que je voulais. Ces zones peuvent généralement être lissées. Ensuite, faites quelques passages dans le code pour le rendre plus lisible sans étaler tellement les choses que vous sautez partout pour comprendre ce qui se passe lors d'un débogage.

DKnight
la source
5

Si je choisis la simplicité, je peux écrire du code comme ceci:

10000000000000000000000000000000000000000000

Mais si je choisis la lisibilité, je préférerai ceci:

1e43

D'un autre côté, 1000c'est beaucoup plus lisible et simple qu'à 1e3moins de travailler avec des nombres en notation scientifique tout le temps.

C'est un exemple dégénéré de modèle beaucoup plus général que vous pouvez trouver presque n'importe où - construire quelque chose à partir de blocs très simples peut rapidement devenir illisible / inefficace / mauvais de nombreuses façons différentes. La généralisation et la réutilisation, en revanche, sont plus difficiles au début ("wtf est e?! Voulaient -ils écrire 1343?" Pourrait-on dire), mais peuvent aider beaucoup à long terme.

Rotsor
la source
Votre argument selon lequel "1e3" est moins lisible que "100" est bien exprimé. En fait, c'est un excellent exemple de la façon dont la charge cognitive influence la lisibilité. "1e3" nécessite la lecture de 3 caractères ET la traduction de l'exponentiation. La lecture de "100" nécessite la lecture de 3 caractères et aucune autre évaluation.
Stephen Gross
Stephen, en fait, lorsque vous lisez un nombre à trois chiffres comme 100vous devez effectuer deux multiplications et deux additions ( 0+10*(0+10*1)). Cependant, après avoir utilisé cette notation, vous ne le remarquez même pas. Cela montre à nouveau à quel point la notion de simplicité peut être subjective.
Rotsor
Intéressant. Donc, à proprement parler, "100" nécessite 2 multiplications (1 * 100, 0 * 10) et 2 opérations d'addition. "1e3" nécessite une opération de multiplication. Ainsi, en l'absence de tout contexte cognitif , "100" est plus difficile à lire que "1e3". Mais! Si vous incluez la charge cognitive de changement de contexte, le calcul est différent. Puisque nous lisons normalement des entiers sous une forme non scientifique, "100" est plus facile. Mais, si nous écrivons une application d'ingénierie dans laquelle tous les nombres sont exprimés en notation scientifique, la forme "1e3" est plus facile!
Stephen Gross
2

Pas nécessairement. Si vous avez une opération complexe, cette complexité doit aller quelque part. Réduire le nombre de "trucs" qui va sur une seule ligne signifie simplement qu'il prendra plus de lignes, ce qui peut en fait nuire à la lisibilité du code s'il rend votre routine trop "grande" pour tenir sur un seul écran.

Maçon Wheeler
la source
La complexité n'est pas irréductible. Nous avons "abstraction" et "chunking" et "organisation" pour essayer de gérer la complexité. Je pense qu'une opération complexe peut être décrite en plusieurs étapes plus simples. Cela fonctionne pour de nombreux processus physiques du monde réel: résumés, aperçus, etc.
S.Lott
1
@ S.Lott: C'est vrai, mais suffisamment de défilement et de Ctrl-clic pourraient rendre un processus "simplifié" plus difficile à suivre. Je l'ai vu se produire une ou deux fois (ce n'est pas courant mais ça peut être très frustrant de travailler avec quand ça va trop loin).
FrustratedWithFormsDesigner
3
@ S.Lott - il y a encore des limites à la réduction de la complexité. Vous pouvez éliminer la complexité inutile, mais vous ne pouvez gérer (pas éliminer) la complexité nécessaire - la complexité inhérente aux exigences. On peut dire que les mécanismes de gestion de la complexité augmentent également la complexité - une complexité supplémentaire est impliquée dans le déplacement de la complexité non pertinente pour mieux révéler les détails pertinents pour un aspect / problème / construction particulier.
Steve314
1
@ S.Lott - Eh bien, il est certainement vrai que vous pouvez représenter n'importe quelle exigence que vous souhaitez avec un fichier source à complexité nulle (complètement vide). Mais comme vous avez besoin d'une langue très spécifique pour répondre à vos exigences, tout ce que vous faites, c'est déplacer vos exigences dans la spécification de langue.
Steve314
1
@ S.Lott - si vous prétendez que vous pouvez prédire la position de Jupiter le jour de Noël en utilisant rien mais G=0, je pense que vous êtes fou. Si vous ne l'êtes pas, vous manquez mon point. Certes, vous pouvez faire abstraction des détails non pertinents, mais ce n'est pas inutile si vos exigences indiquent que c'est pertinent. Si vous relisez, je n'ai jamais prétendu que toute la complexité est nécessaire - seulement qu'une certaine complexité est inhérente aux exigences et ne peut pas être éliminée.
Steve314
2

Clarté + Normes + Réutilisation du code + Bons commentaires + Une bonne conception pourrait améliorer la lisibilité .

La simplicité n'est pas toujours entre les mains du développeur car la nature des algorithmes et la complexité de la structure de l'application de nos jours.

Prenez les pages Web simples qui effectuent des tâches simples. Étant donné une routine de tri, il n'est pas possible de simplifier la logique, mais vous pouvez la rendre plus claire avec des commentaires, en utilisant des noms de variables significatifs, en les écrivant de manière structurée, etc.

Aucune chance
la source
2

La simplicité améliore-t-elle toujours la lisibilité?

Non. J'ai vu de nombreux cas où faire plusieurs choses plus simples sur une seule ligne est moins complexe que d'avoir plusieurs lignes.

Il y a un compromis entre moins de code et un code plus simple.

En général, je recommanderais d'utiliser un code plus simple, sauf si vous êtes sûr de le faire en moins de lignes, c'est mieux. Je préférerais de beaucoup avoir un code "trop ​​verbeux" plutôt qu'un code "trop ​​complexe".

Tom Squires
la source
1

"Rendre les choses aussi simples que possible, mais pas plus simples" - Une paraphrase souvent d'Albert Einstein

La simplicité améliore tout . Pour des valeurs différentes de simplicité, bien sûr. S'agit-il de moins de lignes de code? Peut être. Est-ce un exécutable plus petit? Peut-être. Est-ce quelque chose sur lequel votre équipe doit s'entendre? Absolument .

Jesse C. Slicer
la source
+1 pour le devis, mais la simplicité améliore-t-elle la lisibilité?
Richard
"Rendre les choses aussi simples que possible puis les simplifier" est une meilleure paraphrase car les ingénieurs SW sont enclins à une ingénierie excessive.
mattnz
1
Je souhaite que les gens cessent de dire "rendre les choses aussi simples que possible, mais pas plus simples". Ne pouvons-nous pas au moins généraliser à MakeAsGoodAsPossibleButNoMoreSo <Thing, Attribute> alors que nous allons vers une astuce d'ingénierie inutilement générale? (Désolé @Jesse C. Slicer, vous êtes loin d'être la seule personne à le citer, donc vous ne méritez pas vraiment le mini-diatribe plus que quiconque).
psr
1

La simplicité améliore-t-elle toujours la lisibilité? Oui. Une déclaration par ligne est-elle toujours plus simple? Non. Beaucoup de langues ont un opérateur ternaire, qui, une fois saisi, est plus simple et plus facile à comprendre que les affectations équivalentes if / else.

Dans les langues qui permettent de définir plusieurs variables sur une seule ligne, cela est souvent plus simple et plus facile à comprendre que l'équivalent.

Autre exemple: les expressions régulières font beaucoup, généralement sur une seule ligne, et l'équivalent sans expression régulière est souvent beaucoup plus difficile à lire. / \ d {3} [-] \ d {3} - \ d {4} / est l'équivalent d'un appel de fonction avec plusieurs commentaires au moins, et est plus facile à comprendre que le corps de fonction correspondant.

jmoreno
la source
1

La lisibilité et la simplicité sont des termes subjectifs qui, selon la personne et le contexte, vont généralement mais pas toujours ensemble.

Un terme plus objectif est la concision - quelque chose que vous pourriez en principe compter en comptant les caractères, bien qu'il y ait quelques défauts dans cela. La concision semble impliquer la simplicité et la lisibilité, mais il y a (au moins à mon avis) des exceptions.

Un morceau de code plus long (et sans doute plus complexe) peut être plus lisible s'il exprime mieux l'intention. Que votre définition de la simplicité se soucie de l'intention est une autre chose subjective - vous pouvez définir la complexité en termes de structure syntaxique et d'entropie de la théorie de l'information, par exemple, sans aucune référence aux intentions.

Ainsi, un nom de variable plus long et bien choisi peut ...

  • Améliorez la lisibilité en exprimant mieux l'intention
  • Réduisez la concision - c'est plus long, après tout
  • N'ont aucun effet sur la simplicité syntaxique - la structure syntaxique du code est inchangée

De même, je pourrais écrire if (some_boolean == true). En comparaison avec l'alternative équivalente if (some_boolean), cela ...

  • Réduit la concision
  • Réduit la simplicité syntaxique, mais
  • Peut améliorer la lisibilité en exprimant mieux l'intention.

Bien sûr , celui - ci déclenche une manifestation de masse - à beaucoup de gens, ce toujours la lisibilité des dommages aussi. Pour moi, cela dépend beaucoup de la source du booléen - par exemple, le nom de la variable (ou le nom de la méthode ou autre) peut ne pas exprimer clairement que la valeur est la "valeur de vérité". Bien sûr, le ifvous dit quelque chose, mais ça sent toujours. Mais beaucoup de gens me traiteront d'idiot pour avoir cru cela.

Ce qui est une preuve supplémentaire de la subjectivité globale, bien sûr.

Steve314
la source
1

Vous manquez tous des définitions fondamentales . Simple, à partir de la racine sim-plex , signifie un pli . Simple signifie faire une chose . Facile, de la facilité racine , signifie rester près . Facile signifie qu'il est à portée de main . Les exemples de code simple donnés dans d'autres réponses ne sont pas exactement ce qu'ils apparaissent.

Prenez l' affichage du rotsor d'une très grande valeur. Il dit que c'est simple . N'est pas, à mon avis, simple. C'est facile. Il est à portée de main pour taper le nombre de 0 requis.

10000000000000000000000000000000000000000000

La version lisible est simple. Cela fait une chose. Il exprime le nombre en décrivant sa taille dans un but de notation construit pour cette fonction.

1e43

Pourriez-vous décrire l' extrait de code "simple" d' Aidan comme faisant une chose? Il contient 10 lignes de code (sans compter les commentaires) et au moins 7 blocs (comme je les compterais). Si vous suivez les commentaires, vous verriez qu'il fait au moins 4 choses!

count :: [Integer] -> [[Integer]]
count [] = [[]]
count (x:xs) =
  -- get all possible sequences for the remaining digits
  let
    remDigits :: [[Integer]]
    remDigits = count xs
  in
  -- pull out a possible sequence for the remaining digits
  do nextDigits <- remDigits
     -- pull out all possible values for the current digit
     y <- [0..x]
     -- record that "current digit" : "remaining digits" is
     -- a valid output.
     return (y:nextDigits)

Mais, une des recommandations pour réécrire ce code était une déclaration. Aidan déclare qu'un lecteur devrait être ou se familiariser avec les déclarations monadiques, le code sans pointeur, etc. C'est très bien. Ces concepts sont singuliers et indépendants à apprendre.

count = mapM (enumFromTo 0)

Vous constaterez que le code vraiment simple est plus lisible que le code facile car il ne fait qu'une chose. Vous devrez peut-être partir et apprendre plus "une chose" pour comprendre le code simple. Mais cela devrait toujours être plus lisible.

Anthony Mastrean
la source
1

La simplicité améliore-t-elle toujours la lisibilité?

Je dirais, peut-être avec un peu de controverse, absolument pas .

Vous pourriez me donner une classe avec 200 fonctions membres dans son interface publique, et c'est peut-être l'interface publique la plus lisible humainement. Ce pourrait être une joie de lire nonchalamment ce code et sa documentation. Cependant, je n'appellerais pas cela "simple", car malgré la lisibilité, je devrais m'inquiéter de la façon dont toutes ces fonctions interagissent les unes avec les autres, et potentiellement faire attention aux cas délicats résultant d'une mauvaise utilisation.

Je préférerais une classe avec 20 fonctions membres qui n'étaient pas si faciles à lire à 200 qui le sont, car la "lisibilité" n'est pas la priorité absolue pour moi en termes de prévention des erreurs humaines et d'amélioration de la maintenabilité du code (la facilité avec laquelle on peut le changer, ie).

Cependant, tout cela dépendra de notre définition personnelle de la "simplicité". La «lisibilité» ne varie généralement pas si énormément parmi nous, à moins que quelqu'un ait acquis une telle expertise et une telle fluidité qu'il considère que l'expression régulière est très «lisible», par exemple, en oubliant le reste d'entre nous de simples mortels.

Simplicité

Il fut un temps, il y a longtemps, où je pensais que "simplicty" signifiait "aussi facile à lire que possible". J'écrirais donc du code C avec beaucoup de fonctions pratiques, en essayant d'améliorer la syntaxe et de rendre les choses aussi faciles à lire et à écrire que possible.

En conséquence, j'ai conçu de très grandes bibliothèques riches et de haut niveau, essayant de modéliser une fonction pour chaque pensée humaine naturelle: aides sur aides sur aides, le tout pour façonner le code client selon une syntaxe plus lisible. Le code que j'ai écrit à l'époque était peut-être le plus "lisible", mais il était aussi le plus "incontrôlable" et "complexe".

Zézayer

Pourtant, j'ai eu une brève passion avec LISP vers le milieu des années 90 (retardataire). Cela a changé toute mon idée de la "simplicité".

LISP n'est pas la langue la plus lisible. Espérons que personne ne pense que l'extraction de CDR et de CAR tout en invoquant une fonction récursive avec une cargaison de parenthèses imbriquées est très "lisible".

Néanmoins, après avoir lutté pour que mon cerveau s'enroule autour de la syntaxe étrange du langage et des façons de faire totalement récursives, cela a définitivement changé mon idée de la simplicité.

Ce que j'ai trouvé avec le code que j'ai écrit dans LISP, c'est que je ne faisais plus d'erreurs subtiles, même si la difficulté de penser de cette façon m'a fait faire des erreurs plus flagrantes (mais celles-ci sont faciles à repérer et à corriger). Je ne comprenais pas mal ce que faisait une fonction et je manquais un effet secondaire subtil et imprévu. J'avais juste plus de facilité à faire des changements et à écrire des programmes corrects.

Après LISP, la simplicité est devenue pour moi le minimalisme, la symétrie, la flexibilité, moins d'effets secondaires, des fonctions moins nombreuses mais plus flexibles qui se combinent de manière infinie.

J'ai fini par comprendre que le code le plus fiable de tous est le code qui n'existe pas. Bien qu'il ne s'agisse que d'une mesure brute, j'ai tendance à voir le potentiel de manque de fiabilité du code en fonction de sa quantité. La recherche de la plus grande commodité syntaxique et de la meilleure lisibilité tend à augmenter cette quantité d'un facteur important.

Minimalisme

Avec l'état d'esprit LISP intégré en moi, j'en suis venu à préférer les API minimalistes. Je préférerais une bibliothèque avec moins de fonctions mais plus fiables et flexibles, moins pratiques et plus difficiles à lire qu'une bibliothèque qui offre une multitude d'aides "pratiques" et qui pourraient rendre le code facile à "lire" mais potentiellement trébucher plus de problèmes de manque de fiabilité et de surprises résultant d'une mauvaise compréhension de ce que font ces milliers de fonctions.

sécurité

Une autre chose à propos de LISP était la sécurité. Cela favorisait des effets secondaires minimes et des fonctions pures, et c'est là que je ne me voyais plus commettre d'erreurs subtiles, même si la difficulté de lire et d'écrire dans la langue augmentait les erreurs les plus flagrantes que je pouvais repérer 10 secondes plus tard.

Les fonctions pures et les états immuables m'est devenu préférable chaque fois que je pouvais me le permettre, même si la syntaxe de:

sword = sharpen(sword)

... est un peu moins simple et détaché de la pensée humaine que:

sharpen(sword)

Lisibilité VS. Simplicité

Encore une fois, LISP n'est pas le langage le plus "lisible". Il peut regrouper beaucoup de logique dans une petite section de code (peut-être plus d'une pensée humaine par ligne). J'ai tendance à préférer idéalement une pensée humaine par ligne pour la "lisibilité", mais ce n'est pas nécessairement pour la "simplicité".

Avec ce type de définition de «simple», parfois «simple» pourrait en fait quelque peu rivaliser avec «lisible». Cela considère les choses davantage du point de vue de la conception de l'interface.

Une interface simple signifie que vous devez apprendre beaucoup moins de choses pour l'utiliser, et potentiellement avoir une plus grande fiabilité et moins de problèmes en raison de son minimalisme. Une documentation complète sur le sujet pourrait convenir à un livret plutôt qu'à un volume massif de livres. Néanmoins, cela pourrait nécessiter plus de travail et produire du code moins lisible.

«Simple» pour moi améliore notre capacité à comprendre les fonctionnalités de notre système à un large niveau. «Lisible» pour moi améliore notre capacité à connecter chaque petite ligne de code au langage naturel et à la pensée et pourrait accélérer notre compréhension de ce qu'une seule ligne de code fait, surtout si nous ne parlons pas couramment la langue.

Regex est un exemple de ce que je considère comme "extrêmement simple". C'est "trop ​​simple et trop illisible" à mon goût personnel. Il y a un équilibre pour moi entre ces extrêmes, mais le regex a cette qualité de simplicité LISP telle que je le définis: minimalisme, symétrie, flexibilité incroyable, fiabilité, etc. Le problème pour moi avec le regex est qu'il est si simple qu'il est devenu tellement illisible au point où je ne pense pas que je pourrais jamais le maîtriser (mon cerveau ne fonctionne tout simplement pas de cette façon et j'envie les gens qui peuvent écrire couramment du code regex).

Donc, de toute façon, c'est ma définition de la "simplicité", et elle est complètement indépendante de la "lisibilité" et peut même parfois interférer avec l'autre, conduisant à un équilibre entre une bibliothèque plus "syntaxiquement pratique" et lisible mais plus grande ou une "syntaxiquement" inconvenient ", bibliothèque moins lisible, mais plus petite. J'ai toujours trouvé que les véritables priorités de «commodité de compréhension» et de «maintenabilité» s'alignaient sur ces dernières, avec la forte préférence pour le minimalisme, même à un certain coût pour la lisibilité et la syntaxe humaine plus naturelle (mais pas au point de regex) . YMMV.


la source
0

Toujours? - OUI

Atteindre le bon niveau de simplicité est une entreprise complexe et difficile. Mais toujours utile car il améliore toujours la lisibilité. Je pense que la clé est une compréhension profonde. La simplicité est un absolu, mesuré par de "nouveaux concepts" par "morceau" de code. Quelques nouveaux concepts signifient plus simple.

Concentrez-vous sur les domaines où il existe un groupe dense de concepts et trouvez des moyens de "fragmenter" ou "résumer" ou "abstrait". Effectuez quelques passages dans le code pour le rendre plus simple et plus lisible.

Une bonne abstraction vaut son pesant d'or. Une bonne abstraction rend cela plus simple - et par conséquent plus lisible.

S.Lott
la source
Je ne peux pas m'empêcher de penser que vos citations de peur sont là parce que vous êtes conscient que le "concept" et le "morceau" sont eux-mêmes subjectifs. Le concept unique d'une personne est un autre regroupement de trois idées distinctes. Il est difficile d'avoir une mesure absolue et objective de choses subjectives.
Steve314
@ Steve314: Citations effrayantes? Non. En.wikipedia.org/wiki/Chunking semblent tous être similaires dans la mesure où ils décrivent la simplification par segmentation. (Sauf la technique de la guitare, cela semble différent.) Les citations sont là parce qu'il y a tellement de termes alternatifs pour abstraction, segmentation, résumé, etc. Les citations sont là pour souligner que cela est en quelque sorte discutable. Encore. C'est clairement fait tout le temps et semble être une tendance humaine naturelle.
S.Lott
Ce que je ne nie pas - le découpage est fait tout le temps et c'est une bonne idée. Ce que je nie - qu'il existe une règle objective définitive pour savoir où les limites doivent être entre les morceaux. Mes arguments peuvent être plus pédants qu'utiles, mais je doute toujours que le "toujours" dans "améliore toujours la lisibilité".
Steve314
@ Steve314: Nous résumons, découpons et résumons toujours pour nous aider à comprendre les choses. Toujours. Couper, résumer, résumer («simplifier») est quelque chose que nous faisons toujours. Nous faisons juste. C'est ainsi que nos cerveaux appréhendent la réalité. La simplification améliore toujours la lisibilité et peut toujours être effectuée.
S.Lott
Oui. Je n'ai jamais dit le contraire.
Steve314
-2

Les questions me rappellent cette réponse sur Stack Overflow, en particulier cette citation (substituer la qualité à la simplicité):

Qualité - vous savez ce que c'est, mais vous ne savez pas ce que c'est. Mais c'est contradictoire. Mais certaines choses sont meilleures que d'autres, c'est-à-dire qu'elles ont plus de qualité. Mais quand vous essayez de dire quelle est la qualité, à part les choses qui en ont, tout va pouf! Il n'y a rien à dire. Mais si vous ne pouvez pas dire ce qu'est la qualité, comment savez-vous ce qu'elle est, ou comment savez-vous qu'elle existe même? Si personne ne sait ce que c'est, alors à toutes fins pratiques, cela n'existe pas du tout. Mais à toutes fins pratiques, il existe vraiment. Sur quoi d'autre les notes sont-elles basées? Sinon, pourquoi les gens paieraient-ils des fortunes pour certaines choses et en jetteraient d'autres dans la poubelle? Évidemment, certaines choses sont meilleures que d'autres - mais quelle est la `` amertume ''? - Alors tour à tour tu vas, faire tourner les roues mentales et ne trouver nulle part où obtenir de la traction. Qu'est-ce que c'est que la qualité? Qu'Est-ce que c'est?

Je pense qu'il est important de garder à l'esprit qu'une norme de codification codifiée pour tous ses avantages ne fera pas des bons programmeurs des mauvais. Un mot comme «simple» peut être interprété différemment par différentes personnes (voir la réponse d'Aidan Cully), mais ce n'est peut-être pas une si mauvaise chose. Les programmeurs juniors devront toujours faire réviser leur code par des programmeurs seniors et savoir pourquoi l'interprétation des programmeurs seniors de «simple» est meilleure que la leur.

KaptajnKold
la source
1
C'est pourquoi j'ai défini la simplicité dans la question.
Richard
-2

Un appel de fonction par ligne est plus simple? Essayons un exemple!

=== One call per line ===
x = y.getThis()
a = x.getThat()
b = a.getSomethingElse()

=== Less "simple" version ===
b = y.getThis().getThat().getSomethingElse()

Qu'est-ce que tu penses? Un appel par ligne est-il réellement plus simple?

Stephen Gross
la source
Oui. Un appel par ligne est plus simple et plus facile à lire pour moi. Cependant, la lisibilité est subjective. (En outre, cela ne vient même pas près de répondre à la question.)
Richard
Bonjour Stephen, pouvez-vous expliquer comment vous pensez que cela répond à la question? Ce que vous essayez de souligner ici n'est pas clair.
@MarkTrapp Aucun problème. La question initiale proposait une approche à fonction unique par ligne. L'exemple que j'ai publié montre les deux mêmes extraits de code, l'un implémenté en tant que fonction unique par ligne, l'autre en tant qu'appels de méthode chaînée. Je pense que l'appel chaîné est beaucoup plus facile à lire: court, dépourvu de variables temporaires inutiles et élégant.
Stephen Gross
Si vous devez enchaîner des getters, votre code est conçu pour la piscine
Hiver