Frontier Exclusive Visionary Interview for hardware, software, system related business and and academia
C++: Past, Present and Future
System Design Frontier (SDF):
Any language leverages the power of expression behind one’s mind, whether concise or
verbose. Writing is a process of formulation, so is programming, though it is constrained. When you design
a language, such as C++, do you think syntax is more important, or semantics is more important? What’s the
key difference between language design and language implementation, taking C++ as an example?
Bjarne Stroustrup (BS):
The aim of programming language design is to allow direct expression of ideas in code.
That expression should be elegant and lead to efficient code.
Ideally, syntax directly corresponds to semantics. On the face of it, this is absurd as in theory we
have a free choice about the mapping from syntax to semantics. However, based on their experience, programmers
have strong expectation about what certain forms of syntax "ought to mean".
For example, they "known" that + should mean addition.
Similary, but without the centuries of use to back their opinion, they "know" that small, easy to type,
or implicit freatures should be cheap (i.e. run without noticeable overheads).
Also, "similar looking" syntax should map to similar semantics.
Many of the programmers' expectations are unreasonable and many are mutually inconsistent.
Many are simply design "warts" from earlier languages that have become familiar.
However, such concerns are important when you design a new language feature or a new library.
Also, it is not easy to judge what is reasonable reflections of genuinely valuable principles and what is
mere superstition. Syntax matters, often in perverse ways. Just look
how the oddities of the C syntax keep re-emerging in languages that don't even pretend to C compatibility.
The question about language design and implementation seems unrelated. We have a wealth of implementation
techniques and tools, which we can employ to meet our design goals for a language. Often historical
factors and compatibility constraints make life difficult. For example, we cannot use a new parser
technology if it cannot handle existing code and semantics. However, we basically know how to map
any language semantics that we can express to just about any machine.
One of the interesting and important
aspects of C++ is that there is a direct mapping of language features to machine primitives.
For example a char maps to a byte, an int to a register, a double to a floating-point register, and the
basic operations of C++ directly maps to machine instructions. In addition, C++'s abstraction
mechanisms maps to hardware through simple composition. This transparency (and consequential predictable
performance) are among the reasons that C++ is widely used for embedded systems programming.
For example, see my paper
"Abstraction and the C++ machine model". Proc. ICESS'04. December 2004
(http://www.research.att.com/~bs/abstraction-and-machine.pdf).
SDF:
You studied at Cambridge University by holding a student visa, and started to work at Bell Labs with a
working visa before you invented C++ in early days, was there any culture shocks when you moved from
one country to another? Were there any impacts on your inventing C++ at Bell Labs?
BS:
Yes, there was a significant culture shock each time. The shock lasted longer in the US than in the UK -
years rather than weeks. Maybe a young student is simply more flexible than a slightly older man with
a wife and a child, but I suspect that the cultural gap between UK and the US is larger than the gap
betweeen Denmark and the UK. I'm sure that the gap was far larger for me despite the fact that I had
to work hard just to understand what people said when I first came to the UK. My English was ok, but
it was school English and not English as the English spoke it.
There may be an indirect connection to language design. I had to work hard to understand the people
and the cultures. I had to do it conciously in a way a native doesn't have to. That forced me to
articulate my understanding. I have also had to explain about similarities to and differences from my native
country and culture (Denmark). I think that was good training for understanding workplace cultures,
organizations, and the background of individuals. By the time I had lived and worked a bit in the US,
I was less likely than most to take things for granted and more acustomed in explaining simple things
to people whose idea of what's "simple and natural" differed from mine. That doesn't help with the
technical aspects of language design, of course, but it does help understanding problems and articulating
solutions. Much of practical science and engineering is communications.
SDF:
We know you love history, philosophy and literature a lot, how did that help you in inventing C++ in some way?
Are there any joy and sadness during the period of C++ giving birth to be shared with us?
BS:
I think my reading of history helps me to be patient and not to try to force everything to be exactly
the way I want them to be. It gave me a strong appreciation of the limits of rational pursuation
and an intense dilike of some of the more effective demagogic techniques.
SDF:
Natural languages such as English or Chinese do not require standardization, yet programming languages
do need to be standardized in most cases, or we may call it Constrained Programming. Obviously C++ came
out as a de-facto language, and later on become a standardized language. What is the cause of effects
of Free Soft Movement and Open Source Initiative on the evolution of C++? How far away for us to go from
Constrained Programming to Free Programming, say programming in unconstrained voice or natural language?
BS:
Hmmm, the French (and others) may differ on the need for standardization of natural languages and all languages
have minimum standards of spelling, grammar, and pronounciation. If you deviate too far from the norm,
you run the risk of not being understood and meet even social disapproval.
I think the ideal of programming in something closely akin to a natural language is irrellevant
or even inappropriate for the areas of work that I'm concerned with: We want something flexible, but also
far better specified and precise than a natural language. A good programming language is by design an
artificial language without the ambiguities and shades of meaning inherent in essentially every sentence
of a natural language. To compare, I really don't want to discuss general relativity without equations:
English simply isn't up to expressing the fundamental ideas in many areas of physics. Nor is Chinese
- or any other natural language - up to the task of specifying a major computerized system. Conversely,
I wouldn't try to express Shakespeare in C++ :-)
By and large the open software movement has been very supportive of the ISO standardization of C++ from
the very start. As have the various commercial firms. All agree that unless we agree on what the language
is - and make sure nobody makes a political or commercial punch ball of it - we have something far less
valuable to the community. Standardization is a hard task and the volunteers on the C++ standards committee
deserve much more credit and support than they are usually given. Through their efforts, C++ is a much
better langugage today than it was in 1990 and C++0x will be significantly better still.
SDF:
During C++ programming, one typically first starts with classes specification, which is inherently a static
abstraction of a snap shot of dynamic real world in OO view (dynamic to static), followed by coding,
debugging and testing, in attempt to emulate the same snap shot of real world dynamically (static to dynamic).
From OO perspective, how does C++ address this OO modeling issue to help programmers to perform the manual
dynamic to static mapping and followed by static to dynamic mapping?
BS:
Had I had a chance to name the style of programming I like best,
it would have been "class-oriented programming", but then I'm not particularly
good at finding snappy names. The school of thought that I belong to - rooted in Simula
and related design philosophies - emphasizes the role of compile-time checking and flexible (static) type systems.
Reasoning about the behavior of a program has to be rooted in the (static) structure of the source code.
The focus should be on guarantees, invariant, etc. which are closely tied to
that static structure. This is the only way I know to effectively deal with correctness. Testing is
essential but cannot be systematic and complete without a good internal program structure - simple-minded
blackbox testing of any significant system is infeasible because of the exponential explosion of states.
So, I recommend people to think in terms of class invariants, exception handling guarantees, highly structured
resource management, etc. I should add that I intensely dislike debugging (as ah hoc and unsystematic)
and strongly prefer reasoning about source code and systematic testing. I also maintain what I consider
a healthy suspicion of all kinds of run-time code modification (self modifying code, dynamic linking,
plug-ins, run-time patches) because they too often bypasses careful analysis and whole-system testing.
SDF:
In one of your C++ books, The C++ Programming Language, you stated that, C++ is a general-purpose programming
language with a bias towards system programming that supports data abstraction with mechanisms ranging from
encapsulation, inheritance, template, overloading, while overloading (both operator and function) can be
viewed as control abstraction in someway, do you envision any other mechanisms for control abstraction
to better support OO programming?
BS:
"Control abstraction" is in many contexts not a well-defined term. I'd like to see concurrency (in many forms)
supported in C++. I expect we'll see a threads library and support for futures in C++0x (in this context,
a "future" is a place holder for the result of a thread - a form of simple-to-use synchronosation). There
is currently a lot of talk about "lambdas" for C++ (in this context, a lambda expression is an object that
can be sent somewhere to do an operation, using information from the the called and the calling context).
Incidentally, you can find all proposals for C++0x on the collittee's wensite:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/ . Some easier-to-read discussions can be found on my
publications page: http://www.research.att.com/~bs/papers.html
SDF:
In one of your C++ books, The C++ Programming Language, you stated that, C++ is a general-purpose programming
language with a bias towards system programming that supports OO programming, and OO programming was brought
up to the table to support software reuse better. As you know, software reuse is difficult to achieve because
of its measurability, granularity and intefacibility, from C++ perspective what is the best granularity we
should start to better address software reusability, if there is any?
BS:
I don't think I present reuse as a reason for object-oriented programming. I usually, see reuse as a consequence
of good, flexible design and efficient implementation.
The easiest "things" to "reuse" are the huge and the tiny components: whole applications (e.g., a browser or
a compiler) and simple functions (e.g., sqrt()). Unix did a good job at letting people reuse complete
programs in the form of processes. The difficult granularity is "the medium" such as classes, class
hierarchies, and libraries.
C++ primarily relies on re-use of source code and of object-code libraries
(statically or dynamically linked); it does not privides it's own notion of a "component" but relies on
the platform on which it runs. This is obviously both an advantage (it can use every facility of the host
system) and a disadvantage (code that does use every facility is rarely portable). C++'s greatest weaknesses
in this area is the lack of a C++ ABI on some platforms and the lack of a native notion of a dynamically
linked library. The latter is likely to be remedied by C++0x whereas the former depends on the compiler
vendors, and they have so far not been all that interested in collaborating with each other on this.
C++'s strenght in this are is the flexibility offered by the wealth programming styles it support.
The combination of object-oriented programming and generic programming is extermely powerful when
it comes to reuse, with abstract classes providing precise interfaces that can be easily matched
for separately compiled code and templates that allows flexibility in composition and performance
beyond what object-oriented techniques offer. The support for generic programming will be significantly
improved in C++0x. The notion of concept will both address the major problems with checking of template
code and increase the flexibility and ease of use further. In this context, a concept is a language
construct that expresses required properties of a type, a set ot types, or a set of types and integers).
See for example,
Bjarne Stroustrup: A brief look at C++0x. (http://www.artima.com/cppsource/cpp0x.html)
Or if you have the stomac for a more technical paper: Douglas Gregor, et al:
"Concepts: Linguistic Support for Generic Programming in C++". OOPSLA'06.
(http://www.research.att.com/~bs/oopsla06.pdf)
SDF:
From your own perspective, as the original designer of C++, what is the Pros and Cons of C++ for main-stream
applications as of today (after deployment in various industries for 20-yr or so)?
BS:
Pros: flexibility, generality, performance, portability, good tool support, available on more platforms than
any competitor except C, access to hardware and system resources, good availability of programmers and designers.
Cons: complexity, sub-optimal use caused by poor teaching and myths.
Obviously C++ isn't perfect - no language is - but it is curious how often C++ is underrated. Consider
this list of applications: http://www.research.att.com/~bs/applications.html. C++ succeeded because it
had a unique combination of features and possibly even more because compared to other languages it lacks
fatal flaws in more areas. For any one area, you can find a simpler alternative, but the "simplicity" of
that alternative becomes a serious problem in another area. C++ has many flaws, but those flaws are very
rarely fatal.
After watching "the industry" for 30 years or so, I'm extremely reluctant to define "mainstream" in any
narrow or particularly precise way. Just as you think you know what it is, some hitherto ignored field
becomes the focus. Think of the move from mainframes to PCs and the emergence of the web. Each move
leaves languages specialized for the "previous mainstream" in the dust to the advantage of general,
portable, and flexible languages. Raw efficiency also matter in such shifts because systems relying on
efficiency of high-level components suffer when the specialization implied by such high-level components
become misdirected.
SDF:
From C to C++ migration, one of the biggest reasons for the rapid adoption of C++ is that, the programming
paradigm shifting from imperative (procedural) programming to OO programming. As time goes, there might
be a new dominating programming paradigm giving birth, will C++ be upgraded to fit for the upcoming new
programming paradigm, or a brand new language will come out standing on the giant’s (C++’s) shoulder?
BS:
In the long run, obviously C++ will be replaced. Hopefully, by something much better - "A giant" as you
phrase it. However, as the proverb goes "in the long run we'll all be dead" and for a long time yet,
C++ will have much to offer.
I never saw C++ as "just an object-oriented language". I always aimed for it to support a variety
of languages. For example, see my presentation: "Why C++ isn't just an Object-Oriented
Programming Language". from OOPSLA'95. (http://www.research.att.com/~bs/oopsla.pdf).
Many complain that C++ isn't evolving fast enough and many complain that it is evolving too fast.
That's a sign that the rate of growth is in the right ballpark. I would have preferred a faster rate
of evolution of C++ language features and especially a faster adoption of major C++ libraries.
However, nobody can get all they want, and that's good - the wishes of an individual (however,
experienced) could easily become a burden to the community by being too narrowly based.
Stability is essential for real-world code. If we didn't have to maintain compatibility, we could have
much better languages for writing new code - but they would be useless for major projects. We need languages
that both adapts to new challenges and preserve the correctness of old code and a tools infrastructure
that supports them. Many C++ compilers still have an "ARM compatibility" switch to allow compilation of
1989-vintage code (and that implies support for 1985-vintage code; code written for the first
commercial C++ release).
Obviously, this concern for compatibility and stability slows the evolution of C++ and complicates the
design and implementation of new features. However, steady progress has been maintained since 1985 and
That will not stop now. C++0x is scheduled to be C++09. There is no reason to think that C++0x will be
the end of C++'s evolution either. On the contrary, in adition to stability, a steady infusion of
new ideas is essential to a lively and productive user community.
Back to Home Page