a bit of background for concepts and C++17—Bjarne Stroustrup

Save to:
Instapaper Pocket Readability

In about 1987, I tried to design templates with proper interfaces. I failed. I wanted three properties for templates: full generality/expressiveness, zero overhead compared to hand coding, and good interfaces. I got Turing completeness, better than hand-coding performance, and lousy interfaces. The lack of well-specified interfaces led to the spectacularly bad error messages we saw over the years. The other two properties made templates a run-away success.

The solution to the interface specification problem was named “concepts” by Alex Stepanov. A concept is a set of requirements on a set of template arguments. “Concepts” is currently an ISO TS and it is proposed to be put into the standard proper for C++17. A concept is a compile-time predicate. For example, if a template takes a type argument, we can specify that an argument, T, can be an iterator, Iterator<T>, a random access iterator, Random_access_iterator<T>, or maybe a number, Number<T>. Similarly, we can specify that a set of template arguments must meet a predicate, for example Mergeable<In1, In2, Out>. This is very expressive and nicely cheap to compile (cheaper than using template metaprogramming workarounds). Students can use it after a lecture or two. You can, of course, define your own concepts and we can have libraries of concepts. Concepts enable overloading and eliminate the need for a lot of ad-hoc metaprogramming.

It was not easy to get to this point. In the early 2000s there were several ideas, including the one that became the current approach. However, we struggled with an approach based on specifying requirements as sets of functions. Dealing with implicit conversions was hard, interactions between existing unconstrained templates and templates with concepts were hard to manage, and writing a compiler that generated acceptable code took heroic efforts by Doug Gregor. Compilation speed was nowhere near acceptable, though. In the end, the committee pulled the plug on the C++0x concepts.

But we still wanted and needed concepts! Together with Gabriel Dos Reis and Andrew Sutton, I started to re-design concepts from scratch. In 2011, Alex Stepanov called a meeting in Palo Alto, where a largish group, including Sean Parent and Andrew Lumsdaine, attacked the problem from the user’s perspective: What would a properly constrained STL look like? Then, we went home to invent language mechanisms to approximate that ideal. That re-booted of the standards effort and led to the current TS and compiler. Andrew Sutton’s implementation has been used for over three years now and is part of GCC 6.0.

The current concept design focuses on the specification of interfaces. This has led some people to (wrongly) conjecture that we did not care about checking of template definitions and that concepts (as opposed to C++0x concepts) could not be used for that. In reality, the 2006 POPL paper shows how to do definition checking, Gabriel Dos Reis’ experimental language Liz implements those ideas, and recently Andrew Sutton quickly demonstrated that our predicate model easily handles definition checking even when implicit conversions and move operations are used. What we do worry about is how to gradually convert large C+98-style code bases to use definition checking and how to allow data collection, tracing, telemetry, etc. without interface changes.

We should have concepts in C++17, not just in a TS. “Concepts” as specified in the TS is an immensely useful feature for designers of generic code and together with constexpr functions lead to greatly simplified and more maintainable code. Sadly, the concepts-based Ranges library is by some deemed not ready for C++17, so it is likely to stay a TS for a while, – even though concepts were designed to exactly match the requirements of the STL algorithms.

Add a Comment

You must sign in or register to add a comment.

Comments (12)

0 0

Unoid said on Feb 27, 2016 10:07 AM:

Sorry if this looks OT. I wonder if concepts Could be used not only in template parameter constraining, but also in concret type constraining. i.e in declaration of non-template types, so that the library programmer doesn't forget to provide required class interface?


class old_style_class_decl;//no constraints.

template<typename T> concept bool S=......

//implementation of class 'new_style_S_class_decl' must satisfy S constraints or compilation fails:
class S new_style_S_class_decl;

0 0

Bjarne Stroustrup said on Feb 27, 2016 10:53 AM:

Try this:

class X { ... };

static_assert(Regular<X>(),"irregular!");

You already have it (given concepts grin)
0 0

NoSenseEtAl said on Feb 27, 2016 05:20 PM:

I would rather have ranges than concepts in C++17 since ranges actually work and are much more useful, but I guess certain somebody will use his personal influence to make reverse happen.
3 0

Bjarne Stroustrup said on Feb 27, 2016 05:27 PM:

I think you underestimate "concepts."

Ranges are based on concepts.

Apart from that, I suspect you overestimate "a certain somebody"'s "personal influence".

I would very much like both.
0 0

NoSenseEtAl said on Feb 28, 2016 08:10 PM:

Well current proposal of concepts can not check that implementation is not breaking the contract it claims to have.
Enough for me to say concepts are overrated.
I am not expecting Haskelly compiler determining the type classes(you write a template that uses operator[] and == and compiler infers concepts(RandomAccessContainer, EqualityComparable) on inputs, something like:
" ghci> :t (>)
(>) :: (Ord a) => a -> a -> Bool ")
but "checking of constrained template definitions" is a must.
I know your argument is that there will never be a perfect proposal, but then again IIR C++OX concepts were disaster and you still were upset they got removed, only to later say that you changed your view on the matter of their removal.

That being said ISO committee is packed with experts so if you convince 75% of them I guess I am wrong. smile

0 0

rhl said on Feb 28, 2016 09:56 PM:

Why does it matter if the current proposal does not have definition checking? we could get it in the next release. can a compiler flag not disable this functionality? at the very least -std=c++17. Why not attempt to apply concepts to the STL and if there are any modifications we put that in C++17. I would rather have concepts (and modules) than I would any other C++17 feature, but who am I besides a user.
0 0

NoSenseEtAl said on Feb 28, 2016 09:57 PM:

@rhl http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0240r0.html
0 0

rhl said on Feb 28, 2016 10:00 PM:

@NoSenseEtAl I have read that. My comments aren't a submitted paper, but my proposal is that compiler flags solve the problem of forward compatibility if a user writes incorrect code. Although I agree that not applying concepts to the STL is a mistake. It seems reasonable that this should all work out though, but we should go through that exercise.
0 0

NoSenseEtAl said on Feb 28, 2016 10:02 PM:

I dont have much to say beyond what I said, but versioning language with compiler flags is a horrible idea. IMAO ofc. I know we have different flags for different standards, but there should never be 2 options for the current C++.
0 0

ccSadegh said on Feb 29, 2016 02:18 AM:

I just registered here to say thank you (and all members of the committee) for all your efforts to make C++ a better programming language in the future.

@NoSenseEtAl: C++ will be evolved (even more) by the facts about the current state of the language, available tools and etc.
0 0

Bjarne Stroustrup said on Feb 29, 2016 05:55 AM:

The current proposal checks interfaces and that's where the main benefits for users are, but not template definitions. That has been explicit from the start.

We know how to check definitions (see the POPL paper and the Liz paper, and Andrew Sutton have dome some experiments with the GCC implementation). However, we are not certain if and how we should do that checking. We need to explore how to introduce template definition checking into large code bases with traditional uses of templates. We think we know how to and that it is not difficult, but we have to experiment more. Also, we need to consider how to do various forms of data gathering without disturbing interfaces.

C++0x concepts would have been a disaster. I agreed that their removal was necessary. I and most other proponents of concepts said at the time that we wanted concepts back in some form or other when we could do them right, and now we can. I never changed my mind about that.

The current concepts have been applied to the STL - and much more - (e.g., see the Ranges TS and Andrew Sutton's Origin libraries) but not everybody is convinced that we are ready for STL2 just now.
0 0

Unoid said on Mar 2, 2016 12:10 PM:

I actually implied constraint forward declarations in my earlier post. I do not believe this can be done via static_assert. Is it unacceptable to hide the layout of a class that is supposed to be used as a type argument of constraint templates?