Interview++

Bjarne Stroustrup on the Evolution of Languages

Howard Dierking

Contents

Thoughts on Language
Language Trends
Methodology and Best Practices
Looking toward the Future
Books and Phones

Every once in a while, an evolutionary leap rapidly advances and reshapes the entire field of engineering. Such a leap occurred in software development with the introduction of the C++ programming language. This leap was not inherent in the language itself: object-oriented languages such as Simula67 and Smalltalk existed prior to C++. But because C++ was built on top of the C programming language (and could compile existing C programs), it was able to bring the abstractions of object-oriented thinking into the mainstream.

C++ has inspired a great deal of thought surrounding software design and development, from design patterns to meta-programming. And because of its portability among hardware platforms and its lower-level expressiveness, C++ will assuredly be essential in a world of faster, smaller hardware.

I recently had the pleasure of talking to Bjarne Stroustrup, the creator of C++, about a host of topics, from his thoughts on languages to general industry trends to his own personal reading list. Many of the questions asked were suggested by readers via my blog, so thanks to everyone who contributed questions. And of course, thanks to Bjarne.

Thoughts on Language

Howard Dierking Why do programming languages connect with people on such a deep level—such that communities of language zealots form?

Bjarne Stroustrup You should ask a psychologist, a sociologist, or maybe even an economist, rather than a computer scientist! My guess is that the languages we use to express our ideas become a part of ourselves so that if you know only one language, proponents of other languages could appear personally threatening. In that case, the solution seems to be to know more languages well. I don't think you can be a professional in the software field knowing only one programming language. There may also be an economic reason: while fundamental understanding transcends programming language boundaries, many practical skills don't. So if I know only language X and its tool sets, and you argue for language Y and its toolsets, you are threatening my livelihood. Again, the solution seems to be to know several languages and toolsets (and to be solid on fundamentals). Unfortunately, my suggested solutions do not take into account that most people have very little time left after doing all that they feel necessary just to manage. That's no excuse for zealotry, though.

HD What should be the role of the IDE in software development? How should the IDE support a language?

BS I'm not a heavy IDE user. I appreciate a responsive IDE editor with understanding of my language, but I also want to be able to work without an IDE. I might have a different opinion if a good IDE was universally available—in reality a part of the language or vice versa (see Figure 1). My desire for portability of code plays a role here. With C++, I want to be able to understand my system from just the source code in the source files. I actively dislike IDE mechanisms that involve transformations or generation that cannot be represented as code fit for human consumption.

Figure 1 The IDE Designer as a Language

Figure 1** The IDE Designer as a Language **(Click the image for a larger view)

HD Do you see noise or readability as a problem in today's general purpose languages? If so, what is the solution?

BS A simpler syntax would be nice, but I suspect that what most people grumble about when they talk about readability is not so much the actual text as the complexity of what is being expressed. Too many people expect to walk up to any program written in any language and—with only a bit of help from an online support facility—understand all the constructs used to express the program and all the logic of the program itself. Compare that to the way we look at natural languages and use them. Would you expect to understand a Shakespearean sonnet without background information? How about Beowulf in the original Old English? Maybe we expect too much from our programming languages. Any language that can express all that is needed for a wide range of application areas could be considered unnecessarily complex for any given application, but it must cope with an essentially unbounded set of applications. Domain-specific languages can help in specific cases, but now we have to deal with the complexities of many languages and their interactions.

HD How should a general-purpose language support application design ideas such as component programming and service programming?

BS A general-purpose language should support the writing of libraries that express general and application-specific notions, support tool building, and provide the glue needed to connect different parts of an application. For that, the language needs flexibility, an expressive type system, good basic performance, and long-term stability.

HD Is multiple dispatch a good thing?

BS Yes. A conventional single-dispatch object-oriented programming language (such as Simula, C++, Smalltalk, Java, and C#) cannot elegantly express simple operations, such as multiplying numbers or finding the intersection of two shapes, where the exact types are not known until run time. The resulting code (relying on double dispatch, the visitor pattern, and so on) is slow and not as maintainable as we'd like. Languages that support multiple dispatch at run time (like Dylan and CLOS) do better and languages (such as C++) that support it at compile time can sometimes help a bit. Last year, together with some of my students, I published a research paper on how to cleanly add multiple dispatch to C++. The resulting code for multiple dispatch use-cases is shorter, simpler, uses less memory, and runs faster than all workarounds we have seen (see Figure 2). That work came too late for C++0x, though. You can find a paper about that at research.att.com/~bs/multimethods.pdf.

Figure 2 Multiple Dispatch via Multiple Inheritance

Figure 2** Multiple Dispatch via Multiple Inheritance **(Click the image for a larger view)

HD What are your thoughts on covariance/contravariance in C++ today? Do you expect the current behavior to change in future language versions?

BS Not really. In that area, I think C++ does what it should. Are you thinking about examples such as converting a vector<Apple> to a vector<Fruit>? That's terribly unsafe unless the vector<Fruit> is immutable (or you could add an Orange to it). I don't think implicit run-time type checking is a good approach to such problems.

HD What are your thoughts on making message passing a key language feature, as opposed to method calling?

BS I like explicit message passing, but I have only used it a long time ago and in the context of distributed systems. Realistically, for that to work on a large scale, we'd have to do some serious work on language and tool support for message passing. I don't think that has been done, but I could be wrong. Lots of problems associated with sharing and locking go away if you rely on messages and message queues. I'd love to see a standard C++ library for that, and I just might get it (in a couple of years).

HD Is there an inherent conflict for general-purpose languages in simultaneously supporting a broad, diverse audience and encouraging improvements in code expressiveness and design elegance? What is the role of the language in supporting the latter?

BS I guess there is in the sense that you can approach elegance through specialization. Also, if you have a small audience (user community), you can cater to its tastes (only) and it is possible to depart from conventional notations and concepts if you somehow control your user community (saying something like "you need to read up on type theory to use this"). A general-purpose language is constrained not only by the need to support a wide variety of uses, but also by the need to be teachable to large groups of people with a variety of assumptions and educational backgrounds (the basics have to be usable by a high-school student with a poor teacher).

So I think a general-purpose language can encourage elegance as long as elegant code can be expressed in it. In the case of C++, very elegant code can be written. By being part of a general-purpose language and widely available, such examples can get into the hands of millions and into articles and textbooks that can be read by millions. No specialized language—however elegant—has those options.

HD Have we placed too much emphasis on architecture?

BS No, at least not the way I would define architecture. On the contrary, there is too little emphasis on architecture and too much poor coding with little understanding of structural principles. I suspect a major problem with architecture is that many programmers have only a vague idea of what makes good code good. Being able to recognize it when you see it is not enough. Having rules for what not to do is not enough. We need articulated prescriptive rules.

HD Has the open source community helped, hurt, or made no difference in software quality, design, and professionalism?

BS That's a really hard question. I have seen cases where it helped (increased the quality of code and the degree of professionalism of people involved), cases where it hurt (taught really bad habits and attitudes), and many cases where I couldn't tell.

I have no way of guessing what the effects on the community at large have been or what would have happened had the degree of open source work been greater or lesser. The community is simply too large for me to guess.

Language Trends

HD Do you see a serious shift towards dynamic languages in the near future?

BS Not really. I think people are comparing apples and oranges too often. I don't think we have a choice between static and dynamic languages in general and furthermore I don't think languages cleanly fit into those two categories: most if not all dynamic languages have aspects that are statically determined, and all the major static languages can do things that require run-time determination of the meaning of values. There are fashions, of course, and I can't guess about those, but I think that many real-world language choices are rationally made based on the requirements of an application, an application area, and/or the skills of the available developers. For example, I'd not try to implement a Java runtime in (say) Ruby or express a heavily interactive simulation language as C++ (as opposed to its implementation).

HD Would you see it as a good thing to ultimately remove all existence of void*/variant/object/etc? (Figure 3 shows a good example.)

Figure 3 Polyhedron Sample

STDMETHODIMP 
CoCalc::QueryInterface(REFIID riid, void** ppv)
{
   if (riid == IID_IFirst || riid == IID_IUnknown)
    *ppv = static_cast<IFirst*>(this);
  else if (riid == IID_ISecond)
    *ppv = static_cast<ISecond>(this);
  else
  {
    *ppv = 0;
    return E_NOINTERFACE;
  }
  AddRef();
  return S_OK;
}

BS I guess that in principle it would be a good idea to get rid of all the catchall options, but in reality we could achieve that only by having a full classification of everything we wanted to express so that we could always be more specific. For example, I have never seen a real function that could do something to every object; if you do something, you always make some assumption about what you are manipulating (a pure forwarding function is the closest I can think of as a counter example). The current work on concepts in the C++ world (constraints/requirements on generic algorithms) will be a help here, but I don't see us being able to do without some truly general mechanism for expressing "something, but I really don't know what" for dealing with unanticipated needs.

HD With the trend shifting back to loosely typed languages, should we start considering Hungarian notation again?

BS I'm not sure that there is such a trend, though there probably is an increase in the fraction of the total work that is suitable for loosely typed languages. In other words, the use of statically typed languages could still be growing (I think so) while the use of loosely typed languages is growing faster. And no, don't use Hungarian. Hungarian is an awful idea. The source code should reflect the meaning of a program, not simulate a type system. If you really, really feel the need for Hungarian, you are probably using a language that is unsuitable for your application.

HD In 2000 you gave a presentation called "C++: A New Language for a New Millennium" and introduced the concept of a Wrap<T>. This is basically aspect-oriented programming (AOP). What do you think of AOP (generally) and its formalization of the Wrap<T> pattern (pointcuts, advice, and so on)?

BS I haven't spent enough time on AOP to give a solid answer. I like composition (especially non-intrusive) to be supported in a language (as opposed to both "not supported" and "supported by a tool"). I worry about extra-linguistic tools and about non-standard tool chains. C++ templates have been amazingly successful at non-intrusive composition—just look at the Standard Template Library (STL) and some of the uses in embedded systems programming. It is a real strength to be able to combine ideas without forcing them into a rigid or predesigned hierarchy. However, it has also been hard to manage for some developers and some maintainers. It is also notationally heavy. C++0x contains attempts to address that without flexibility or performance hits.

HD Certain characteristics of the C++ language have the potential to create some nasty unintended consequences (such as macros). What are some other unintended consequences that you would like to see disambiguated in C++ or modern languages in general?

BS Actually, I knew macros were nasty when I started using C; but like most people, I underestimated their nastiness and pervasive negative influences. The pervasive use of macros in C is probably the major reason we didn't have excellent C++ development environments a decade ago. There are also too many, too confusing ways of initializing objects in C++; I hope to address that with a uniform mechanism in C++0x. I mentioned templates in my answer to the previous question. They are the major success in later C++ (post 1985), but their success has strained the language—again, parts of C++0x are intended to deal with that.

Many minor and not-so-minor problems we have discovered over the years cannot be addressed in C++ for compatibility reasons. For example, the declarator syntax is an unnecessary complication—just about any linear notation would be better. Similarly, many defaults are wrong: constructors should not be conversions by default, names should not by default be accessible from other source files, and so on. Not controlling the linker has been a constant source of problems; in particular, implementers seem to delight in providing similar features in incompatible forms.

There have also been positive surprises. The most spectacular has been the pervasive use of destructors in techniques relating to resource management and error handling (using exceptions). I knew destructors were a good idea—after all, you have to reverse the effect of a constructor—but I didn't realize quite how central they would be to good use of C++.

HD You commented on your Web site, "I think we should look for elegance in the applications built, rather than in the languages themselves." Is the move toward domain specific languages (DSLs) a convergence of these?

BS Yes, almost certainly. It is often an attempt in that direction. Sometimes, it even works.

HD What are your thoughts on DSLs in general? What do you envision as the relationship between DSLs and general-purpose languages?

BS I worry about the number of languages being designed, implemented, introduced with great fanfare, and then fading away without significant impact. During this—typically many-years long phase of development—a new language consumes significant resources with essentially no returns. I wrote a paper on this phenomenon called "A Rationale for Semantically Enhanced Library Languages" (research.att.com/~bs/SELLrationale.pdf). I argue for using libraries, possibly supported by tools, and a general-purpose language.

I think that a DSL should be a last resort, not a first. If at all possible, the DSL should be firmly rooted in a general-purpose language and standard tool chains. A DSL needs a general-purpose language (or at least a systems programming language) for its implementation and the implementation of its run-time primitives. I think it would be best if a DSL is consciously and firmly paired with at least one general-purpose language so that it is easy to add new facilities through the use of libraries written in that general-purpose language. Obviously, a professional should master several languages, but I do wonder if the sum of complexity of a variety of DSLs couldn't become so high that it became a problem. Also, many (if not most) DSLs seem to "want to" become general-purpose languages.

HD You mentioned that many constructs in the C++ were intentionally left ambiguous due to varied definitions on different hardware. Do you see advancements in interoperability that could disambiguate some of these constructs?

BS "Ambiguous" is the wrong word. Far too many things have been left undefined or implementation-defined. I suspect that if I could redefine C++ from scratch it would have no undefined behaviors and far fewer implementation-defined ones. However, I don't have a time machine and we just cannot break hundreds of millions of lines of code by picking a set of resolutions today.

Methodology and Best Practices

HD What process methodology do you tend to use and teach?

BS Identify key application concepts, identify useful libraries, build new libraries in support of the application concept, try out ideas early, integrate early, test early and often, use documentation and tutorial material as design tools, and grow larger programs from smaller ones (iterating along the way). It should be obvious that I'm focusing on relatively small projects just now.

HD Do you see an intersection or affinity between a language and a development methodology?

BS I think so, as far as library design is seen as a design/development technique. Focusing on increasingly higher-level (closer to the application) facilities through library building places requirements on the language. I wouldn't overstate this point, but I don't think you could have a single development methodology for (say) COBOL, C, Java, C++, and Python and expect to gain more than the minimal support from each language.

HD What are some of your personal rules of thumb when creating software?

BS Focus on key concepts; focus on their interfaces; focus on the management of resources (memory, files, locks, and so on); focus on error handling. The design of good invariants for classes and Resource Acquisition Is Initialization (RAII) are key techniques.

HD There's a lot of buzz around being agile. What does "agile" mean to you? Does C++ support agile?

BS I don't use the word; it's much too vague. Of course C++ supports agile—whatever that means.

Looking toward the Future

HD How can a language evolve to support advanced features such as templates, dynamic events, and self-writing code, and at the same time remain accessible to new entrants?

BS I don't know. I don't think there is a general answer. New features can be important as far as they support more effective techniques in the context of a language. However, stability is essential: one of the reasons for the continuing strength of C and C++ is the care taken by the standards committees for old (often decades old) code to remain valid and for the integration of new features to be smooth. This is not easy, to say the least, and the introduction of new features doesn't always succeed. Too often, the concerns of novices are ignored by the standards committee members. Some of the key features planned for C++0x, such as uniform initialization, the auto keyword (for deducing a variable type from its initializer), and concepts such as checking of template argument requirements should serve to make the language easier to use by nonexperts.

HD Do you see language metadata as a key foundation for future programming languages?

BS No. I personally feel most uncomfortable with nontrivial uses of metadata.

HD Do you see a fundamental shift in the future for concurrency if CPUs begin ramping up the number of cores? How might the concurrency challenge be addressed in C++0x?

BS C++0x provides the basics: a machine model suitable for multithreading, a set of low-level primitives for library building, and a threads and locks library API. I would love to see more (and probably will over the next few years), especially a simpler, higher-level concurrency model based on thread pools, futures, and message queues. We need to find automatic or near-automatic ways of spreading a computation over many processors and localizing activities on those processors. There is lots of work in this area—much in C++—but not yet a dominant model. Examples include STAPL from Texas A&M University and TBB from Intel.

HD What are your thoughts on general-purpose computing on graphics processing units (GPGPU)?

BS Tantalizing, but I don't have the practical experience to comment beyond the obvious that it takes a lot of skill to utilize a special-purpose processor.

HD Do you foresee High-Performance Computing (HPC) ultimately becoming transparent to programmers? Moreover, would this goal be one for a language or for a library or framework?

BS Somewhat transparent, only; I don't think concurrency could or should be completely transparent. For starters, error handling can be very different depending on the availability of processors, shared (or not) memory, distribution (or not), and latency. Approximating transparency where that is appropriate is and will remain a goal for new languages, new language features, and (my favorite) new libraries. The latter is only feasible if the underlying language provides the basic guarantees needed as a machine model and a set of very low-level primitives. C++0x will do that.

HD How is the design of C++0x coming along?

BS We are near the end—finally! At least I hope so—nothing is certain until the votes are in and towards the end things can get quite tense and emotional. The current plan has us voting out the complete new standard for public comment in June, giving us a new formal standard 12 to 18 months later. Obviously, I could write a book on this one topic: how do you make a standard, what's supposed to be the guiding principles, and exactly what's in it? I almost have; see my HOPL paper "Evolving a language in and for the real world: C++ 1991-2006" (available at research.att.com/~bs/hopl-almost-final.pdf) and anything with C++0x in the title on my home pages. If you are a glutton for punishment, you can look for "WG21" on the Web and find all the ISO C++ standards committee's papers (including all the proposals). If nothing else, it will convince you that it is a lot of work. Improving a widely used programming language is hard, especially one that is at the implementation layer of many, many tools, languages, and applications. You can also find a few videos by me and others online and on my C++ page.

Books and Phones

HD What are you currently reading?

BS On technical material, I'm back to Hennessy and Patterson for a refresher on machine architecture, and I'm trying to collect papers and articles that help people write good code (for a course I'm teaching). Finding such articles is much harder than I expected; academic papers tend to be very specialized and nonacademic papers are often high on promises but short on evidence (suggestions welcome). Then, of course, there is a steady stream of documents relating to the C++ standardization. I was about to refresh my Knuth, but someone has absconded with my volume III, so that'll have to wait. For pleasure, I'm rereading a bit of O'Brian's Aubrey and Maturin series. I'm trying to refresh my understanding of science, so currently just coming off a Richard Dawkins binge. I also recently finished Rodger's Command of the Ocean: A Naval History of Britain, 1649-1815 (hence the visit to O'Brian).

HD You said "I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone." Do you have a smartphone, and has this gotten any easier?

BS I'm not a great fan of phones. I prefer face-to-face communication and the written word if I cannot get that. Even the fanciest phone is not quite up to well-phrased e-mail. I use a slim phone that fits comfortably in my pocket and I don't use anywhere near all of its features. I'd give up just about any feature for sound quality and reliability. To be fair, user interfaces tend to be much better today than when I made that remark.

Howard Dierking is the Editor-in-Chief of MSDN Magazine.