In thinking about algorithms, it is essential to have good notations for expressing them, for conveying the ideas of the algorithms from one human mind to another clearly, unambiguously, and without unnecessary psychological strain or trauma. We also want our expressions of those algorithms to be executable, and we even care a little bit about making the work of translating from our programming notations into sequences of machine instructions efficient and straightforward, but that's of secondary importance. Well-designed programming languages put the interests of the human beings who have to write and read programs ahead of the interests of the creators of compilers and interpreters.
However, not many programming languages are well-designed. Most language creators are preoccupied with their implementations and with some particular feature set that they can implement extraordinarily efficiently. They don't give much thought to design and are oblivious to the issues that a skillful designer of notations takes into account. Nor do they pay much attention to the history of programming languages, to the lessons that long and painful experience should already have taught us or to the brilliant insights of designers of languages that are now obsolete and forgotten.
We now have immense code libraries that should never be used (or, worse, re-used) because it's too difficult to debug them, to adapt them, to prove their correctness, or to estimate their resource use, even asymptotically and in general terms. Careless programming is the principal cause of this catastrophe, but I allocate some of the blame to poorly designed programming languages, which make it almost impossible to express algorithms accurately and intelligibly.
In the early years of C++, its creator, Bjarne Stroustrup, built the language up from C primarily by accretion. Initially, C++ was implemented as a preprocessor that produced standard C, and the first novel elements of the C++ language were the features that introduced object orientation: classes, methods, and inheritance. The preprocessor converted these into standard C typedefs and functions.
Once the project got rolling, though, Stroustrup started adding other features, accommodating first requests from users and then suggestions from other language proponents. If they seemed like good ideas that could be easily implemented, they went into the language, making C++ more powerful and, in some ways, more expressive, but also more difficult to work with and to understand. Stroustrup didn't give enough thought to the interactions among these new features or to their effects on the ability of programmers, particularly new programmers, to write and read C++ code. By the time C++ was first standardized, the language standard was six times as long as the one that defined C and full of bizarre corner cases, unspecified and undefined behaviors, and opportunities for misinterpretation by implementers seeking short cuts. The design of the language was a mess, and it has been a mess ever since.
C++ has, of course, continued to evolve, and ingenious contributors have constantly proposed extensions, improvements, and features of all kinds. However, Stroustrup now opposes most of these suggestions, even when he thinks that they might be good ideas in principle, because he knows that the language is already too large, too complicated, too hard to learn, and too hard to use effectively as a way of expressing algorithms. Most of the proposals would make it even worse in these respects.
Here are two of his contributions (to the C++17 and C++20 working groups, respectively) making this point:
“Thoughts about C++17”
Bjarne Stroustrup, May 15, 2015
It seems to be a popular pastime to condemn C++ for being a filthy mess caused by rampant design-by-committee. This has been suggested repeatedly since before the committee was founded, but I feel the situation is now far worse. C++ is larger now (especially when we consider the standard library). That, and the variety of current proposals make the accusation credible.
“Remember the Vasa!”
Bjarne Stroustrup, March 6, 2018
We are on a path to disaster through enthusiasm and design-by-committee …
C++17 did little to make our foundation more solid, regular, and complete. Instead, it added significant surface complexity and increased the number of features people need to learn. C++ could crumble under the weight of these — mostly not quite fully-baked — proposals. We should not spend most [of] our time creating increasingly complicated facilities for experts, such as ourselves.
We need a reasonably coherent language that can be used by “ordinary programmers” whose main concern is to ship great applications on time. We now have about 150 cooks; that's not a good way to get a tasty and balanced meal.
We are on the path to something that could destroy C++. We must get off that path!
Stroustrup's repentance probably came too late to save C++, but perhaps the next generation of language designers can learn from his tragedy.