This is the eighth of a series of articles examining a 2009 interview with Bjarne Stroustrup. The first part is here with links to the other parts:
Lessons from Early C++
A little further down Stroustrup is asked about lessons learnt. Here we get some candour.
Stroustrup: “During the early development of C++, I articulated a set of “rules of thumb,” which you can find the The Design and Evolution of C++ [Addison-Wesley], and also discussed in my two HOPL papers. Clearly, any serious language design project needs a set of principles as soon as possible, these principle need to be articulated. That’s actually a conclusion from the C++ experience: I didn’t articulate C++’s design principles early enough and didn’t get those principles understood widely enough.”
It is not that the principles weren’t articulated — there either were no principles or C++ was not based on a good principles. Even more than C, C++ has been built on compromises to preserve past mistakes and constraints of past technology and thinking in software. The early form of C++ was just macros defining class and inheritance from Simula. Like C inherited structured syntax from ALGOL via BCPL, it did not get the structured principles that ALGOL sought to establish. C++ similarly, just used classes as a better syntax, not really understanding, but getting some of the strength of the thinking of Dahl and Nygaard in Simula.
Language design also requires more than vague “rules of thumb”, but formal specification of both syntax in EBNF and semantics in the various formalisms that have been developed since (mainly from the work of Christopher Strachey who defined CPL, the language between ALGOL and BCPL). Even these “rules of thumb” were developed after the fact, since Design and Evolution did not appear until 1994.
Stroustrup heavily pushed C++. Ken Thompson (who originally adapted B and C from BCPL) noted: “Stroustrup campaigned for years and years and years, way beyond any sort of technical contributions he made to the language, to get it adopted and used. And he sort of ran all the standards committees with a whip and a chair. And he said “no” to no one. He put every feature in that language that ever existed. It wasn’t cleanly designed — it was just the union of everything that came along. And I think it suffered drastically from that.” From Seibel, Peter (2009). ‘Coders At Work’. p. 475.
Stroustrup: “As a result, many people invented their own rationales for C++’s design; some of those were pretty amazing and led to much confusion.”
It is hard to say what he means by ‘amazing’ since he says this leads to much confusion. Perhaps that is the thing, people see C++ in their own way, rather than a language which fits together and gives definite interpretations (like a language should), C++ has a false appeal to everyone. It illustrates the problem with C++, there is really confusion about what it is, what it should be, and how to use it.
That is not good on a team project that might spread over years with different programmers and different views on how to program, what C++ is and how to use particular things. That is actually difficult enough in any programming. C++ is little help in making such things manageable. This is an important goal of any language, to support programming and support the process so that people come together in a common way.
Stroustrup: “To this day, some see C++ as little more than a failed attempt to design something like Smalltalk (no, C++ was not supposed to be “like Smalltalk”; it follows the Simula model of OO), or as nothing but an attempt to remedy some flaws in C for writing C-style code (no, C++ was not supposed to be just C with a few tweaks).”
This arises from Stroustrup trying to put everything in. I remember when people started talking about C++ before it appeared as the next version of C. About 10 years later (after I had done a lot of OO in other languages), I finally saw a project where C++ was used mainly in the OO sense (many of those guys had been on Bertrand Meyer’s Object-Oriented Software Construction course, so probably didn’t even think of using C++ in a different way). But many projects are just a mess between better C and mixing in a few discretionary classes.
It is true that Simula and Smalltalk have different OO models, even though they start from the same place of classes and inheritance. Languages more directly based on Simula tend to be statically typed languages, whereas Smalltalk is dynamically typed.
That is not the most significant difference. The Simula-based languages are ADT based. Smalltalk is based on objects that interact with each other. They only interactions are through the class interface. This is a general principle for any module system that modules only interact via published interfaces. In true OO, classes are the one and only module. That is not the case in C++. The interfaces should be functional. That is the internal details and data fields of an object are not revealed. Even simple recovery of the value of a field looks like a function (variables are a particular implementation of a function). What Smalltalk has in mind is more Abstract Functional Types. C++ breaks the functional aspects of both Simula- and Smalltalk-style OO. In C++ objects can interact via global variables. Not only that, but functional access through interfaces only can be completely subverted with pointers.
The C++ excuse is that programmers might want more direct and efficient access and that programmers should be trusted to know what they are doing. However, if they are using such shortcuts, they really don’t know what they are doing. They are creating problems for others in baking in dependencies on representations which is the very thing OO was developed to avoid, especially Smalltalk-style OO.
Whatever C++ is or however it is used, it just seems to lack solid foundations and principles to begin with. In contrast, people should read:
https://bertrandmeyer.com/OOSC2/
to see principles and foundations stated before a language. But many programmers don’t like principles, foundations, specifications, and designs first. They even resent that order of presentation as being dictatorial and didactic. It is time for the software profession to become a profession and an engineering discipline.
Stroustrup: “The purpose of a (nonexperimental) programming language is to help build good systems.”
C++ has been one of the biggest experiments ever, running over decades, still trying to get it right, still with a lot to go, still leaving a lot to be desired. Any program design has an element of experimentation — that is what the ‘soft’ in ‘software’ means. We can experiment and explore.
Unfortunately with programming languages people have seen them as a fixed thing, from FORTRAN and COBOL to C, and C++. However, these languages have necessarily changed. Even natural language evolves and changes. While language design must be more formal, there will be aspects where we can improve. Thus software is experimental in nature.
We want to make software flexible and free of dependencies to keep it experimental and able to change quickly. C and C++ bake in dependencies resulting in inflexible software and lock in, particularly to C and C++, for all the wrong reasons.
Stroustrup: “It follows that notions of system design and language design are closely related.”
Depending on the level we are talking about, this is true. If we are talking about the systems we are designing and problems we are solving, this is true, but it is debatable how well C++ achieves that. However, if we are talking about the system and platform underneath the language, that is not true. C++ exposes aspects of the lower level that should not be exposed. This goes against the first interpretation.
Stroustrup: “My definition of “good” in the context is basically “correct, maintainable, and providing acceptable resource usage.”
The number one goal in software production is correctness. We have two kinds of resources — logical resources which are the entities dealt with at the problem level and physical system resources. It is the job of the compilers, runtimes, and operating systems to map requests for logical resources to system resources. This should be as abstracted as possible in a language. Many logical requests can indeed have no effect on physical resources. This is the famous “zero-penalty” mantra of C++. However, it is not unique to C++ — all language implementations try to make the mapping from logical to physical as cheap as possible. But that depends more on the underlying platform than on the language. Trying to do that in the language, to match the language to any particular platform creates burden for the programmer.
Exposing the management of physical resources to the level of general applications programming makes the software inflexible, dependent on underlying assumptions, and locked in to the platforms (that is inflexibility in itself) and to the languages used.
Stroustrup: “The obvious missing component is “easy to write,” but for the kind of systems I think most about, that’s secondary.”
Well this is in keeping with the thinking of many programmers. They don’t believe in the literate side of programming, loving the cryptic aspect of coding. However, being literate is a very important aspect of programming and languages. Writability and readability are related by not identical. Ken Thompson made B easier to write, but sacrificed readability and semantics. A language must be clear, easy to read and write, but more importantly, arising from that, easy to reason with. Again, C++ is a failure on those counts.
One aspect of writability is how regular is the language. Formal specification of syntax helps here. It might be thought that formal specification results in more cryptic languages, harder to understand. But the opposite is true — formal specifications are to avoid pitfalls in languages. C and C++ are full of pitfalls. Formally specified languages are easier to remember, thus easier to write. Perhaps this is not important to Stroustrup, and like C before, compromises were made that the authors felt they could live with to get on with writing other software (Unix). But that is not a good compromise to force onto generations of programmers, nor to lead them in the thinking that being easy to write or easy to read is an unimportant factor.
Writability is not just minimising keystrokes as Thompson tried to do in B.
Correctness follows from being able to reason about software which comes from the expressiveness of the language, to make the meaning of the expressed software clear.
Maintainability also depends on being easy to read and write. If we are given the task of changing some software that we ourselves might not have written, it must be easy to read and understand. Thus it is easier to write and change.
Readability and writability also make it easier to reason about the logical resources we use. Minimising the logical resources we use will also minimise the physical system resources. Programmers should be enabled to think at this logical level, not be forced to think about physical resources which will be different on different machines, different configurations, and at different times on the same system depending on resource demands of all processes.
Clarity is thus of great concern. I can’t even think of what the kind of systems work that Stroustrup is doing where this is secondary. Systems that achieve longevity must be clear.
“For users to be able to speak their mind, programming languages should be designed so that they do not get in the way of their thought.” from ‘Scrambled Features for Breakfast: Concepts of Agile Language Development’ Walter Cazzola and Luca Favalli in CACM volume 66 no. 11, November 2023.
Stroustrup: ““RAD development” is not my ideal.”
Larger more complex projects certainly need more upfront thinking. There is no one correct approach here. Some projects are done quickly. However, we need clean, clear, and expressive languages to make large-scale complex development as fast as possible. A language should fit in a every level of the development process, not just be for ‘coding’.
Stroustrup: “My aim for C++ was and is direct expression of ideas, resulting in code that can be efficient in time and space.”
Well, that is in common with many language designs. This is part of the scare campaign of C and C++, as if other languages have not thought of this. However, most languages can separate language design from the issues of generating code in language implementations. C++ might give the illusion of efficiency by directly exposing the physical resource. Other languages are more ambitious to only use logical concepts that are common to computation in any environment and then automatically mapping that to the physical resource.
Stroustrup talks about evolution of a language claiming changing a language every year is not good. Well I can’t think of languages that do that. Most languages are more stable than C++ because they don’t have as many things to fix. C++ is slow at fixing things up because the things that need fixing are so difficult to fix. Many things have to stay because of programmer backlash. But people are still clamouring for better, but for some reason they can’t see past C++, like Herb Sutter and Scott Meyers. Well, they are probably making good money out of that feeding a confused industry.
Stroustrup talks about community. It is very true that a language requires support and community. Many language designers have only been interested in producing good language designs, especially academics. They then move on to something new that grabs their interest. Niklaus Wirth certainly was not interested in creating a following. Neither was Bob Barton. This comes from a perspective that technology had to change and thus improve. Steve Jobs noted this back in 1983. Many designers of good systems were disillusioned that they would design and develop good systems only to find there was no interest in shipping products. Apple was going to fix that and came out with the Macintosh in 1984 that did change the way we all do computing.
We need that in programming languages, but we need communities behind good languages, not just communities to prop up and perpetuate bad languages.
Now Stroustrup also claims other languages have been marketed and promoted and sold, using Java and Ada as examples. He claims C++ has had none of that. Well let’s let the words of Ken Thompson burn in our ears: “Stroustrup campaigned for years and years and years, way beyond any sort of technical contributions he made to the language, to get it adopted and used.”
Stroustrup could not accept criticism or dissension about C++, as Thompson said: “I would try out the [C++] language [at AT&T] as it was being developed and make comments on it. It was part of the work atmosphere there. And you’d write something and then the next day it wouldn’t work because the language changed. It was very unstable for a very long period of time. At some point, I said, no, no more. In an interview I said exactly that, that I didn’t use it because it wouldn’t stay still for two days in a row. When Stroustrup read the interview he came screaming into my room about how I was undermining him and what I said mattered and I said it was a bad language.”
Let’s be clear that C++ very much rode on the back of the market success of C. Some C programmers saw C++ for what it was, and backed out. Ken Thompson himself saw C++ for what it was.
Coming from the OO direction, Alan Kay (who coined OO): “I made up the term “object-oriented,” and I can tell you I did not have C++ in mind.” and “This is the most pernicious thing about C++ and Java in that they think they’re helping the programmer by looking as much like the old thing as possible but in fact they’re hurting the programmer terribly by making it difficult for the programmer to understand what is really powerful about this new metaphor.”
Stroustrup very much promoted and marketed C++ beyond what it was worth. C also was very hyped, even if it was among the technical community.