Parallel

The C++0x "Remove Concepts" Decision

Technical Issues

The unresolved issue about "concepts" focused on the distinction between explicit and implicit "concept" maps (see [BS2009]):

Should a type that meets the requirements of a "concept" automatically be accepted where the "concept" is required (e.g. should a type X that provides +, -, *, and / with suitable parameters automatically match a "concept" C that requires the usual arithmetic operations with suitable parameters) or should an additional explicit statement (a "concept" map from X to C) that a match is intentional be required? (My answer: Use automatic match in almost all cases).

Should there be a choice between automatic and explicit "concepts" and should a designer of a "concept" be able to force every user to follow his choice? (My answer: All "concepts" should be automatic).

Should a type X that provides a member operation X::begin() be considered a match for a "concept" C<T> that requires a function begin(T) or should a user supply a "concept" map from T to C? An example is std::vector and std::Range. (My answer: It should match).

The answers "status quo before Frankfurt" all differ from my suggestions. Obviously, I have had to simplify my explanation here and omit most details and most rationale.

I cannot reenact the whole technical discussion here, but this is my conclusion: In the "status quo" design, "concept" maps are used for two things:

To map types to "concepts" by adding/mapping attributes and

To assert that a type matches a "concept."

Somehow, the latter came to be seen an essential function by some people, rather than an unfortunate rare necessity. When two "concepts" differ semantically, what is needed is not an assertion that a type meets one and not the other "concept" (this is, at best, a workaround -- an indirect and elaborate attack on the fundamental problem), but an assertion that a type has the semantics of the one and not the other "concepts" (fulfills the axiom(s) of the one and not the other "concept").

For example, the STL input iterator and forward iterator have a key semantic difference: you can traverse a sequence defined by forward iterators twice, but not a sequence defined by input iterators; e.g., applying a multi-pass algorithm on an input stream is not a good idea. The solution in "status quo" is to force every user to say what types match a forward iterator and what types match an input iterator. My suggested solution adds up to: If (and only if) you want to use semantics that are not common to two "concepts" and the compiler cannot deduce which "concept" is a better match for your type, you have to say which semantics your type supplies; e.g., "my type supports multi-pass semantics." One might say, "When all you have is a 'concept' map, everything looks like needing a type/'concept' assertion."

At the Frankfurt meeting, I summarized:

Why do we want "concepts"?

To make requirement on types used as template arguments explicit

Precise documentation

Better error messages

Overloading

Different people have different views and priorities. However, at this high level, there can be confusion -- but little or no controversy. Every half-way reasonable "concept" design offers that.

What concerns do people have?

Programmability

Complexity of formal specification

Compile time

Run time

My personal concerns focus on "programmability" (ease of use, generality, teachability, scalability) and the complexity of the formal specification (40 pages of standards text) is secondary. Others worry about compile time and run time. However, I think the experimental implementation (ConceptGCC [Gregor2006]) shows that run time for constrained templates (using "concepts") can be made as good as or better than current unconstrained templates. ConceptGCC is indeed very slow, but I don't consider that fundamental. When it comes to validating an idea, we hit the traditional dilemma. With only minor oversimplification, the horns of the dilemma are:

"Don't standardize without commercial implementation"

"Major implementers do not implement without a standard"

Somehow, a detailed design and an experimental implementation have to become the basis for a compromise.

My principles for "concepts" are:

Duck typing

The key to the success of templates for GP (compared to OO with interfaces and more)

Substitutability

Never call a function with a stronger precondition than is "guaranteed"

"Accidental match" is a minor problem

Not in the top 100 problems

My "minimal fixes" to "concepts" as present in the pre-Frankfurt working paper were:

No C++0x, Long Live C++1x

Even after cutting "concepts," the next C++ standard may be delayed. Sadly, there will be no C++0x (unless you count the minor corrections in C++03). We must wait for C++1x, and hope that 'x' will be a low digit. There is hope because C++1x is now feature complete (excepting the possibility of some national standards bodies effectively insisting on some feature present in the formal proposal for the standard). "All" that is left is the massive work of resolving outstanding technical issues and comments.

A list of features and some discussion can be found on my C++0x FAQ. Here is a subset:

Even without "concepts," C++1x will be a massive improvement on C++98, especially when you consider that these features (and more) are designed to interoperate for maximum expressiveness and flexibility. I hope we will see "concepts" in a revision of C++ in maybe five years. Maybe we could call that C++1y or even "C++y!".

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!