I have long wanted to write a similar text, but my hands did not reach. But after the summer meeting of the C ++ Standardization Committee that ended and the howling that the complexity of the language increased even more, I had to find the time and fix my own thoughts on this subject.
There will be a lot of text, so those who are not sorry for their time, I invite you to look under the cat.
Programming language is a technological product, but not so simple
Some time ago I had the opportunity to read an interesting book, The Innovator’s Dilemma . There, with examples of high-tech products, it is shown how new products emerge that first lose to the decisions that currently dominate the market, and then radically change the state of the market.
One of the most striking examples: digital photography, which was completely absent in the 1990s, but only 20 years later led to the collapse of such a monster of the 20th century as Kodak (which, incidentally, was the first to make a prototype of a digital camera).

Another example close to developers: the evolution of hard drives. From the hefty monsters of the mainframe and mini-computer era, to the small 3.5 "and 2.5" inch models, and then to the M.2 format SSDs and wired directly to the eMMC board.

The same thing with floppy disks, which first reached 3.5 ", and then disappeared as a class under the pressure of USB flash drives.

Another example from our professional field is the development of personal computers. Which initially were not able to compete with the "real" computers of the mid-late 1970s. And then they just destroyed the mini-computers as a class. Then they led to the emergence of modern servers, somewhat reminiscent of the then mini-computers. And now PCs themselves are disappearing from mass consumption under the influence of laptops, tablets and smartphones.

The authors of the book declare that events in all such cases develop according to the same scenario:
- First, there is a need for some product that solves a particular problem. Let's say a flexible magnetic disk;
- since at the initial stage all competing solutions (of which, in principle, are few) are based on the same technologies, the market is divided between more or less similar products;
- manufacturers of successful products begin to compete with each other and in this competition bring their products almost to the most favorable price-quality ratio. And, most importantly, while existing products are as consistent as possible with the views on how the tasks for which these products are intended to be addressed. Roughly speaking, everyone knows that 8 "floppy disks are excellent for transferring information from one mini-computer to another using flexible magnetic disks. And no one else can imagine another way in the mainstream;
- somewhere on the sidelines, based on some new discoveries / materials / technologies, a new product appears that is significantly inferior to existing products in almost all respects. Generally more expensive. As a rule, not comparable in capabilities / capacities. But it has a very important quality: it can be used where it is impossible or difficult to apply mainstream solutions. For example, you cannot plug an 8 "drive into a personal computer. And PC owners are not interested in carrying 8" floppy disks. It is just not practical. Whereas a 5.25 "diskette is quite a thing for itself. And it doesn’t give a damn that at the cost of a kilobyte 5.25" diskette was originally more expensive than 8. "There was still no choice;
- A new market was formed around the new product, which was initially not at all interesting for mainstream product manufacturers. But, since it was a new market, new players flocked to it, which created serious competition for each other. And this competition quickly translated marginal and ineffective technology into extremely effective. Which soon ceased to be marginal, because as soon as it exceeded the old mainstream products in terms of its totality, it quickly replaced them in their own niche. Roughly speaking, if there are hundreds of thousands of 5.25 "drives and millions of 5.25" floppy disks around, then what's the point of holding onto the much more marginal 8 "devices at the moment?
Programming languages as technological products
At first glance, similar analogies can be seen in the way programming languages came to the mainstream. And perhaps the most striking examples here are the Java and Go languages.
The Java language came about as a result of an attempt to create “proper C ++”. But the resulting language would hardly be needed by anyone, because he was very miserable and, more importantly, slow and gluttonous. On the desktop, even considering the rapid growth in PC power at that time, Java had no chance.
However, Java entered the “market” from a completely different perspective, through a niche in which no one could really work then: via the Internet and browser applets (everything was a bit more complicated and there was still a market for JavaCard and STK applets, but we won’t leave in the wilds). The Internet was a very hot topic, and then there was simply nothing to do dynamic sites / pages (JavaScript appeared after the announcement of Java). And, since there was nothing to use besides Java, Java began to be used. Well, then, as it developed and overcome childhood diseases, Java went into other areas, displacing other technologies from there. Although in the same desktop she could not bite off a significant piece of the pie herself.
The Go language could hardly interest anyone in traditional niches where C, C ++, Java, C #, Python, Ruby, etc. already lived. But the development of products for the Internet has spawned another niche - RESTful services. For development of which Java was an overkill, C ++ is too complicated and dangerous, Python / Ruby and other dynamics are too slow. And now one of the most miserable in the expressive terms of languages developed in the 21st century becomes almost a silver bullet for this applied niche. From where, perhaps, it will spread somewhere else over time (which I personally will not be surprised at, given the general level of qualifications of the young generation of developers).
So one gets the feeling that programming should be the same with languages as with other technological products: the emergence of new languages will either lead to an almost complete disappearance or to oust previous languages into separate marginal niches. At the same time, old languages, in the process of their development within the framework of the competitive environment, are becoming more powerful and expressive for cheaper solutions to their typical tasks. As a result, old languages are becoming more and more voluminous and complex. And less attractive for use outside those niches that they have already occupied.
Therefore, it seems that the life cycle of a technological product described in the Innovator’s Dilemma should also extend to programming languages.
But not everything is so simple with programming languages
In the scheme of penetration of new technological products into the market described in the Innovator’s Dilemma, one of the most important reasons for users to switch from old mainstream products to new ones is either simply a significant reduction in the cost of ownership or the acquisition of previously available opportunities + a decrease in the cost of ownership.
For example, the development of PCs and the growth of their power makes owning a PC fleet cheaper than owning one or more mini-computers. As a result, three-inch floppy disks are cheaper per unit of capacity than 5.25 "(taking into account greater reliability and other factors). As a result, digital photography is cheaper per frame than film. And so on.
But two more important indicators are associated with the transition from one product to another - this is the cost / complexity of the transition itself, as well as the speed with which you can switch to a new product. These indicators can be estimated in money. And if the benefit of the transition to a new product is present, then the transition is carried out. Perhaps not fast, but carried out.
And here it turns out that the cost of switching from one programming language to another is much higher than in the case of switching from a mini-computer to a PC, from 8 "floppy disks to 5.25" or from HDD to SSD. Since changing a programming language is usually a complete rewrite of a software product. Often from scratch.
And what does rewriting mean? Salary of a new team of programmers, which will need to repeat the functionality already available in the product. And even if the new PL allows you to halve the size of the team, it will still mean significant costs. For if $ 10M was spent on developing the old version of the product, then rewriting will require a minimum of $ 5M.
But, more importantly, this is that the rewritten product will not appear right away, at once. Need time. A lot of time. Again, assuming that the new language allows you to write working code twice as fast, then rewriting a product whose development of an old version took 5 years will require only 2.5 years.
It turns out that right now you need to start investing a lot of money in order to get a copy of something that has been working for a long time and is bringing money now.
And one more side of this coin must be mentioned: if a software product is operated in changing conditions, then the product will inevitably be finalized or processed to meet modern needs. At the same time, the business does not have the opportunity to wait a year and a half, until a new version of the product appears on a new PL, new functionality, as a rule, is needed in the foreseeable future. Often, yesterday.
Therefore, when rewriting, expenses increase: you need to write a new version at the same time and develop the old one.
In my opinion, this is precisely what explains why new languages are "fired", primarily in the development of new applications for a new application niche. But crowding out old languages from previously occupied areas is already much slower. Fortran and Cobol can probably be considered the most striking examples. Not only is the software written on them still in operation, they continue to write new code in these languages. And these languages themselves are evolving.
And it seems to me that one of the worst dreams of owners of software products in Cobol is to rewrite the product in Java or C #;)
And another important factor: the development of IT itself
Another point that I would like to draw attention to is the fact that IT exists not so long ago and the history of the evolution of high-level languages is even shorter. The first part of this story is unlikely to provide us with solid support for our discussion of how some languages replace others. The 1950s and 1960s were years of experimentation. Moreover, the years when the computer market itself was segmented and a significant part of the software was written for specific computers and OS, without any special requirements for portability. The number of existing software developers, as well as the range of areas in which computers are widely used, can not be compared with the current state of affairs.
IMHO, fundamentally things changed in the 1970s, and since the 1980s we have seen the emergence of nuclear weapons that are already based on both the practical experience of past years and the results of theoretical studies. As for me, it is precisely the 1980s (and maybe the late 1970s) that are the beginning of the era of programming languages aimed at manufacturing software on an industrial scale. For it is here that we see Modula-2, SmallTalk, Ada, C ++, Eiffel, object extensions of Pascal, Objective-C, Perl.
Therefore, I will continue to build on precisely what appeared in this era of industrial nuclear weapons.
By the way
Listing the languages that appeared in the 1980s, I remembered about the PL developed by Niklaus Wirth: first Pascal, then Modula / Modula-2, then Oberon.
By the example of these languages, one can see how the experience of their author leads to the emergence of tools that take into account the shortcomings of previous attempts, as well as meet the new requirements of their time.
But these same languages also show how important it is for users of YaP to stay within the framework of the once chosen language. The transition from Pascal to Modula-2 was. But by no means massive. And, despite the fact that Modula-2 was more or less actively used, it did not become as popular as the heirs of Pascal, especially Delphi. And there was no observable transition to Oberon at all, as far as I remember.
The popular programming language cannot just be replaced. And what of that?
So, the main message in my previous reasoning is that if a language has found more or less widespread use and with its help a lot of various software products that are in everyday use have been created, then this language cannot simply be completely replaced by other programming languages. Especially in a short time.
Successful programming languages are doomed to continue to be used for years. And most likely to evolve.
And the evolution of a programming language implies the expansion of the language with new features. Which is inevitable, because progress does not stand still. People come up with more convenient ways to solve known problems. Faced with new tasks, which require additional expressive capabilities of programming languages. And, since the programming language is just a tool, people are moving towards improving their tool.
Which means that widely used programming languages are simply doomed to become more and more voluminous and more complex, in the course of their development acquiring opportunities that were not even discussed at first.
In principle, Bjarn Straustrup spoke about this a long time ago. And even what I myself have been observing for almost thirty years confirms the words of Straustrup. Say, modern Java is already very different from Java 1.0 of 1995. The C # language demonstrates an even more impressive evolution from a successful clone of the first Java to perhaps the most expressive mainstream language suitable for use by Hindu programmers (regardless of their nationality).
But the most striking example for me is still the Go language. Which, already in the 21st century, they began to do by deliberately throwing out a bunch of things that have proven themselves well over decades of widespread use in different nuclear materials. And which thanks, including this, has become popular. But, nevertheless, life takes its toll and Go is forced to add something that the authors initially intentionally refused - tools for generalized programming (aka templates / generics) .
So popular programming languages evolve towards expanding their capabilities. And that means complications. Since new features need to be added so as not to seriously break the already written code. For the epic story with Python of the second and third versions became a good example, which few dare to repeat.
Is it so bad?
The negative side of the ever-increasing complexity of programming languages (especially a language such as C ++) seems to be obvious: the input threshold is too high. Too much time needs to be spent in learning the language in order to start issuing code of acceptable quality in an acceptable time frame. What makes development in a complex programming language both expensive and risky. What happens if one or more qualified developers leaves the project? How fast and easy will it be to find a replacement? Difficult questions.
On the other hand, since a programming language is the same tool for recording the intentions of a particular person, as, for example, mathematical expressions, it is appropriate to draw an analogy with mathematics.
At school, we begin to study mathematics starting with the simplest arithmetic operations. Then we move on to more complex things: fractions, degrees and roots. Then we go further, towards the logarithms. Then we take a little integral calculus. Similarly with geometry.
As a result, a graduate of a normal high school has a certain mathematical apparatus, which may well be redundant for a single person. I will not be mistaken if I assume that many after school never needed to calculate anything using logarithms or take integrals.
Nevertheless, the mathematical apparatus, which is mastered in high school, can not be compared with the fact that university students will then be given courses in higher mathematics. Especially if this is a student of a mathematical or physical faculty (and not only seriously download higher mathematics in many specialties).
But after all, it does not occur to anyone to blame mathematics for the fact that the deeper you plunge into it, the more difficult it is. Since if a person is faced with an area of activity where he needs TFKP, there is nothing to be done, TFKP will have to be studied. However difficult it may be. Well and yes, it’s normal that not everyone succeeds.
Actually, the same thing with programming languages.
If you need to solve relatively simple problems, then you have a choice: either you use a simpler programming language, or you use a limited subset of a more complex language. But if you are faced with a difficult task (or specific conditions for its solution), then you may not have such a choice at all: the complexity of solving this problem in a "simple" language may be too large.
Speaking of tasks
From time to time I come across the assertion that almost all complex problems have already been solved (i.e., OSs have been developed, there are many DBMSs, middleware for every taste and color, etc., etc.), so in most only a simple and monotonous routine remains, to combat which complex tools are not needed.
It’s hard for me to agree with this point of view. But I can’t refute it confidently either. it’s just that physically I don’t have the opportunity to survey everything that happens outside my narrow professional niche. I myself seem to be doing not the simplest tasks. But at the same time, the goal of my efforts is to make it easier for other people to do their job. So, it seems, I myself strive to ensure that it becomes more than a simple and monotonous routine.
In addition, judging by the prevalence of languages such as Go, Python, Ruby, and PHP, it can be assumed that the percentage of tasks that really require sophisticated tools is gradually decreasing. Moreover, due to the fact that more and more are being programmed in absolute numbers, it may turn out that there are still more and more complex tasks over the years. Even if a smaller percentage of software developers are working on their solution.
However, it is necessary to take into consideration also such a factor, which is constantly increasing over time, as an increase in the amount of work per programmer. Roughly speaking, if 25 years ago one developer could make a medium-complex form for a GUI application in one working day, now the same form needs to be riveted in two hours. And the rest of the time should be spent on other tasks that would have taken another week 25 years ago.
Therefore, it may well be that it seems like a routine around you is uncomplicated in appearance, but there are so many of them that its volume is itself difficult. And therefore, a complex tool that will automate the routine and / or reduce the number of errors in its implementation, may also be preferable to a more primitive tool, albeit easier to learn.
So, on the one hand, indeed, we can assume an increase in the number of tasks of small or medium complexity for which it makes no sense to use complex languages, such as C ++, Scala, or Haskell. But, on the other hand, complex tasks still do not disappear. Yes, and simple, but voluminous, the task may also require a tool higher than Go or pure C.
At the same time, we have at our disposal programming languages for every taste and color. You can choose any. Therefore, as mentioned above, developers have a choice: you can take a simple tool to solve a simple task, you can take a more complicated tool, but limit yourself to only part of its capabilities. Therefore, if someone is confused by the complexity of modern C ++, then this is not a problem at all. Because, firstly, it makes no sense to use C ++ anytime, anywhere. And, secondly, no one forces us to use all the features of C ++ in a specific project at once, it is enough to limit ourselves to only what is really needed.
Total
So what can be said in the end? A few things:
- firstly, times have changed. The situation when the programming language appeared, began to be widely used, and then disappeared "from the radar", which was the case in the 1960s and 1970s, became completely different. A range of widely used hardware platforms has appeared that live long and will live long. Time has proved to everyone the importance of such a thing as code portability. Programs themselves have become much more voluminous and more complex (especially taking into account all their dependencies). Therefore, if some program was written yesterday in the X language, today it is useful and tomorrow the need for this program will not disappear suddenly, then the X language will not go anywhere. Actually, one can be convinced of this by looking at the C language. Shit is rare and ancient as the mammoth coproliths. But many continue to eat the cactus. Moreover, a considerable number of them - voluntarily and with pleasure. So mainstream languages now have much more chances to stay wide-spread;
- secondly, since programming languages will not be replaced one by one as quickly as it happened 40 years ago, then every popular language will inevitably evolve. As for me, it’s so obvious that in the direction of complication. Well, the increase in volume, because in the language that which was originally in it will be preserved, so the new will accumulate;
- Thirdly, there is a decent selection of tools for various tasks. Somewhere you can get by with Ruby / Python, somewhere Go will do, somewhere it's cheaper to stay in Java. Well, somewhere you have to use Rust, C ++, Scala or Haskell. So it’s not at all necessary to mess with complex programming languages if you don’t have really complicated tasks. And if a complex tool was nevertheless required, then it is not at all necessary to use it “to the fullest”, you can restrict yourself to a simpler and more understandable subset of a complex language. And this is normal.
But the main thing, perhaps, is still different: the specificity of the programmer’s work is that you always have to learn something new and relearn in this profession. The brains have to be kept ready for the perception of something new. This distinguishes our profession from some other, more conservative professions (although it is unlikely to find a profession that would not be influenced by technological progress and the development of society). , - , , : , , -. ;)