
Why Concepts didn’t make C++17 - ingve
http://honermann.net/blog/2016/03/06/why-concepts-didnt-make-cxx17/
======
_yosefk
"Concepts have been _widely expected_ to produce better error messages than
are currently produced when template instantiation fails. ... Unfortunately,
it turns out not to be so simple and use of concepts sometimes results in
_worse_ error messages. Constraint failures frequently manifest as overload
resolution failures resulting in a potentially long list of candidates, each
with its own list of reasons for rejection. Identifying the candidate that was
intended for a given use and then figuring out why the constraint failure
occurred, can be a worse experience than navigating a template instantiation
stack."

Perhaps someone indeed has been "widely expecting" a huge new source of
complexity in C++'s already very complex static binding rules to help produce
better error messages. I personally have never met that someone.

~~~
rat87
I'm not that into c++ but I thought better error messages was one of the main
if not the main point of concepts.

Basically the problem with templates is that there is no check for whether a
thing can be satisfy a function/operation till it's fully expanded and it's
hard to figure out where the "error" occurred during the template expansion. I
thought concepts were meant to be like type classes (and type class limits to
generics) in other languages so that the template writer could say that a
template parameter has to implement x,y,and z and if the type passed in
doesn't put the error at that expansion.

An optional constraint on a feature(templates) otherwise too powerful for good
error messages.

~~~
_yosefk
Well, they didn't stop at concepts as contracts to be checked, instead they
let you have a different oveload called depending on what concepts your
argument types implement. Hence the problem with having to sift through
potential overloads and reasons for rejection.

------
makecheck
Good. C++ still badly needs to go through a phase of tuning, deprecation and
removal before adding much more.

As I have said before, there have been shockingly poor design decisions in
some of the oldest and most fundamental standard libraries. Little to no work
has been done to introduce replacement APIs (or even replacement classes) that
would allow the deprecation of stupid features to begin.

~~~
PopsiclePete
It's extremely hard to take something away once you've given it. Once it's out
there, someone's using it and not everyone can afford to rewrite/re-test/re-
deploy just because you changed how iostreams work.

The C++ std. lib. is one of the worst abominations of over-engineered
disasters that I have ever seen in my life - how people even deal with
stdout/stdin without tearing their hair out is beyond me. I just go back to
printf and friends.

The fact that they had to have no fewer than 6 (or is it 8 now?) string types
before they got Unicode right... it's truly a sad state of affairs.

How can anyone look at that and not feel embarrassment to have been part of
those design decisions...

~~~
hacker_9
> It's extremely hard to take something away once you've given it

I would agree, but I look at c# and every time they introduce a new feature
the revamp the standard library just fine.. so C++ really has no excuse. C#
went from ArrayList -> List<T> -> IEnumerable<T>, and when async/await was
introduced they upgraded the methods that used plain old threads before or
just introduced new '{name}Async' methods. C++ is so bogged down in legacy at
this point that I would never use it given the alternatives of Rust/D.

~~~
coliveira
.NET is a closed platform that is controlled by Microsoft. When MS upgrades
the API, developers working there rejoice because now they can charge a lot of
money to upgrade the same systems. This is completely different from the
mindset of people using C++. There is no company controlling the language, and
code is written in C++ because of it is well known to be a language that
maintains backward compatibility.

------
hacker_9
Google Cached Page here [1] as the link is Down. The summary:

 _the committee failed to achieve consensus that Concepts, as specified in the
TS, has attained sufficient implementation and usage experience to be
confident in the current design. Basically, the committee did not say “no” to
concepts, it said “not yet.”_

[1]
[http://webcache.googleusercontent.com/search?q=cache:SurLIow...](http://webcache.googleusercontent.com/search?q=cache:SurLIowej1oJ:honermann.net/blog/%3Fp%3D3+&cd=3&hl=en&ct=clnk&gl=uk)

------
hellofunk
It's such a tease to see a headline I'm really interested in, only to wait for
the excitement to die down so the guy's web server is accessible again!

That's okay, I can wait -- concepts are something I really want to learn more
about and understand how they work, what they do, and every new article helps.

~~~
taspeotis
[http://webcache.googleusercontent.com/search?q=cache:http://...](http://webcache.googleusercontent.com/search?q=cache:http://honermann.net/blog/2016/03/06/why-
concepts-didnt-make-cxx17/)

~~~
hellofunk
Even this won't load for me. The browser still says it is waiting on the
source webserver.

~~~
nikbackm
Worked for me, but try the text-only version, that usually helps.

------
blackhole
I desperately, desperately want this feature, but I am glad that the committee
is determined to implement it _correctly_. C++ already has a convoluted,
complex syntax, it doesn't need to be made any more complicated.

~~~
thechao
A large portion of my dissertation revolved around the original C++0x concepts
proposal. There are some amazing things you can do with concepts; I think the
most important part of '0x concepts were 'concept_map's. However, I don't
think they're anywhere near as important as truly lightweight coroutines,
modules, etc. Mostly, they added a great deal of complexity to both the
compiler implementation and, more importantly, day-to-day coding. One thing I
don't see discussed is that if you don't want concepts without ugly &
nonintuitive "holes" (backdoors), they tend to leak _everywhere_
\---especially into code you'd never expect to find them in.

~~~
KKKKkkkk1
Sounds like your dissertation would be interesting to a lot of people on HN.
Mind sharing a link?

~~~
thechao

       http://oaktrust.library.tamu.edu/bitstream/handle/1969.1/ETD-TAMU-2010-05-7823/SMITH-DISSERTATION.pdf?sequence=2&isAllowed=y
    

As always, if something is correct, it's probably due to the good auspices of
my advisor; if something's wrong, I've lost all sense of shame, long since.

~~~
vmorgulis
I've seen the name of Gabriel Dos Reis in the committee member list. I wonder
if he gave up "the Pivot" (and Stroustrup too)...

------
pjmlp
Even though I hardly use C++ nowadays, concepts and modules were two features
I was looking forward to see in C++17, as a language geek.

However if it wasn't for my goal to write portable native code across mobile
OSes or the occasional weekend dive into LLVM, I would hardly touch C++
nowadays.

Waiting until C++20 for them, will mean 4 more years for alternatives to
slowly erode C++'s usage where its features aren't really that critical for
fulfilling the customer's use case.

On the other hand, people are still writing new Fortran code everyday, so
maybe those 4 years won't make a difference to those highly invested into C++.

~~~
coroutines
So... I'm not a C++ person. I think what I'm going to say next will sound like
someone who speaks English as a second language.

I don't like templates at all, I think it's just an even greater hack than how
the preprocessor might be used in C. The only place I have liked macros
[essentially] is in Lisp.

Something that bothers me about C++ is when a program might instantiate a
template like this: std::vector<int>

I'm sure vectors of ints is quite common. I wish C++ could share that
generated object code (not the instantiated template at compile-time). I've
heard of `extern template` but I don't think it gets used. Even then I wish
you didn't have to tell the compiler to look for external versions of the
template instance. I wish the compiler could aggressively look for and link to
instances that have the same binary representation - even if they have
disparate type information. That kind of analysis would probably be easier if
C++ had a defined ABI.

I am not a C++ person, so I am sure I'm wrong more than a few times in this
post. I wish C++ had a standard class to represent classes, so then we could
construct a very generic object heirarchy like Ruby. I don't just mean support
for reflection. I also want partially-defined classes for monkeypatching, but
people tend to disagree with that for ethical and performance reasons.

I've been happy to see a lot of languages enable expressiveness/freedom to do
whatever the hell you want in the last 10 years - instead of people forcing
their mentality of how you should code and think about problems.

</ramble-ramble>

I am happy concepts were not added. The preprocessor &and& templates should
die.

~~~
scott_s
I'm not sure what purpose your desire would serve, or even if it makes sense.
For example, this is a contradiction: "I wish the compiler could aggressively
look for and link to instances that have the same binary representation - even
if they have disparate type information."

The generated object code for thing<int> and thing<double> are likely to _not_
be identical, except for where the types are manipulated. Because thing<int>
and thing<double> generate entirely different classes, they can actually be
radically different. First, C++'s resolution rules allow them to be actually
different C++ code. But even if it reuses the C++ code, because that code then
goes through the optimization phases, what comes out the other side may not
have the kind of trivial relationship you're thinking of.

I don't think this is unique to C++; it should be true of any language that
has non-type erased generics that generates native code. I'm thinking of
Haskell, OCaml and Rust - but if people who know those languages and compiler
chain better think I'm wrong, please speak up.

Personally, I find C++'s templates to be extremely useful and powerful. I also
think they are demonstrably not as nearly as hackish as the C preprocessor, as
evidenced by the fact that they actually have knowledge of types. The C
preprocessor is just textual substitution, while C++'s templates are far, far
from that.

~~~
coroutines
I mean to say, the compiler might see std::vector<a> and std::vector<b> as
strictly separate types, but at their base/binary might be code that is
identical (effectively std::vector<int>). I am imagining that the compiler
would generate code for both, and not see the opportunity to deduplicate
identical object code. Again, I suspect I am naive here.

~~~
scott_s
I think you're saying that a and b are actually typedefs to the same type.
Yes, in that case I believe C++ compilers are smart enough to share code.

~~~
coroutines
That is not what I'm saying.

Example: You can have 2 struct types that each only contain an int with the
same member name. They would [likely] have the same binary representation. You
could then create 2 vector types specialized for each struct type. The code
for both vectors would handle the data in the same way - but the compiler
would view the vector types as _STRICTLY_ separate types.

I do not think this code would be uniquely shared - the compiler would
generate code for both vector types.

~~~
scott_s
Now I get what you're saying. I think it's possible for a C++ compiler to be
smart about this. But why is this such a big deal to you? Have you seen it
become an issue in projects you've worked on?

~~~
coroutines
Full disclosure: I have not had a problem with this.

It's just a theory I have that this is low-hanging fruit to reduce C++ binary
size.

You're less likely to define the same structure and methods of a type in
exactly the same way as someone else in C because we don't have the STL (ofc).
So it's probably a worse issue in C having a hundred different implementations
of a linked list or some array type across your system in each program.

I just think there's an opportunity to aggressively dedupe object code for
"representation-identical" types in C++.

~~~
scott_s
We've had optimizing C++ compilers for a long time - decades. I think it's
safe to assume that the low-hanging fruit was picked a long time ago.

~~~
coroutines
Forgive me here if I'm being argumentative, but I think we're both
speculating.

Someone further up the chain mentioned this sort of deduplication might be
done by the linker, but the code for the duplicated type would still exist in
the binary before linking.. An old but probably negligible complaint about C++
is that it creates larger binaries than if one were writing C. I think this is
something overlooked because C++ has a focus on type strictness - perhaps the
linker has a better way of seeing through abstractions..

I've identified where I think a problem lies.. now I just have to find proof
it :3

Unrelated: I wonder if identical libraries that exist in separate filesystem
trees (like in Docker) are deduped in memory, or if it's done by inode.

------
gpderetta
At this point, I don't really care any more about having concepts for better
error messages. I can usually figure out what the compiler is telling me after
skimming through the first 7 pages of template errors ;).

The reason I really want some sort of concept support is because the jumps you
have to go through to define a generic function that, for example, takes only
a range of some specific Ts are getting ridiculous. Especially if you have
multiple overloads.

Also, some of the syntactic sugar of the proposal is nice (implicit templates,
concept names instead of auto).

------
crb002
I want C++ to have a built in SMT solver expressive enough that it can do
concepts and a whole lot more. Maybe a new keyword constrain?

~~~
bjz_
Surely you could just write the SMT solver in templates, right? ;)

------
rilut
Is there a Rust equivalent for Concepts?

~~~
steveklabnik
Trait bounds, in my understanding.

