J'ai vu beaucoup de gens se plaindre de la verbosité dans les langages de programmation. Je trouve que, dans certaines limites, plus un langage de programmation est verbeux, mieux il est à comprendre. Je pense que la verbosité renforce également l'écriture de API
s plus clairs pour cette langue particulière.
Le seul inconvénient auquel je peux penser est que cela vous fait taper plus, mais je veux dire, la plupart des gens utilisent des IDE qui font tout le travail pour vous.
Alors, quels sont les inconvénients possibles d'un langage de programmation détaillé?
"Verbose" signifie "utilise trop de mots". La question est de savoir ce qu'est "trop".
Un bon code doit être facile à comprendre en un coup d'œil. C'est plus facile si la plupart des caractères servent directement le but du code .
Si une langue est verbeuse, une plus grande partie de votre code est du bruit. Comparer "Hello World" de Java :
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
... avec Ruby:
print "Hello World!"
Le bruit gaspille l'énergie mentale.
D'un autre côté, une lacune excessive dans une langue coûte également de l'énergie mentale. Comparez ces deux exemples de Common LISP :
(car '(1 2 3)) # 3 characters whose meaning must be memorized
# vs
(first '(1 2 3)) # 5 characters whose meaning is obvious
Cela affecte la quantité de code que vous pouvez voir et analyser en un seul coup d'œil
x++
Plutôt que set(x,Integeradd(get(x),1))
ps. Ce n'est pas seulement une question de lecture de code. À l'époque des écrans 40x25, les langages de type APL, ou Perl, étaient utiles sur Cobol ou Fortran pour la quantité de code que vous pouviez lire/page. Mais maintenant, il s'agit plus de votre propre cache interne - si une instruction a un seul opérateur, il est plus facile pour mon cerveau vieillissant d'analyser qu'un avec 3 symboles et 4 appels de fonction.
Si la verbosité du langage nuit à la lisibilité du code, alors c'est mauvais.
Certains langages ont une syntaxe tellement verbeuse que saisir le sens du code prend plus de temps (je pense à VB.NET par rapport à C #):
If something Then
End If
if(something)
{}
Cela se résume vraiment à ce qu'un codeur est familier et à l'aise.
Allez voir AppleScript , l'un des langages les plus verbeux que je puisse penser qui pourrait être considéré actuel, essayez de écrire quelque chose de trival in et revenir et essayer de faire valoir que la verbosité est un bon trait dans une langue.
Essayer de se souvenir de toute la sémantique de l'endroit où vont les mots-clés et de ce qu'ils sont n'est pas anodin si vous ne le faites pas tous les jours.
Il suffit de regarder tout le bruit de mot-clé dans cet exemple trivial:
tell application "Finder"
if folder "Applications" of startup disk exists then
return count files in folder "Applications" of startup disk
else
return 0
end if
end tell
accorder la même chose dans bash
avec les outils Unix traditionnels serait concis mais cryptique pour la plupart des utilisateurs OSX, donc il y a un équilibre à trouver.
Je pense que vous devez tourner la question sur sa tête et demander: Pourquoi certaines personnes pensent-elles que le code laconique est bon?
Ma réponse serait qu'il y a deux raisons fondamentales:
Raisons pour lesquelles Terse peut être meilleur
Il s'agit notamment d'être plus lisible, de la même manière qu'une courte phrase peut être plus compréhensible qu'une phrase fleurie et verbeuse. Souvent, les langages de programmation qui tentent d'imiter la grammaire de la langue anglaise finissent par être horriblement longs, nécessitant d'énormes quantités de code pour effectuer les actions les plus simples. Souvent, vous constaterez que plus une langue émule une langue écrite, plus il est difficile de l'amener à effectuer des opérations logiquement complexes.
Raisons pour lesquelles Terse peut être pire
Certaines langues (et je pense à Perl) utilisent un tableau de symboles étranges, qui semblent avoir été sélectionnés de façon presque arbitraire, dans le cadre de leur syntaxe. Pour ceux qui ne connaissent pas ces hiéroglyphes, la langue devient alors impénétrable. Il devient également facile de faire des fautes de frappe qui ne sont pas facilement visibles. Les expressions régulières incarnent peut-être ce genre de lacune.
De plus, certaines personnes aiment se montrer en écrivant du code laconique parce que, franchement, elles pensent que cela les rend intelligentes. Vous le voyez parfois sur StackOverflow, où les gens soumettent souvent des réponses extrêmement compactes au détriment de la lisibilité. C'est une sorte d '"impressionnez vos pairs" avec tout ce que vous savez de la philosophie, mais les bons programmeurs réalisent que " code golf " n'est pas le moyen de créer un logiciel maintenable.
@frowing, je dirais qu'une façon d'examiner le problème de la verbosité est de réaliser que la programmation est toujours un mélange de deux styles plutôt différents de recherche et d'expression d'une solution.
Le premier style, plus verbeux, est la programmation linguistique (linguistique). Ce style combine des mots semblables à des noms et des mots semblables à des verbes dans des structures similaires à des phrases, et il est destiné à être lu et compris de la même manière qu'un paragraphe bien écrit. La programmation linguistique est le style de programmation le plus universel puisque le langage lui-même est universel. Pour cette même raison, le support de programme à long terme a toujours besoin d'une puissante composante linguistique, car la première chose qu'un nouveau programmeur recherchera est une compréhension conceptuelle de ce qui est fait. En règle générale, plus vous vous éloignez du contexte dans lequel vous avez créé un programme, plus un style linguistique de programmation sera important pour garantir que vos hypothèses et concepts ne seront pas mal compris par la prochaine personne essayant de comprendre votre code. . Votre propre exemple d'utilisation d'un style de programmation plus linguistique pour réduire l'ambiguïté dans les API est un bon exemple de ce principe.
Le deuxième style, plus concis, est la programmation mathématique (mathématique). Ce style de raisonnement repose également sur le langage, car par exemple les variables sont analogues aux noms et les opérateurs aux verbes. Cependant, le raisonnement mathématique exploite la capacité étonnante et hautement parallèle de notre cerveau à effectuer des transformations spatiales complexes sur des objets qui se trouvent dans notre champ de vision. En représentant les noms et les verbes sous forme de symboles distinctifs compacts qui peuvent être organisés en objets imaginaires bien structurés - des équations - nous pouvons ensuite utiliser nos capacités visuelles hautement parallèles pour effectuer des rotations, des remplacements, des mouvements, des inversions et d'autres transformations sur ces imaginaires objets. Le résultat est une énorme amplification du nombre de cas que nous pouvons traiter simultanément, car chaque symbole peut représenter des classes entières d'objets étroitement liés.
Notez que pour appliquer efficacement le traitement visuel, vous devez garder votre objet imaginaire aussi similaire que possible en taille et en fonctionnalités à un objet réel. Si le champ de vision nécessaire devient trop large, ou si les symboles ne peuvent pas être utilisés comme des marques mobiles sur un objet, ou si vous devez "lire des lettres" et les convertir en mots, la capacité à effectuer des transformations complexes de manière fiable diminuera rapidement même pour un très bon mathématicien.
C'est pourquoi les gens plongés profondément dans le style mathématique de la programmation peuvent devenir gravement mécontents si une équation est étalée et exprimée dans ce qu'ils appellent un style linguistique "verbeux". Ce n'est pas parce que l'équation a été modifiée de manière significative, c'est parce que la diffuser ainsi peut rendre pratiquement impossible de lui appliquer un style visuel de compréhension. Pourtant, en même temps, un nouveau programmeur qui n'est pas du tout familier avec les symboles courts est susceptible de préférer une version plus verbeuse qui fournit plus d'informations linguistiques pour comprendre initialement ce que fait le code.
Alors que recommanderais-je?
Utilisez les deux styles, mais faites très attention à pourquoi vous utilisez chaque style.
Par exemple, tout ce qui a une chance de s'interfacer avec le monde extérieur devrait être intensément verbeux à un certain niveau, même si ce n'est que sous la forme de commentaires en ligne mélangés avec le code, et devrait également inclure des vérifications automatisées pour une utilisation correcte. Les notations cryptiques et surtout incomplètement définies n'ont rien à voir avec de telles interfaces, car il est presque certain qu'elles seront mal comprises à un moment donné. Le perte de Mars Climate Obiter en 1999 en raison d'un échec à reconnaître si les unités d'interface logicielle étaient exprimées en livres ou en newtons est un exemple particulièrement pointu des dangers de se fier trop nonchalamment aux chiffres bruts du logiciel ou du matériel. interfaces.
Inversement, toute forme de programmation profondément algorithmique et mathématique est une bonne programmation succincte candidate qui prend en charge le style mathématique de raisonnement. Si quelqu'un de nouveau doit conserver un tel code, il serait généralement préférable pour lui d'apprendre les notations mathématiques au lieu d'essayer de transformer le code en formes plus verbeuses. Il devrait bien sûr y avoir à tout moment une documentation facilement disponible pour expliquer les parties mathématiques du code à la disposition de ces développeurs, mais c'est un problème distinct.
Entre ces extrêmes se trouvent de nombreux cas où le programmeur a une discrétion considérable. Je suggérerais d'examiner comment le code sera maintenu à long terme et d'essayer de répondre aux besoins des personnes les plus susceptibles de maintenir le code à long terme.
Un certain nombre de personnes ont fait allusion à quelque chose qui, selon moi, devrait probablement être énoncé explicitement.
La verbosité tend à favoriser la compréhension au niveau microscopique - elle conduit généralement à une déclaration individuelle facile à lire et à comprendre. La verbosité tend également à réduire le degré de familiarité avec la langue nécessaire pour la comprendre (au moins dans une certaine mesure). Les langues les plus verbeuses (par exemple, COBOL) peuvent être au moins quelque peu lisibles même par des non-programmeurs complets.
La concision tend vers le contraire: elle aide à comprendre au niveau macroscopique, en particulier par les programmeurs ayant la connaissance la plus intime de ce langage particulier. Dans le même temps, le manque de familiarité avec ce langage spécifique peut empêcher une compréhension même rudimentaire, même de la part de programmeurs qui sont par ailleurs assez expérimentés.
En tant que telle, la lisibilité varie considérablement en fonction du public cible. D'une part, considérons un grand projet complexe écrit et maintenu par des personnes qui travaillent presque exclusivement sur ce projet, dont la plupart ont une formation et une formation substantielles (par exemple, de nombreux doctorants). Cela tendra à privilégier un langage plus concis.
À l'extrême opposé, considérons un projet beaucoup plus simple (mais peut-être encore assez important) qui est principalement géré par des personnes qui se spécialisent vraiment dans les affaires associées au logiciel, plutôt que dans le logiciel lui-même. Cela favorisera presque certainement une langue beaucoup plus verbeuse.
Plutôt que d'aller dans un livre technique, je reviens aux Elements of Style * de Strunk and White. Le concept sous-jacent est "Soyez précis" et "Ne dites pas plus que nécessaire". Tout le reste est un commentaire.
Appliqué à la programmation, il s'agit d'être très précis, mais de ne pas avoir de peluches inutiles. Le fluff supplémentaire peut être de la syntaxe, mais il peut également y avoir plus de mots que nécessaire pour transmettre un sens. (Bien sûr, pas trop peu pour permettre l'ambiguïté non plus)
À la fin de la journée, tout ce qui est "différent" fera hurler les gens. Je suis à l'aise avec la syntaxe de style C et donc ok avec d'autres langages qui partagent une syntaxe similaire (C++, Java, C #). J'ai donc tendance à privilégier ce style particulier.
Les langues ont tendance à trouver un équilibre entre suffisamment descriptif et non verbeux.
Perl est un exemple où vous pouvez écrire du code très concis. Pour les non-initiés, le code écrit par un ninja Perl n'est rien de moins que de la magie.
COBOL est un exemple de trop verbeux.
Einstein a bien compris: "Rendez les choses aussi simples que possible, mais pas plus simples."
Cela s'applique également au code. Si vous pouvez simplifier le code en supprimant les éléments répétitifs et inutilement verbeux, c'est une bonne chose.
De plus, certaines études de cas suggèrent que la productivité du programmeur mesurée en lignes de code est plus ou moins constante. Tout comme le nombre de bogues par LOC. Ainsi, le passage à un langage qui vous permet d'en faire plus par ligne de code peut être considéré comme une amélioration de la productivité, si toutes les autres choses restent égales.
Cela étant dit, il y a une tendance dans cette industrie à trop concevoir et compliquer ce qui devrait être des choses simples. Des choses simples comme le remplissage des coordonnées dans une base de données relationnelle. J'ai vu des solutions ridiculement compliquées et malavisées (toux MDA) pour ce problème particulier. Des langages comme Scala et Ruby sont de bons exemples d'outils puissants qui, entre les mains de certaines personnes, produisent un code inintelligible, trop compliqué et mal entretenu. Tout simplement parce que vous pouvez utiliser plusieurs niveaux d'indirection avec quelques touches clés ne signifie pas que vous devez décoiffer chaque ongle en vue avec ce marteau particulier.
Lorsqu'il est utilisé correctement, vous obtenez un code propre et agréable qui est à la fois court et facile à comprendre. Lorsqu'il est mal utilisé, vous feriez mieux de limiter la personne en question à l'utilisation de Visual Basic ou d'un langage similaire pour éviter d'autres dommages.
La véritable compétence réside dans la fabrication de choses complexes de manière simple, et non dans la fabrication de choses simples de manière compliquée.
J'ai lu quelque part une fois qu'une grande partie du débat verbeux vient des nouveaux programmeurs par rapport aux anciens. L'analogie utilisée était que lorsque nous apprenons quelque chose de nouveau, nous nous racontons une "histoire" pour la traverser (pensez au moment où vous avez appris l'algèbre en HS). Au fur et à mesure que nous acquérons de l'expérience, nous allons au-delà du besoin d'une histoire expliquant les composants individuels et nous en comprenons davantage. Notre code devient plus dense et plus concis, avec des commentaires expliquant uniquement les éléments nécessaires, au lieu de répéter ce que dit le code.
J'ai trouvé que c'était vrai entre moi et un collègue. Elle écrit du code avec beaucoup de commentaires expliquant quelles sont les lignes de code et beaucoup d'espace blanc. Si je le lis, je trouve que je ne peux tenir que quelques lignes de code sur un écran à cause de cela. Cela rend la compréhension de chaque ligne individuelle beaucoup plus facile, mais il est beaucoup plus difficile de bloquer toute la fonction.
J'ai tendance à écrire du code sans espace ni commentaires supplémentaires. Cela permet de voir le tout beaucoup plus facilement, mais vous devez simplement pouvoir "obtenir" les "mots" du code individuel. Si vous essayez de lire cette réponse avec chaque mot sur sa propre ligne, avec beaucoup d'espaces/commentaires/verbiage supplémentaire, il serait beaucoup plus facile de comprendre chaque mot individuel, mais beaucoup plus difficile de comprendre l'ensemble.
Quelque chose que personne d'autre n'a touché est dans la quantité de code que vous pouvez insérer sur un seul écran. Cela aide pour plusieurs raisons:
La verbosité étant une tendance à utiliser de grandes quantités de texte, et la concision à utiliser très peu de texte ...
La verbosité est mauvaise car:
Un certain niveau de verbosité est cependant essentiel pour la clarté ...
n niveau minimal de verbosité est bon car:
De merveilleux exemples de commandes trop laconiques pour de nombreuses personnes incluent les anciens standbys BASIC de val(x$)
, str$(x)
et chr$(x)
... retournent un nombre à partir de sa représentation sous forme de chaîne , renvoie une chaîne pour un nombre et renvoie un seul caractère ayant la valeur ascii x comme chaîne.
Ou le pointeur C/C++ et par les opérateurs de référence &
et *
par rapport au mot clé BASIC byref
. En C/C++, je peux avoir une variable X, et passer un pointeur vers cette variable, mais je dois me rappeler quel est le pointeur et quel est le "utiliser le pointeur comme variable vers laquelle il pointe"; en base, je passe simplement la référence avec un mot-clé byref dans l'appel de fonction, qui est plus clair, mais moins flexible:
def fn Foo(x byref as float) foo= (x += x+1)
...
Foo(x)
Dans ce code, le contenu de x est modifié en raison de l'indicateur byref. Certaines saveurs autorisent le byref à l'appel, d'autres dans la définition, certains dans les deux.
La verbosité est importante pour que les programmeurs occasionnels puissent utiliser le symbolisme plus facilement; BASIC ou python sont plus lisibles par l'homme et plus verbeux que C/C++, et donc beaucoup plus utiles pour les programmeurs occasionnels; la lourdeur de C/C++ le rend beaucoup mieux pour les programmeurs plus expérimentés, qui ont besoin pour voir plus de code et de code plus complexe sur un écran, mais ont dû apprendre les différentes conventions de structure symbolique. À l'extrémité est APL, qui est presque complètement illisible par l'homme.
Un problème intimement lié est la clarté - le code laconique est souvent peu clair, et le code excessivement verbeux (comme dans AppleScript) peut être tout aussi peu clair. La familiarité avec un langage donné augmente la clarté du code laconique au sein de ce langage - un débutant brut, confronté au code C++ est susceptible de ne pouvoir analyser que les formules, et même beaucoup de BASIC fonctionnel ou Python code est trop laconique pour être compris, mais AppleScript peut être déconcerté, en général, sans avoir recours à des dictionnaires de langue. Le moins clair que j'ai rencontré sans obscurcissement intentionnel est Inform 7 ...
Autrefois
Une autre considération importante dans le passé, mais qui n'est plus aussi importante pour le codeur amateur, est l'espace de fonctionnement et de stockage. (C'est toujours vital dans le haut de gamme.) En gardant à l'esprit que de nombreux langages ont été interprétés, en particulier les saveurs BASIC, et que beaucoup d'autres ont été compilés au moment de l'exécution, l'espace de code était important, surtout lorsque les disques ne contenaient que 128 Ko et les cartes perforées individuelles seulement 80 B.
Plusieurs solutions existaient - la tokenisation était extrêmement courante en BASIC; les mots clés de langue individuels ont été réduits à un mot de 1 ou 2 octets dans les 128 caractères supérieurs ou dans l'espace de caractères de contrôle. La tokenisation conduit également à une compilation de bytecode (comme dans Inform et la Z-Machine).
La compilation et la liaison de plusieurs fichiers objets ont également été utilisées pour contourner les limitations d'espace. Une section de code Pascal de 100 Ko peut se compiler à seulement 5 Ko; en liant plusieurs fichiers compilés, on pouvait créer des applications massives sans avoir accès à des disques de grand format (en se souvenant que 10 Mo étaient incroyablement volumineux et acheter une nouvelle voiture chère).
Des langages plus laconiques, cependant, ont obtenu plus de code dans un bloc donné de disque et de RAM, et ont donc compilé des blocs plus gros à la fois. Gardant à l'esprit: les "mini-ordinateurs" du début des années 1970 ne pouvaient avoir que 64 Ko de RAM (le Honeywell 800 avait une installation de base de 4 banques de 2048 mots de 8B chacune). L'APL et les langages symboliques similaires ont approché 1B par instruction plus ses opérandes, contre les 3B-10B beaucoup plus grands par instruction plus les opérandes. (C'était un cauchemar de taper sur des cartes perforées, d'autant plus que les symboles étaient essentiellement une police sur type-ball, et de nombreux cardpunches n'avaient pas les symboles sur les touches ...)
Gardez également à l'esprit que les cartes ne peuvent pas être effacées ... et de nombreux programmes ont été entrés sur des cartes. Bien qu'il ne soit pas individuellement cher, plus votre code pourrait être compressé sur la carte, moins vous en aurez besoin, et plus les programmes seront gros, ou moins chers. Cela fait partie de la raison pour laquelle BASIC a une concaténation de plusieurs instructions par ligne dans la plupart des versions - il a été introduit pour économiser sur les cartes perforées. (Ou du moins, dit mon texte de programmation Vax Basic.) Bien que je n'ai pas programmé de lecteur de carte, j'ai fait le poinçonnage de la carte pour un Honeywell 800 en FORTRAN, BASIC, APL et quelques autres langages hautement symboliques.
Habituellement, les gens préfèrent les langues lisibles/verbeuses aux langues cryptiques/laconiques. Cependant, je pense que la plupart des gens ont assimilé "verbosité" à "fouillis", ce qui n'est pas la même chose.
Par exemple: while(<>){print if($.==2 || $& && !$x++); $.=0 if (/^--+$/)}
est une déclaration très laconique. Il contient tout ce que vous voulez savoir. Cependant, en raison de sa lacune, il est difficile à comprendre. D'un autre côté, une version légèrement plus verbeuse du même programme serait assez simple à comprendre car elle est plus lisible. Ce n'est bien sûr pas une propriété du langage en soi, mais certains langages ont tendance à être plus verbeux tandis que d'autres ont tendance à être plus concis dans leur manière de programmer.
À l'autre extrême de la verbosité, il y a http://en.wikipedia.org/wiki/Literate_programming , que je considère comme un concept assez intéressant.
Un autre aspect est la "verbosité indésirable", également appelée "fouillis". Choses que vous devez ajouter pour des raisons techniques, manque de sucre syntaxique, API gonflées, etc.
Je pense qu'une syntaxe claire et intuitive est très importante. Il doit également être suffisamment verbeux pour faciliter une lecture facile. Des déclarations trop courtes et trop logiques peuvent souvent donner plus de temps pour déchiffrer que leurs homologues légèrement plus longues. D'un autre côté, un code gonflé inutile rempli de lignes passe-partout pour faire quelque chose de très simple est également une nuisance.
Parce que plus de code signifie plus de temps de développement et plus de bugs.
Si vous écrivez 100 lignes de codes plutôt que 300 lignes de codes. Cela signifie près de 1/3 des temps de développement dont vous avez besoin et 1/3 des bugs potentiels que vous pourriez rencontrer.
Dans la plupart des cas, vous devez équilibrer l'efficacité et la concision, car écrire moins de codes signifie que la machine doit faire plus de choses et cela réduira l'efficacité.