By now the news has probably reached everyone interested in the evolution of C++0x: the ISO C++ committee voted to remove Concepts from the C++0x working draft at its July 2009 meeting in Frankfurt, Germany. Concepts were the flagship feature of C++0x, and their removal has been met with varying degrees of shock, disappointment and relief. In this post I’ll describe the effort to bring concepts into C++0x and the reasons that effort ultimately failed.
C++ programmers have always wanted a better template programming experience, and the notion of “constraints” for C++ templates go back at least as far as Bjarne Stroustrup’s The Design and Evolution of C++ (see section 15.4). Jeremy Siek and Andrew Lumsdaine extended this notion of constraints checking for “concepts”, and also illustrated how the use of archetypes can mimic type-checking the definition of a template (Siek2000). In 2003, Bjarne Stroustrup and Gabriel Dos Reis brought forward a series of proposals (N1510, N1522, N1536) exploring how concepts could be expressed within the C++ language itself.
My own involvement with concepts began in January of 2005, when I co-authored Concepts for C++0x, which came to be known as the “Indiana” proposal. Shortly afterward, Bjarne Stroustrup and Gabriel Dos Reis proposed A Concept Design (Rev. 1), which came to be known as the “Texas” proposal. Concepts were first discussed in the C++ committee at the April 2005 meeting in Lillehammer, Norway, and it was immediately apparent that the Indiana and Texas proposals were based on fundamentally different philosophies. Although there were several points of contention, the most fundamental disagreement was about the “matching” of a data type to a concept: the Texas proposal favored entirely implicit (automatic) matching (like auto concepts in the current specification), while the Indiana proposal favored an explicit statement of conformance that allowed remapping (like concept maps in the current specification).
Following Lillehammer, I spent much of the next six months implementing ConceptGCC, the first (and only) prototype compiler to implement concepts. The compiler was intended to provide a proof-of-concept, illustrating how a complete system might look within a real compiler. Experience with ConceptGCC helped us produce a drastically improved version of the “Indiana” proposal. I demonstrated ConceptGCC at the October, 2005 meeting. The committee’s reaction was generally favorable, but some members were very concerned by the rapid divergence of the two efforts. The authors were asked to work together to produce a consolidated proposal. We held a number of meetings to hash out the details, and eventually produced the first compromise proposal in June 2006. At the same time, development of ConceptGCC’s standard library continued, and we produced the first proposals to introduce concepts in the standard library (see committee documents N2036-N2041).
We held several meetings outside of the committee, and each new meeting brought more discussions and subsequent changes to the compromise proposal. The largest changes were the removal of “or” constraints, the introduction of scoped concept maps and the elimination of forwarding functions. Also during this time, I completed the first draft of the standard wording for concepts. Many revisions of the wording for both the language and the standard library followed.
Concepts were finally accepted into the C++0x working paper at the September 2008 meeting in San Francisco, and were incorporated into the first C++0x candidate draft (CD1). Overall, they were voted into the C++0x candidate draft as a series of fourteen coordinated proposals, covering the core language and a significant portion of the C++0x standard library.
The Road to Frankfurt
The six or seven months following the San Francisco meeting saw various refinements to the standard wording and standard library. As the Frankfurt meeting neared, two separate issues arose: concerns about implementation experience surfaced and the compromise that produced the concepts specification started to unravel.
The concerns about implementation experience focused on the inadequacies of ConceptGCC, such as its poor compile-time performance and its lack of some advanced features (e.g., scoped concept maps, associated templates). Committee members worried that, without a production-quality implementation to validate the full concepts-based standard library, there would be a significant number of defects in the concepts specification for the language and the library. At best, these defects would further delay the C++0x standard; at worst, we would ship a broken standard.
At the same time, there were numerous, heated discussions of concepts on the committee mailing lists. Most of the heat focused on a single perceived usability problem with the current specification: that, in some cases, users may have to write an “empty” concept map to satisfy the requirements of a constrained template in a library, and that users might view such a concept map as pure syntactic baggage. The discussions revolved around Bjarne Stroustrup’s paper “Simplifying the use of concepts.” Along with creating a general sense of unease about the design, these discussions illustrated plainly how fundamentally different the Indiana and Texas philosophies still were. In particular, Dr. Stroustrup’s paper proposed the elimination of so-called “explicit” concepts, which have been a fundamental part of concepts since 2005 and had been a particularly contentious issue from the beginning.
The Vote in Frankfurt
The C++ committee spent roughly half a day discussing the fate of concepts at the beginning of the Frankfurt meeting. Dr. Stroustrup requested a vote on the following three options:
- Continue with the current specification of concepts in C++0x.
- Make the changes suggested in “Simplifying the use of concepts” and retain concepts in C++0x.
- Remove concepts from C++0x.
Along with an overwhelming majority of committee members, I voted to remove concepts, because I felt that removing them was our best available option both for C++0x and for concepts as a language feature.
My natural inclination would have been to continue with the current specification, which I believe is fundamentally the right design. However, by this point it was clear that our compromise had shattered; we would need to rebuild confidence in concepts before they could be accepted by the wider C++ community. Moreover, the concerns about implementation experience were quite justifiable, and may by themselves have been reason enough to remove concepts from C++0x.
The second option involved making significant changes to the design while still trying to ship concepts as part of C++0x, which I found untenable. Any change of this magnitude coming this late within the development cycle carries significant risk. In this case, there was no implementation experience, no usage experience, and insufficient technical detail to verify that the new design would be functional. Remember that ConceptGCC was already considered by some to be inadequate implementation experience, so there certainly was not enough implementation experience for a modified version of that design. More importantly, I found it extremely unlikely that we would come to consensus on the proposed changes, given the long history of disagreements over this issue.
There were other options, such as delaying C++0x for several more years to allow a consensus to develop, but such delays were considered unacceptable. Removing concepts from C++0x was the only sensible option, and it does not mean that they are gone forever. To the contrary: the committee likes concepts and would consider them again, should a suitable proposal come forward. In my next article, I will discuss some of the lessons we’ve learned from this failure and outline an approach for future work.