La complication du C ++ est inévitable. Et pas seulement C ++

J'ai longtemps voulu écrire un texte similaire, mais mes mains n'ont pas atteint. Mais après la réunion d' été du Comité de normalisation C ++ qui s'est terminée et le hurlement que la complexité du langage a augmenté encore plus, j'ai dû trouver le temps et fixer mes propres réflexions sur ce sujet.


Il y aura beaucoup de texte, donc ceux qui ne sont pas désolés pour leur temps, je vous invite à regarder sous le chat.


Le langage de programmation est un produit technologique, mais pas si simple


Il y a quelque temps, j'ai eu l'occasion de lire un livre intéressant, The Innovator’s Dilemma . Là, avec des exemples de produits de haute technologie, on montre comment de nouveaux produits émergent qui perdent d'abord les décisions qui dominent actuellement le marché, puis changent radicalement l'état du marché.


L'un des exemples les plus frappants: la photographie numérique, qui était complètement absente dans les années 1990, mais seulement 20 ans plus tard a conduit à l'effondrement d'un monstre du XXe siècle comme Kodak (qui, soit dit en passant, a été le premier à fabriquer un prototype d'appareil photo numérique).


image

Un autre exemple proche des développeurs est l'évolution des disques durs. Des monstres lourds de l'époque des ordinateurs centraux et des mini-ordinateurs, aux petits modèles de 3,5 "et 2,5", puis aux SSD au format M.2 et câblés directement à la carte eMMC.


image

La même chose avec les disquettes, qui ont d'abord atteint 3,5 ", puis ont disparu en tant que classe sous la pression des lecteurs flash USB.


image

Un autre exemple de notre domaine professionnel est le développement des ordinateurs personnels. Qui au départ n'étaient pas en mesure de rivaliser avec les "vrais" ordinateurs du milieu des années 70. Et puis ils ont juste détruit les mini-ordinateurs en classe. Ensuite, ils ont conduit à l'émergence de serveurs modernes, rappelant quelque peu les mini-ordinateurs d'alors. Et maintenant, les PC eux-mêmes disparaissent de la consommation de masse sous l'influence des ordinateurs portables, des tablettes et des smartphones.


image

Les auteurs du livre déclarent que les événements dans tous ces cas se développent selon le même scénario:


  • Premièrement, il existe un besoin pour un produit qui résout un problème particulier. Disons un disque magnétique flexible;
  • étant donné qu'au stade initial toutes les solutions concurrentes (dont, en principe, peu nombreuses) sont basées sur les mêmes technologies, le marché est divisé entre des produits plus ou moins similaires;
  • les fabricants de produits à succès commencent à se faire concurrence et, dans cette compétition, amènent leurs produits presque au rapport qualité-prix le plus favorable. Et, plus important encore, alors que les produits existants sont aussi cohérents que possible avec les vues sur la façon dont les tâches pour lesquelles ces produits sont destinés à être traités. En gros, tout le monde sait que les disquettes 8 "sont excellentes pour transférer des informations d'un mini-ordinateur à un autre à l'aide de disquettes. Et personne d'autre ne peut imaginer une autre manière dans le courant dominant;
  • quelque part en marge, sur la base de nouvelles découvertes / matériaux / technologies, un nouveau produit apparaît qui est sensiblement inférieur aux produits existants à presque tous les égards. Généralement plus cher. En règle générale, pas de capacités / capacités comparables. Mais il a une qualité très importante: il peut être utilisé là où il est impossible ou difficile d'appliquer des solutions traditionnelles. Par exemple, vous ne pouvez pas brancher un lecteur 8 "sur un ordinateur personnel. Mais les propriétaires de PC ne sont pas intéressés par le transport de disquettes 8". Ce n'est tout simplement pas pratique. Alors que la disquette 5,25 "est tout à fait pour elle-même. Et ne vous en souciez pas, au prix d'un kilo-octet, la disquette 5,25" était à l'origine plus chère que 8 ".
  • Un nouveau marché s'est formé autour du nouveau produit, ce qui n'était initialement pas du tout intéressant pour les fabricants de produits traditionnels. Mais comme il s'agissait d'un nouveau marché, de nouveaux acteurs s'y sont précipités, ce qui a créé une concurrence sérieuse les uns pour les autres. Et cette compétition a rapidement traduit une technologie marginale et inefficace en une technologie extrêmement efficace. Ce qui a vite cessé d'être marginal, car dès qu'il a dépassé les anciens produits grand public en termes de totalité, il les a rapidement remplacés dans leur propre niche. En gros, s'il y a des centaines de milliers de lecteurs 5,25 "et des millions de disquettes 5,25", quel est l'intérêt de conserver les périphériques 8 "beaucoup plus marginaux pour le moment?

Les langages de programmation comme produits technologiques


À première vue, des analogies similaires peuvent être observées dans la manière dont les langages de programmation sont devenus courants. Et les exemples les plus frappants sont peut-être les langages Java et Go.


Le langage Java est né d'une tentative de création d'un «C ++ approprié». Mais la langue qui en résulterait ne serait presque pas nécessaire à quiconque, car il était très misérable et, plus important encore, lent et gourmand. Sur le bureau d'alors, même compte tenu de la croissance rapide de la puissance des PC à cette époque, Java n'avait aucune chance.


Cependant, Java est entré sur le «marché» dans une perspective complètement différente, à travers une niche dans laquelle personne ne pouvait vraiment travailler alors: via Internet et les applets de navigateur (tout était un peu plus compliqué et il y avait encore un marché pour les applets JavaCard et STK, mais nous ne partirons pas dans la nature). Internet était un sujet très chaud, et puis il n'y avait tout simplement rien à faire des sites / pages dynamiques (JavaScript est apparu après l'annonce de Java). Et, comme il n'y avait rien à utiliser à part Java, Java a commencé à être utilisé. Eh bien, puis, en développant et en surmontant les maladies infantiles, Java est allé dans d'autres domaines, évincant ainsi d'autres technologies. Bien que dans le même bureau, elle ne pouvait pas se mordre une part importante du gâteau.


Le langage Go ne pouvait guère intéresser personne dans des niches traditionnelles où vivaient déjà le C, C ++, Java, C #, Python, Ruby, etc. Mais le développement de produits pour Internet a créé un autre créneau - les services RESTful. Pour le développement dont Java était une surpuissance, C ++ est trop compliqué et dangereux, Python / Ruby et d'autres dynamiques sont trop lents. Et maintenant l'un des plus misérables dans les termes expressifs des langages développés au 21e siècle devient presque une solution miracle pour ce créneau appliqué. D'où, peut-être, il se répandra ailleurs dans le temps (ce qui ne me surprendra pas personnellement étant donné le niveau général de qualification de la jeune génération de développeurs).


On a donc le sentiment que la programmation devrait être la même avec les langues qu'avec les autres produits technologiques: l'émergence de nouvelles langues conduit soit à une disparition presque complète, soit à évincer les langues précédentes dans des niches marginales distinctes. Dans le même temps, les anciennes langues, en cours de développement dans le cadre de l'environnement concurrentiel, deviennent plus puissantes et expressives pour des solutions moins chères à leurs tâches typiques. En conséquence, les anciennes langues deviennent de plus en plus volumineuses et complexes. Et moins attrayant pour une utilisation en dehors des niches qu'ils ont déjà occupées.


Il semble donc que le cycle de vie d’un produit technologique décrit dans le dilemme de l’innovateur devrait également s’étendre aux langages de programmation.


Mais tout n'est pas si simple avec les langages de programmation


Dans le schéma de pénétration de nouveaux produits technologiques sur le marché décrit dans le dilemme de l'innovateur, l'une des raisons les plus importantes pour les utilisateurs de passer des anciens produits traditionnels aux nouveaux est soit simplement une réduction significative du coût de possession ou l'acquisition d'opportunités précédemment disponibles + une diminution du coût de possession.


Disons que le développement des PC et la croissance de leur puissance rendent la possession d'une flotte de PC moins chère que la possession d'un ou plusieurs mini-ordinateurs. En conséquence, les disquettes de trois pouces sont moins chères par unité de capacité que 5,25 "(en tenant compte d'une plus grande fiabilité et d'autres facteurs). En conséquence, la photographie numérique est moins chère par image que par film. Et ainsi de suite.


Mais deux indicateurs plus importants sont associés à la transition d'un produit à un autre: c'est le coût / la complexité de la transition elle-même, ainsi que la vitesse à laquelle vous pouvez passer à un nouveau produit. Ces indicateurs peuvent être estimés en argent. Et si l'avantage de la transition vers un nouveau produit est présent, alors la transition est effectuée. Peut-être pas rapide, mais réalisé.


Et ici, il s'avère que le coût du passage d'un langage de programmation à un autre est beaucoup plus élevé que dans le cas du passage d'un mini-ordinateur à un PC, de 8 "disquettes à 5,25" ou de HDD à SSD. Depuis changer un langage de programmation est généralement une réécriture complète d'un produit logiciel. Souvent à partir de zéro.


Et que signifie la réécriture? Salaire d'une nouvelle équipe de programmeurs, qui devra répéter les fonctionnalités déjà disponibles dans le produit. Et même si le nouveau PL vous permet de diviser par deux la taille de l'équipe, cela entraînera quand même des coûts importants. Car si 10 millions de dollars ont été dépensés pour développer l'ancienne version du produit, la réécriture nécessitera au moins 5 millions de dollars.


Mais, plus important encore, c'est que le produit réécrit n'apparaîtra pas immédiatement, immédiatement. Ça prend du temps. Beaucoup de temps. Encore une fois, si nous supposons que le nouveau langage vous permet d'écrire deux fois plus rapidement du code de travail, alors la réécriture du produit, dont le développement de l'ancienne version prenait 5 ans, ne prendra que 2,5 ans.


Il s'avère qu'en ce moment, vous devez commencer à investir beaucoup d'argent afin d'obtenir une copie de quelque chose qui fonctionne depuis longtemps et rapporte de l'argent maintenant.


Et un autre aspect de cette médaille doit être mentionné: si un produit logiciel est utilisé dans des conditions changeantes, alors le produit sera inévitablement finalisé ou traité pour répondre aux besoins modernes. Dans le même temps, l'entreprise n'a pas la possibilité d'attendre un an et demi, jusqu'à ce qu'une nouvelle version du produit apparaisse sur un nouveau PL, de nouvelles fonctionnalités, en règle générale, sont nécessaires dans un avenir prévisible. Souvent, hier.


Par conséquent, lors de la réécriture, les dépenses augmentent: vous devez écrire une nouvelle version en même temps et développer l'ancienne.


À mon avis, c'est précisément ce qui explique pourquoi de nouveaux langages sont "tirés", principalement dans le développement de nouvelles applications pour un nouveau créneau d'applications. Mais évincer les anciennes langues des zones précédemment occupées est déjà beaucoup plus lent. Fortran et Cobol peuvent probablement être considérés comme les exemples les plus frappants. Non seulement le logiciel qui y est écrit est toujours en fonctionnement, mais ils continuent à écrire du nouveau code dans ces langues. Et ces langues elles-mêmes évoluent.


Et il me semble que l'un des pires rêves des propriétaires de produits logiciels en Cobol est de réécrire le produit en Java ou en C #;)


Et un autre facteur important: le développement de l'informatique elle-même


Un autre point sur lequel je voudrais attirer l'attention est le fait que l'informatique existe il n'y a pas si longtemps et que l'histoire de l'évolution des langages de haut niveau est encore plus courte. Il est peu probable que la première partie de cette histoire nous fournisse un soutien solide pour notre discussion sur la façon dont certaines langues remplacent d'autres. Les années 1950 et 1960 ont été des années d'expérimentation. De plus, les années où le marché informatique lui-même était segmenté et une partie importante du logiciel était écrite pour des ordinateurs et des systèmes d'exploitation spécifiques, sans exigences particulières de portabilité. Le nombre de développeurs de logiciels existants, ainsi que l'éventail des domaines dans lesquels les ordinateurs sont largement utilisés, ne peuvent être comparés à la situation actuelle.


À mon humble avis, les choses ont fondamentalement changé dans les années 70 et, depuis les années 80, nous avons assisté à l'émergence d'armes nucléaires, qui reposent déjà à la fois sur l'expérience pratique du passé et sur les résultats d'études théoriques. Quant à moi, ce sont précisément les années 80 (et peut-être la fin des années 70) qui marquent le début de l'ère des langages de programmation destinés à la fabrication de logiciels à l'échelle industrielle. Car c'est ici que nous voyons Modula-2, SmallTalk, Ada, C ++, Eiffel, extensions d'objets de Pascal, Objective-C, Perl.


Je vais donc m'éloigner davantage de ce qui est apparu à l'ère des armes nucléaires industrielles.


Au fait


En énumérant les langages apparus dans les années 80, je me suis souvenu du PL développé par Niklaus Wirth: d'abord Pascal, puis Modula / Modula-2, puis Oberon.


Par l'exemple de ces langues, on peut voir comment l'expérience de leur auteur conduit à l'apparition d'outils qui prennent en compte les lacunes des tentatives précédentes, tout en répondant aux nouvelles exigences de leur temps.


Mais ces mêmes langues montrent également combien il est important pour les utilisateurs de YaP de rester dans le cadre de la langue une fois choisie. La transition de Pascal à Modula-2 a été. Mais en aucun cas massif. Et, malgré le fait que Modula-2 était plus ou moins activement utilisé, il n'est pas devenu aussi populaire que les héritiers de Pascal, en particulier Delphi. Et il n'y a eu aucune transition observable à Oberon, pour autant que je m'en souvienne.


Le langage de programmation populaire ne peut pas simplement être remplacé. Et ça?


Ainsi, le message principal de mon raisonnement précédent est que si un langage a trouvé une utilisation plus ou moins répandue et avec son aide, de nombreux logiciels divers utilisés quotidiennement ont été créés, alors ce langage ne peut pas simplement être complètement remplacé par d'autres langages de programmation. Surtout en peu de temps.


Les langages de programmation réussis sont voués à continuer d'être utilisés pendant des années. Et le plus susceptible d'évoluer.


Et l'évolution d'un langage de programmation implique l'expansion du langage avec de nouvelles fonctionnalités. Ce qui est inévitable, car les progrès ne s'arrêtent pas. Les gens trouvent des moyens plus pratiques de résoudre les problèmes connus. Face à de nouvelles tâches, qui nécessitent des capacités expressives supplémentaires des langages de programmation. Et, comme le langage de programmation n'est qu'un outil, les gens s'orientent vers l'amélioration de leur outil.


Ce qui signifie que les langages de programmation largement utilisés sont simplement voués à devenir de plus en plus volumineux et plus complexes, au cours de leur développement, acquérant des opportunités qui n'étaient même pas discutées au départ.


En principe, Bjarn Straustrup en a parlé il y a longtemps. Et même ce que j'observe moi-même depuis près de trente ans confirme les propos de Straustrup. Disons que le Java moderne est déjà très différent de Java 1.0 de 1995. Le langage C # démontre une évolution encore plus impressionnante d'un clone réussi du premier Java à peut-être le langage traditionnel le plus expressif adapté aux programmeurs hindous (quelle que soit leur nationalité).


Mais l'exemple le plus frappant pour moi reste la langue Go. Ce que, déjà au 21e siècle, ils ont commencé à faire en jetant délibérément un tas de choses qui ont fait leurs preuves au cours des décennies d'utilisation généralisée dans différentes matières nucléaires. Et qui grâce, y compris cela, est devenu populaire. Mais, néanmoins, la vie fait des ravages et Go est obligé d'ajouter quelque chose que les auteurs ont initialement refusé intentionnellement - des outils de programmation généralisée (alias modèles / génériques) .


Les langages de programmation les plus populaires évoluent vers l'extension de leurs capacités. Et cela signifie des complications. Étant donné que de nouvelles fonctionnalités doivent être ajoutées afin de ne pas casser sérieusement le code déjà écrit. Car l'histoire épique avec Python des deuxième et troisième versions est devenue un bon exemple, que peu osent répéter.


C'est si mauvais?


Le côté négatif de la complexité toujours croissante des langages de programmation (en particulier un langage tel que C ++) semble évident: le seuil d'entrée est trop élevé. Il faut consacrer trop de temps à l'apprentissage d'une langue pour commencer à émettre un code de qualité acceptable dans un délai acceptable. Ce qui rend le développement dans un langage de programmation complexe à la fois coûteux et risqué. Que se passe-t-il si un ou plusieurs développeurs qualifiés quittent le projet? À quel point sera-t-il rapide et facile de trouver un remplaçant? Des questions difficiles.


D'autre part, puisqu'un langage de programmation est le même outil pour enregistrer les intentions d'une personne particulière, comme, par exemple, les expressions mathématiques, il convient de faire une analogie avec les mathématiques.


À l'école, nous commençons à étudier les mathématiques en commençant par les opérations arithmétiques les plus simples. Ensuite, nous passons à des choses plus complexes: les fractions, les degrés et les racines. Ensuite, nous allons plus loin, vers les logarithmes. Ensuite, nous prenons un petit calcul intégral. De même pour la géométrie.


En conséquence, un diplômé d'un lycée normal possède un certain appareil mathématique, qui peut bien être redondant pour une seule personne. Je ne me tromperai pas si je suppose que beaucoup après l'école n'ont jamais eu besoin de calculer quoi que ce soit à l'aide de logarithmes ou de prendre des intégrales.


Néanmoins, l'appareil mathématique, qui est maîtrisé au lycée, ne peut être comparé au fait que les étudiants universitaires suivront ensuite des cours de mathématiques supérieures. Surtout s'il s'agit d'un étudiant d'une faculté mathématique ou physique (et non seulement télécharger sérieusement des mathématiques supérieures dans de nombreuses spécialités).


Mais après tout, personne n'a l'idée de blâmer les mathématiques du fait que plus vous y plongez profondément, plus c'est difficile. Puisque si une personne est confrontée à un domaine d'activité où elle a besoin de TFKP, alors rien ne peut être fait, TFKP devra étudier. Aussi difficile que cela puisse être. Eh bien et oui, il est normal que tout le monde ne réussisse pas.


En fait, la même chose avec les langages de programmation.


Si vous devez résoudre des problèmes relativement simples, vous avez le choix: soit vous utilisez un langage de programmation plus simple, soit vous utilisez un sous-ensemble limité d'un langage plus complexe. Mais si vous êtes confronté à une tâche difficile (ou à des conditions spécifiques pour sa solution), alors vous n'avez peut-être pas du tout le choix: la complexité de la résolution de ce problème dans un langage «simple» peut être trop grande.


En parlant de tâches


, (.. , , , .., ..), , .


. , .. , . , , . , , , . , , , .


, , Go, Python, Ruby PHP, , , , . , , , , . .


, , , , . , 25 GUI , . , 25 .


, , , . , / , , .


, , , , , C++, Scala Haskell. , , . , , Go C.


. . , , : , , . , - C++, . .., -, C++ . , -, C++ , , .


Total


, ? :


  • -, . , , , « », 1960-1970- , . , . , . ( ). - X, , X . , C. , . . , — . ;
  • -, , 40 , . , , . , .. , , ;
  • -, . - Ruby/Python, - Go, - Java. - Rust-, C++, Scala Haskell-. , . - , « », . .

, , - : , - . - . , ( , , ). , - , , : , , -. ;)

Source: https://habr.com/ru/post/fr463745/


All Articles