Sponsored Link •
Bill Venners: C++ has a lot of stuff in it. The more features that a designer puts into a language or library, the more power the users get, but also the more surface area they get. There are more features users have to know about, even if it is knowing they just want to ignore certain features. As a designer of a language or library, how do you decide what features to leave in what to leave out?
Bjarne Stroustrup: It's very hard. I don't have a good enough philosophical base for that, and neither has just about anybody else. In the C++ language, I try to put in what will help everybody as opposed to what will help a particular group. I try to put in very general facilities. For example, I don't put in specific features for GUIs, because lots of people don't put GUIs in in their programs. I don't put in specific features for databases, because lots of people don't use databases. I don't put in specific features for concurrency, because you can put them in a library. So I go for generality, for features that in principle will be used by everybody, directly or indirectly. And I try not to force people to do lots of repetitive, tedious stuff. My work with templates, inlines, and overloading to eliminate dangerous casts and repetition is probably the best example.
Of course, you can say that everything I just said could be applied either to the design of a language itself or to the design of a standard library that everybody's using, or should be using. And it is very hard to define exactly where you should draw the line between a language and its libraries. In C++, I have tended to build into in the language facilities that are abstraction mechanisms. So contrary to some languages, I have not put in an advanced vector, because I could do that in a library with the facilities provided by the language. I didn't provide a string with special facilities for string manipulation. Instead, I put in general mechanisms that allow you to write a string class. I didn't put in properties because you can write a properties class. So in that sense, I go against some of the currently fashionable trends in other languages to put in very specific and specialized facilities. I guess that's a kind of basic philosophy of mine.
If you want more detail, read The Design and Evolution of C++, which is where I document a lot about why C++ is designed the way it is. Among other things, reading that book will help you avoid things like people—in this case, me—being wise after the event and trying to change history retrospectively. That book is a fairly solid record of what I thought at the time. There is unfortunately a lot of revisionist history in the computing world. Interestingly enough, the C++ language hasn't changed since I described in The Design and Evolution of C++. What has changed is the standard library and some of the styles of usage.
Bill Venners: Language and library designers often think about protecting users from themselves, but in C++, you seem to operate more from the philosophy that designers should give people enough rope to shoot themselves in the foot. In your C++ FAQ, you write, "As you protect people from simple dangers, they get themselves into new and less obvious problems." In our designs, how much should we try to shield users from their own potential mistakes?
Bjarne Stroustrup: I'm not as paternalistic as some language designers. I may have romantic notions of how competent users—in this case programmers—are, but I don't consider programmers on average stupid, and I would like to see them as more respected professionals. I wish programmers would act professional more often and that people would be willing to pay for more competence.
In addition, I don't want to disenfranchise users by giving them facilities that allow them to only do so much. I often see systems that require their users, if they want to do more than the system directly provides, to go back to the system vendor and ask the vendor to provide new facilities. The best examples are some of the fourth generation languages and tools for generating code from models or diagrams. If some facility you require was not thought of by the designer and is not built into the tool, you basically have to go back to the tool vendor and ask for a change in the tool. I have seen an example where a customer couldn't easily define a new sort operation. A related example is languages where you can't write the standard libraries, let alone the advanced libraries, in the language itself. That means you separate the user population into the untrusted developer group and the trusted and privileged group that tends to work for the supplier.
I prefer to see everybody on a reasonably even keel. My ideal is that if you don't like the libraries your vendor ships, you can build your own, because you have the same tools available. That idea doesn't seem to be fashionable among tools and platform vendors either.
C was designed with the principle that you should be able to write its standard library in the language itself. That same principle guided the design of C++. I don't think it's a principle in just about any other language. What other languages do is write their implementation in C or C++ instead. That approach works, but it runs the risk of having the great unwashed masses writing in some more protective language, and the specialists, working for the vendor, writing in the language where the actual work can be done. Once you have generality, you can get safety though coding standards or libraries; preferably through domain-specific coding standards supported by libraries.