Bjarne Stroustrup On Concepts, C++0x
An anonymous reader writes "Danny Kalev has an interview with Bjarne Stroustrup about the failure of concepts, the technical issues of concepts, whether the ISO committee's days are over, and whether C++ is at a dead-end. 'I don't think that concepts were doomed to fail. Also, I don't think concepts were trying to fix many things or to transform C++ into an almost new language. They were introduced to do one thing: provide direct language support to the by-far dominant use of templates: generic programming. They were intended to allow direct expression of what people already state in comments, in design documents, and in documentation. Every well-designed template is written with a notion of what is required from its arguments. For good code, those requirements are documented (think of the standard's requirements tables). That is, today most templates are designed using an informal notion of concepts.'"
Donkey Kong: The specification of concepts has taken seven years. By contrast, the standardization of the entire STL took about half that time. What is so complicated about concepts?
... etc.
Bull Shit! I count the concepts work as started in 2002! I presented my first design papers in 2003! In 1994 Alex Stepanov presented a complete implementation of the STL to Andrew Koenig and me, but 2002-to-2009 and 1994-to-1998 are not comparable time lines! Alex had been working on the STL from at least 1976!
What's really unfortunate is that he's one of the very few language maintainers out there that isn't of the mentality "Rah rah! My language/tool/design-philosophy/whatever is the solution to all your problems and will take over the world tomorrow." (phrase lifted from the interview) Wish we had more people like you out there, Stroustrup. Also, if this isn't fixed by now, I'm sorry Slashdot couldn't even get your name right in the title to this story.
My work here is dung.
No you need to calm down and thing about the previous designations of C and C++ standards: C++98, C99, etc. C++0x was intended to be a C++ standard released between 2000 and 2009; at this point, it looks like it is actually going to be released in 2010, and we'll all be calling it C++10.
Palm trees and 8
Templates are what Python calls 'duck typing'. ("If it looks like a duck and quacks like a duck...") Why not just do that? You could add methods for introspection and so forth...
My blog
It's named in parallel with language-revision names like Fortran77 and C99, that use the base language plus the last two digits of their revision year. When the process started years ago, though, they didn't know what year it would finish, but expected it to be in the 200x decade, hence "0x". So, C++0x. Now that the finalization has slipped past 2009, it's C++1x. When it actually comes out, it will have a year with no 'x', like C++10 or C++11.
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
I've seen a lot of people dramatize about concepts being removed from C++0x.
Really, it's no big deal. There are alternative solutions, like some based on SFINAE -- that has now been extended to arbitrary expressions --, that provide almost the same feature set, the same quality in error messages, and are not much harder or more verbose to write or use.
Actually, getting rid of concepts was probably the best solution for C++0x, since they were a lot of work to implement on top of not being that well polished, not integrating that well with the rest (concepts are not types, nor are they templates, they're a whole new category of things) which would probably have led to different categories of compliance to the new standard.
This even gives a new chance to more vital features, such as polymorphic lambdas (understand lambdas were the types of the arguments is not given and which thus exhibit parametric polymorphism), to now being reconsidered.
The main reason for not making GUI part of the standard is that there are already plenty of GUI libraries for C++, and nobody on the standards committee will be able to agree on which one should be used. This is in contrast with, say, file-based IO, which is implemented in roughly the same way on all platforms.
There are plenty of features that I would say are a lot more important than a GUI framework. A standard way to convert C style FILE pointers into an iostream would be a great feature, one that several vendors already implement as extensions. Even a standard way to open a network connection and represent it as an iostream would be a good thing to have, with the heavy focus on network applications these days. Also, move allocators out of the template argument list for containers, and representing them as class members instead -- if ever there was a perfect case for preferring composition, it is this. Also, improved i18n/l10n support (C++ is better than C in this regard, but there is a lot that remains to be done).
Palm trees and 8
Uncluttered article, without any extra crap and multiple pages. Printable = readable.
Do you realise that most of the guts of Windows is actually written in C++? And that the secretary of the C++ Standards Committe, Herb Sutter, works for Microsoft?
Are you even a C++ developer at all?
I would be willing to bet that some vendors that make more than one language are probably not too crazy about doing more with an open language like C++. Not that I would make any association with a large software vendor founded in the 1970s that leveraged a pretty good BASIC interpreter into operating system and tools dominance... but
Yeah, Microsoft is so uninterested in C++ that for the Visual C++ 2010 release that they've added in a whole bunch of new features including partial support for this new standard.
Can't we just skip "concepts", and move straightaway to "meta-concepts"? After all, a "concept" is just a concept itself, so with meta-concepts we'll be able to define "concepts" recursively. Which doesn't sound like a win, until you realize then you can redefine concepts to fit your own idiosyncratic needs. Like how in my code, the first thing I always do is overload "+" to mean "*", and vice versa. I've always liked them the other way around, not sure why. Anyway, back on point: Concepts by itself is like the 4-blade razor, a lame, stupid half-measure. The real prize, the 360-dunk-off-the-free-throw-line, is 5 blades on a razor. I move we skip "concepts" and go for the big win. Those effeminate Python dorks will have no answer to this, they'll be stunned to see just how inferior they really are. Who's with me on this?
Broader point: I'm sick and tired of these language designers not giving us enough features. For the last 20 years I've been waiting for a language that will allow me to redefine keywords. If that too much to ask? What if I don't happen to like "for", or "while", or "return"? Do you people lack vision, or competence, or both? Second thing on my must-have list is a pre-pre-processor. I'm tired of writing all these header files all the time. I want a way to generate them programmatically, at compile time. A small embedded scripting language would do fine, just make sure it has templates and operator overloading and multiple inheritance, so I can stretch my legs and get comfy with it. Come on people, start earning your paychecks and get some of this stuff done!
as it is, I think C++ is pretty much dead as it is, and its' probably going to have to be up to gcc to just grab the bull by the horns and implement new features by fiat and create a defacto standard.
Well, that's how it used to be - the standards committee generally checks what all the major implementations implement that isn't specified by the standard, and then try to get the common non-standard parts into the next standard. Basically - see what the industry is doing, and if they all seem to agree then standardise it.
I'm a minority race. Save your vitriol for white people.
C++ is far from dead in all piece of code that need performances. Intel released a C++ library called TBB to use multi-core architecture a few years ago. They do not believe it is dead. Parallel programming framework such as cilk stoped using C to use C++ to gain templates.
Don't get me wrong, for most task people don't care about the performance provided by a low level language and thus don't need it. It is even harmful to use C++ if you are not going to do it properly.
And let's not forget Intel C++. Intel hates C++0x so much that they decided to add the following C++0x features in Intel C++ 11.0 which has been available since November 2008: - Empty macro arguments - Variadic macros - Type long long - Trailing comma in enum definition - Concatenation of mixed-width string literals - Extended friend declarations - Use of ">>" to close two template argument lists - Relaxed rules for use of "typename" - Relaxed rules for disambiguation using the "template" keyword - Copy constructor does not need to be callable on direct reference - Binding to class rvalue - "extern template" to suppress instantiation of an entity - "auto" type specifier - decltype operator - static_assert - compliant __func__ - lambda expressions
What on earth does a GUI have to do with a language? A GUI belongs in the C++ specification about as much as Java belongs in the kernel.
Each has its place and is used when necessary and shouldn't be forced into a place it doesn't belong for convenience.
- Michael T. Babcock (Yes, I blog)
Qt 4.5 has been released LGPL. As long as you link to the Qt's dynamic libraries, you can completely close the rest of your app. Qt has become the standard cross-platform GUI framework for C++.
and we'll all be calling it C++10.
I, for one, will be calling it C++0x0A.
Reply to That ||
It is a big deal. The two most important things concepts were going to do was make generic programming in C++ (1) explicit and (2) accessible.
Currently, generic programming in C++ is supported through a number of template meta-programming patterns and practices, most of which exist as Boost tribal knowledge - hail King Dave!* It is implicit in many library designs, but there is nothing enforcing it at the language level. If you're not familiar with the concepts of generic programming (pun intended), it's easy to mistake what's going on in the standard libraries as something else. This is especially true if your primary use of the STL is to have polymorphic container classes - you might just design a generic extension to another language that completely misses the point of generic programming (see Java Generics).
At a more fundamental level, a lot of the power in generic programming comes from the specializations that are possible when you meet type requirements. Right now, there is no way, outside the documentation, to state requirements and possible specializations. Making this explicit in the language makes it clear to the library user what the requirements are and what specializations are available.
This leads into the accessibility problem. Generic Programming using template meta-programming is difficult. To use it, you have to understand both the template system and generic programming. The former is defined in the standard, but the latter, as mentioned above, is tribal knowledge. By making generic programming explicit in the language, it immediately becomes accessible to a large number of developers who didn't have the time, patience, or fortitude (dealing with the Boost mailing list requires a large supply of this) to become proficient with template-based generic programming.
As an analogy: consider object-oriented programming in C. Prior to (and even after) C++, lots of OO code was been developed in C. But, each object system was different and based on local best-practices. C++ (and Objective-C) took those practices and codified them into a language extension. As soon as that occurred, one method for OO was standardized. Developers no longer had to implement their own object systems and adhere to documented (but not language enforced) policies. And, with a standard set of rules around this flavor of OO, many other developers felt comfortable jumping in the the fray.
Concepts in C++ should have had the same effect for Generic Programming in C++ that C++ had for Object Oriented Programming in C. The should have democratized generic programming and brought forth a renaissance in C++ library design. Instead, petty politics killed the most exciting change to C-like languages in years.
-Chris
*(Dave - I mean that in the nicest sense... you've done a great job with Boost (oh, we need to jam again, too)).
The main difference that springs to mind is that duck typing in Python is dynamic (resolved at runtime), where-as the type system in C++ is static (resolved at compile-time).
Compile-time checking has two purposes: enforce contracts between methods and allow for optimization. I'll cover each of these in turn:
Dynamic languages have more overhead to dispatch a method call. But then static languages have to duplicate the template code for each type that it handles. It is disputed whether the more direct dispatch outweighs the overhead of loading the duplicated instructions into the CPU's instruction cache.
Types of arguments to methods make up part of a contract between a method and methods that call it. It's good to have a compiler that can verify some of a contract at compile time, but the halting problem implies that not all parts of all contracts can be expressed in a way that can a machine can verify. Fans of dynamic languages claim that purpose-written unit tests can verify contracts more thoroughly than a compiler's built-in checking, but fans of static languages claim that properly done static typing writes half the unit test for you.
Kalev's questions came across as ignorant and belligerent, but Stroustrup answered all of them intelligently, thoroughly and patiently. It's good to know that there are men like Stroustrup still working hard on C++, even though I no longer do much work in it.
They are supposed to make the claim against the area for which their language is most appropriate. Although to be fair, it is often the people who are marketing the self-help books that tend to be the most vocal advocates of a particular language. I remember picking up an early O'Reilly book on Perl in a bookstore and reading the introduction and putting it back on the shelf in disgust because of the zealousness of the advocacy in the introduction.
I have also been down the "should not" path on several languages much to my chagrin. Fortunately, I've paid the price allowing me to spare my students the pain.
Atlas stands on the earth and carries the celestial sphere on his shoulders.
The C+-* Language
* pronounced "C, more or less."
Unlike C++, C+- is a subject oriented language. Each C+- class instance known as a subject, holds hidden members, known as prejudices or undeclared preferences, which are impervious preferences, which are impervious to outside messages, as well as public members known as boasts or claims. The following C operators are overridden as shown:
C+- is a strongly typed language based on stereotyping and self-righteous logic. The Boolean variables TRUE and FALSE (known as constants in less realistic languages) are supplemented with CREDIBLE and DUBIOUS, which are fuzzier than Zadeh's traditional fuzzy categories. All Booleans can be declared with the modifiers strong and weak. Weak implication is said to "preserve deniability" and was added at the request of the D.O.D. to ensure compatability with future versions of Ada. Well-formed falsehoods (WFFs) are assignment-compatible with all Booleans. What-if and why-not interactions are aided by the special conditional evenifnot X then Y.
C+- supports information hiding and, among friend classes only, rumor sharing. Borrowing from the Eiffel lexicon, non-friend classes can be killed by arranging contracts. Note that friendships are intransitive, volatile, and non-Abelian.
Single and multiple inheritance mechanisms are implemented with random mutations. Disinheritance rules are covered by a complex probate protocol. In addition to base, derrived, virtual, and abstract classes, C+- supports gut classes. In certian locales, polygamous derivations and bastard classes are permitted. Elsewhere, loose coupling between classes is illegal, so the marriage and divorce operators may be needed:
Operator precedence rules can be suspended with the directive #pragma dwim, known as the "Do what I mean" pragma. ANSIfication will be firmly resisted. C+-'s slogan is "Be Your Own Standard."
http://baetzler.de/humor/c_more_or_less.html
It's kind of sad. The C++ committee has taken the general position that the underlying defects of C++ should be papered over by making it possible to write templates that hide the problem. But the hiding never quite works; the mold always seeps through the wallpaper.
The root of the problem is that C and C++ backed into a type system. Originally, C barely had types at all; there were ints and there were floats. Pointers and ints were almost interchangeable. Fields in structures were just offsets, and field names had to be unique across all structures. Gradually, C evolved into a strongly typed language. Sort of. "void *" was introduced as a sort of escape hatch for the type system.
More importantly, there was never a clear distinction made between arrays and pointers. That single design decision is responsible for most of the buffer overflows in the world. We should have had syntax like
int read(int fd, char buf[n]&, size_t n);
to replace the old
int read(int fd, char *buf, size_t n);
which says nothing about the size of the array. Right there is the cause of most buffer overflows - the language doesn't properly support talking about the size of arrays.
Part of the problem there was a major error in the original design of C++ - it didn't have "&" references. So you couldn't talk about a reference to an array; you had to use a pointer to the first element. That pointer has the type of the element, not of an array. Every time you write "char *buf" instead of "char buf[n]&", you're lying to the compiler. The cost of that lie is millions of crashes a day.
Instead of fixing the mess underneath, C++ papered it over. Arrays were wrapped with classes in the Standard Template Library. The STL is a good thing, but it's not good enough to totally replace built-in arrays. So real-world programs remain a mixture of ambiguous built-in arrays, pointers to arrays, and STL arrays.
Then the STL approached iteration as an extension of pointer arithmetic. For "compatibility" with C pointer arithmetic, iterators are not only unchecked, but are not explicitly bound to the collection over which they iterate. So the safety problems of C were carried over into STL arrays. This was another bad decision. Most modern languages approach iteration by providing a "do this to all that stuff" construct used for most common iteration cases. C++ does not.
This is why I'm so critical of the C++ committee. If they'd focused on safety, instead of cool but obscure template features, software would be much better today.
It is even harmful to use C++ if you are not going to do it properly.
For example:
Is that some kinda of filthy ASCII art?
Utilizing the synergization of benchmark e-solutions to pre-workaround action items!
Hehe, it does seem a pretty good symbol of C++'s syntax: bits of syntax that make sense individually turning into a monstrosity when combined.
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
Yukihiro Matsumoto of Ruby: "Why should you switch to Ruby? If you are happy with Perl or Python, you don't have to. But if you do feel there must be a better language, Ruby may be your language of choice." and then "I believe people want to express themselves when they program. They don't want to fight with the language. Programming languages must feel natural to programmers."
Nice job quoting him out of sequence, and implying that his response regarding his guiding philosophy is even relevant to the question that's posed to him about switching. And also, nice job omitting the phrase "I tried to..." from his guiding philosophy. Since such a qualifier implies personal doubt that he even achieved such a goal, that doubt was endangered your thesis, so kudos removing it -- that makes his response (that you've already completely distorted by quoting out of sequence, and quoted from a totally different question then the one you've put before it) sound even more absolute.
Stewart: Did you have a guiding philosophy when designing Ruby?
Matz: Yes, it's called the "principle of least surprise." I believe people want to express themselves when they program. They don't want to fight with the language. Programming languages must feel natural to programmers. I tried to make people enjoy programming and concentrate on the fun and creative part of programming when they use Ruby.
[...]
Stewart: Why should someone already familiar with Perl or Python switch to Ruby?
Matz: Why should you switch to Ruby? If you are happy with Perl or Python, you don't have to. But if you do feel there must be a better language, Ruby may be your language of choice. Learning a new language is harmless. It gives you new ideas and insights. You don't have to switch, just learn and try it. You may find yourself comfortable enough with Ruby to decide to switch to it.
He means adding a GUI to the STL, not the C++ language.
Stupid name, it should be
C+++=1
or is equiv
C+=2
C++0X is a syntax error!
Actually, the two forms aren't equivalent.
I mean, I was pretty annoyed when they said, "Hey, here's C++! We added that increment operator to show you that we made C better!" But, then, wouldn't you know it... Yeah, they made a better C, but what they actually gave to us was the same old C, as it was before they improved it. Later on I kept checking back to see if C++ really was substantially different from plain old C: and it was, but each time I looked at C++, the result was something different from what I'd seen before!
(C+++=1 simply wouldn't work, as C++ is an rvalue. Suppose D=C. Now, D == C++. But then, D != C++. And for that matter, C++ != C++. It's maddening, I tell you! And I don't think C+=2 is equal to anything at all...)
Bow-ties are cool.
Uncluttered article, without any extra crap and multiple pages. Printable == readable.
There fixed that for you.
You know, this tends to bug me a bit...
I mean, yeah, here we are talking about C++ in which "=" means assignment and "==" means an equality test... But the world at large is not governed by these definitions. An equation like "y = 3*x + 4" establishes a relationship in which the two sides of the equation are equal.
If you want to apply the meanings of C operators to English text, then really neither meaning is correct:
"Printable = Readable" - means "Henceforth, until further notice, 'Printable' will have the value that 'Readable' has now" (Assignment)
"Printable == Readable" - means "I want to know if 'Printable' and 'Readable' have the same value". (It's an equality test, not an equality assertion)
Bow-ties are cool.
What follows is all IMHO, of course you are welcome to your own opinion as well.
.. slightly .. but not enough for me to want them. Safer? Well not if you take into account the fact that you are using C++, probably the most dangerous language to work with of all. I'll cast the result of my collection operation manually, thanks.
I've struggled with large C++ codebases on a number of different projects, and while I admit that it is a powerful language, the problem is that there are a half a dozen different ways to do things. The fact that they are trying to give the language even more expressive power is just adding to the amount of rope that we as developers can hang ourselves with.
I yearn for a language which is functionally complete, compiled, small, fast, cross-platform, and oh, NO TEMPLATES PLEASE! Templates/Generics are a blight (a blight I say!) on modern programming -- to say I was pissed when they added them to C# and Java was an understatement. I like my languages without too much syntactic sugar, thanks.
In general, OO programming was never fully grokked by the masses. People spent far too much time trying to make their objects re-usable, and not enough time solving the problem at hand. At least with a language like C you are not fooling yourself, you can write in a procedural style and be happy.
Don't get me wrong, C has a lot of short-comings as well. D is almost perfect, but again, the template blight has reared its ugly head.
I know, a lot of people love templates, and they will argue that they are faster, or they are safer because of type-safety. Faster? Maybe
Plus, you make the compiler work really hard, and your project now takes 40 minutes to compile instead of 5. Thanks for the productivity gains, but no thanks!
f u cn rd ths, u r prbbly a lsy spllr.
I think you're overstating things a bit. It's certainly true that Concepts would have been an improvement, and would have made life a whole lot easier for a whole lot of people -- but let's face it, "renaissance" implies that we're currently in a dark age, and that's overstating things quite a bit. Point one, there's pretty substantial work being done right now. Point two, concepts are not going to allow an average programmer to just decide that they're going to recreate something like Spirit or Proto or Xpressive this afternoon, or anything like that.
:-)
I also the think "petty politics" is going overboard, at best. Howard Hinnant seems to have been the one who started the discussion at the last meeting that ultimately led to the removal of concepts from the draft standard -- and I find an accusation of his being involved with petty politics completely unbelievable. Quite the contrary, the (admittedly few) times I've talked with him, he struck me as a very level-headed person who was careful to evaluate ideas on their merits. Likewise, Beman Dawes, Bjarne himself, and (since you brought him up) Dave Abrahams don't seem to me exactly "petty politics" kinds of people either.
I'd also note that when it came to a vote, the overwhelming majority of committee members voted to remove them -- including (for one example) Douglas Gregor, the primary author of ConceptGCC, and one of the coauthors of both N1758 and N1849 (the two versions of the Indiana Proposal).
I think the vast majority of the committee simply believed that including concepts would delay the standard by a minimum of a couple years, and probably longer than that. A fair number of features originally intended to be included in C++0x have been removed for exactly the same reason, though quite a few others have localized enough effects that they're currently scheduled for a TR (Technical Report) rather than waiting for the next major update to the standard itself. Unfortunately, since they make fundamental changes to the type system, I don't think concepts can be added in the same way.
*(Dave - I mean that in the nicest sense... you've done a great job with Boost (oh, we need to jam again, too)).
I object your honor. Everybody knows a proper blues guitarist is short and fat, with black hair and a scraggly beard -- and this "Dave" is about as different from that as humanly possible!
The universe is a figment of its own imagination.
Now, we damn well know that, barring memory corruption or a serious bug in the STL, that this won't overrun the boundaries of the container. So why should i be range-checked ten million times?
It shouldn't. If the compiler, rather than the template library, knew about subscript checking, it could optimize much of it out. Most subscript checks in FOR loops can be hoisted out of the loop. Only a single check at loop entry is required, and that may resolve to a constant expression which is always true, eliminating the test entirely. Most C compilers today know how to hoist expressions and do basic strength reduction; that's why, for loops, pointer arithmetic and subscripts generate almost the same code in modern compilers.
But because the language doesn't know how big arrays are, the compiler can't help out here.
This is another price paid for papering over the problem with templates.