views:

1474

answers:

9

As you may have heard, the last meeting of the C++ standards committee voted to remove concepts from the next C++ standard. Of course, this will affect other features and would seem to throw the standard wide open again. If that is the case, which other features do you think should be stripped away (or added), and why?

Links:

Removal of Concepts -- Danny Kalev (on the decision to remove concepts)

Simplifying the use of Concepts -- Bjarne Stroustrup (on the problems with concepts as they look now)

The Long Pole Gets Longer -- Martin Tasker (on the impact to the schedule for C++0x if concepts have to be fixed)

The C++0x "Remove Concepts" Decision - Stroustrup on the issue on Dr. Dobbs

Trip Report: Exit Concepts, Final ISO C++ Draft in ~18 Months - Herb Sutter

Concepts Get Voted Off The C++0x Island - Jeremy Siek defending the current Concepts spec

What Happened in Frankfurt? - Doug Gregor on C++Next (on the history and removal of Concepts).

+5  A: 

None, I think the rest of the draft was great - a large number of very small pieces that can be correctly implemented independently, allowing vendors to evolve toward complete support and allowing users to take a "shopping list" approach.

Quite a different situation with contracts, as they were like a whole new parallel type system and would have been very likely to have led to different compilers ending up with their own backward compatibility problems, very similar to CSS in web browsers.

Daniel Earwicker
Yeah, concepts had become a really major feature touching almost every part of the standard. That made them dangerous, and of course, made it essential that they got it right the first time, or we would have risked a mess similar to CSS and other web standards. C++ could not afford that. +1
jalf
+1  A: 

The un-named function / lambda function stuff makes me nervous. Function objects are perfectly good and are explicit, thus easier to read and find.

On the other hand I kinda liked concepts, though I certainly would not have used them every day.

Eric M
I don't know how the committee is proposing lambda functions, but if it's anything like C#'s, it's a very worthy addition to the language.
Pedro d'Aquino
I like lambdas. They make it easy to write shorter code, without the weird bloat you have to write today
Johannes Schaub - litb
@Pedro - it's a very similar addition, just capturing a commonly-used pattern in a succinct syntax. If the user has to give something a name just so they can refer to it once, it's a likely spot to add some sugar to the language. People who like writing out the same ugly pattern every time are free to continue doing so, of course! :)
Daniel Earwicker
Eric M
You can put a block after `while (n != 0)` - does that block have a name?
Daniel Earwicker
@Earwicker If you refer to something in source code it will not be once almost for sure :)
Piotr Dobrogost
That's because you're only counting the pieces that have names and hence are referred to, instead of simply appearing nested at the one location they are needed. All programs consist of a lot of chunks of unique code, many of which it would make no sense to jump into; they only make sense in the context they are embedded in. The lack of lambdas forces the user to pull code out of context and then laboriously write the necessary plumbing to feed data in and out of it.
Daniel Earwicker
To put it another way, a while loop "refers" to the block or statement immediately following it. Wouldn't make a lot of sense for anything else to refer to it, and so there's no reason to force users to think of a name for it.
Daniel Earwicker
lambdas make a good picture together with other features. condition variables for example will be able to `c.wait([ })` This would look awfully bloated without lambdas
Johannes Schaub - litb
@hoohoo: I'd recommend trying out a functional programming language when you have the time. The flexibility that lambdas give you is rather eye-opening, and gives you new ways of approaching problems - and, even, of constructing functions. They're not to be underestimated.
greyfade
c.wait(var(count) == 1); Bloated ?
keraba
Take a look at http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions - that's how they implemented it.
shash
Lambdas are basically the one missing piece in making STL algorithms *really* shine. Having to define functors is tedious and takes up a lot of space, sometimes making a plain for loop more attractive than std::for_each. Being able to inline the functor by declaring it as a lambda finally makes for_each and similar algorithms easy to use.
jalf
@keraba, no it's not, but it's a hack. Try to call v.begin() with your notation.
Johannes Schaub - litb
I can't count how many times I've said "screw this" and written a manual loop rather than build a custom functor for std::for_each. Lambdas will be incredibly useful.
Tyler McHenry
Mostly for Earwicker: an 'if () {block}' has no name, but it is contained in a function or method that does. I commented imprecisely. I mean that: functions or methods are named blocks ie return_type function_name(args) { block }, where the block may contain other blocks. In the absence of the lambda stuff, one cannot have an uncontained block floating around... you can start at main() and trace the flow of a program by following the function calls around. If I have lambdas then I think I would get lost because they don't have names (and as I noted above, I could be wrong about this).
Eric M
+8  A: 

Personally, I want C++ to finally break away from C. No more pre-processor, no more header files. I basically want D, but without all the stuff that D tacks on, using the STL.

Randolpho
This is exactly how I feel. I hate the old C crap that gets in the way.
GMan
Amen to that. Toasting the C pre-processor ought to qualify the standards committe that does it for a Nobel peace prize. What would society do with the sudden burst of productivity?
T.E.D.
I wouldn't say I'm a macro fan, but there are a few I'd be hard-pressed to replace with any other current mechanism.
anon
I like header files.
Paul Nathan
@Paul - some people pay good money to be whipped!
Daniel Earwicker
@Earwicker Then include (ha-ha) me in for a bit of flage - I like them too.
anon
There are some things that make good use of preprocessor macros. I am thinking of boost::bind/boost::function and probably others...
David Rodríguez - dribeas
Okay, who's next for a bit of pun-ishment?
Daniel Earwicker
Nothing that breaks backward compatibility can be seriously considered for the new standard. There is too much existing C++ code outside that needs to work.
Nemanja Trifunovic
If you want D, use D, not C++.
Ditching the preprocessor would be great, but replacements would have to be added. There are quite a few features that still depend on the preprocessor (the assert macro, for example). Headers are horrible. Luckily they're still planning to get around to that module system later, afaik, so who knows, perhaps one day we won't need headers.
jalf
@mmutz: the point is that I *don't* want D, because D does things stupid. It started out with a great premise: ditch the preprocessor and use a symbol table rather than requiring header files, then went ass crazy with all the changes it did. I just want C++ the way C++ is, but without forward declaration, headers, and a preprocessor.
Randolpho
@Randolpho, you can have part of your wish courtesy of Lazy C++, at www.lazycplusplus.com.
Iceman
@Kevin: Maybe, but it's a monkeypatch that hides the issue rather than fixes it.
Randolpho
You may want to see this thread about why macros are still needed in C++ http://stackoverflow.com/questions/96196/when-are-c-macros-beneficial
Motti
@Motti: I've read them all. About half are due to the deficiencies of having header files and (ironically) macros themselves. The rest are thing that you Should Not Do(tm).
Randolpho
Header files are beautiful flowers, full of light and joy and goodness.
Eric M
+3  A: 

To me the problem is not what other features should be stripped away, but how complex will other features be after concepts have been removed. That and how much longer will it take for the rest of the features to be rephrased without concepts.

A lot of features assumed that concepts would be accepted into the language and the wording is expressed in terms of concepts. (I wonder if any proposed feature depends on concepts).

I also wonder how other libraries will evolve (think boost::type_traits) to take the niche left by concepts. Part of what concepts provided can be implemented (even if in a more cumbersome way) in terms of traits applied to the type arguments.

To me, the most important thing that concepts added to the language was an expressive formulation of compilation errors, which is nowadays one of the places where C++ is most criticized.

R.I.P. concepts.

David Rodríguez - dribeas
Personally I suspect this won't be rocket science (though the result will obviously take months to review carefully). Any feature that is specified in terms of concepts can simply state the signatures of the operations it requires on types. The standard could easily retain a limited version of concepts just "on paper", purely as an aid to unambigious specification.
Daniel Earwicker
Concepts "on paper" as a tool for terse and unambiguous specification is a very good idea.
Piotr Dobrogost
From what I can tell, the only real casualty without concepts is "foreach", and that is a relatively small feature and so should be easy to fix.
Richard Corden
According to Herb Sutter's blog post, the range-based for loop was the only feature that depended on concepts, and that was fixed during the meeting.
jalf
+1  A: 

Strip away the pages of error messages on template code!

IIRC concepts should solve a big C++ coder problem: Human readable error messages for the STL. Its bad news that this issue isn't addressed.

Maik Beckmann
That is what Concepts tried to achieve
David Rodríguez - dribeas
That's a quality of implementation issue for the compiler - nothing to do with the standard.
anon
@Neil: Still, it would be nice to have a certain standard of quality applied to make the errors a bit easier to decipher. Error log filters are all well and good, but... wouldn't it be nicer if the compiler filtered them out for you in the first place?
greyfade
Ah, you young folk don't know when you are well off! The Glockenspiel compiler (cfront derived, late 80s) used to simply core dump if it came across any code it particularly disliked (which was quite a bit). This was (btiefly) the standard compiler at the training company I worked for - the paying customers were not amused.
anon
@greyfade I basically agree. Some sort of "precis the message" switch would be nice. But sometimes you need the whole shebang.
anon
+3  A: 

There are two things I think should be added to C++0x, I've thought of both these myself and then found that others have suggested them before but it doesn't seem like they're going to happen.

1. Defaulting Move Constructors and Move Assignment Operators

Writing a move constructor is a manual and error prone activity, if a member is added it must be added to the move constructor and assignment operators and std::move must be used religiously. That's why I think these functions should be defaultable.

movable(movable&&) = default;
movable& operator=(movable&&) = default;

Edit (2009-10-01): Looks like this is going to happen after all.

2. Override Type Deduction for Expression Templates

Expression templates often define types that should not be used directly, a case in point is the return value of std::vector<bool> operator[](size_type n), if auto or decltype are used on this kind of object unexpected behaviour may ensue. Therefore a type should be able to say what type it should be deduced to be (or prevent deduction using = delete syntax).

Example for vector addition.

// lazy evaluation of vector addition
template<typename T, class V1, class V2>
class vector_add {
     V1& lhs_;
     V2& rhs_;
public:
     T operator[](size_t n) const
     { return lhs_[n] + rhs_[n]; }
     // If used by auto or decltype perform eager creation of vector 
     std::vector<T> operator auto() const 
     {
         if (lhs_.size() != rhs_.size()) 
             throw std::exception("Vectors aren't same size");
         std::vector<T> vec;
         vec.reserve(lhs_.size());
         for (int i = 0; i < lhs_.size(); ++i)
            vec.push_back(lhs_[i] + rhs_[i]);
         return vec;
     }
Motti
I find the second one surprising. In the example you give, what would be the problem with using `auto` to store an instance of `vector_add<T, V1, V2>`? Surely this is a major application of the new `auto`, making it practical to store intermediate results from expression template systems (especially as they tend to have revoltingly huge type declarations).
Daniel Earwicker
The problem is that expression templates are designed to work within a statement which means that they probably store a reference to the two operands, if one of these is temporary it may be destroyed before the `vector_add` instance is used.
Motti
+22  A: 

Of course, this will affect other features and would seem to throw the standard wide open again.

Hardly. They still want to wrap up the standard soon, which is one of the main reasons for removing concepts. Making it "wide open" to unrelated changes would just throw away everything they gained by ditching concepts.

Anyway.... Of the remaining C++0x additions, I can't think of anything else I'd want to remove. I agree with their decision regarding concepts though. Stroustrup's paper really outlined some serious problems, The current specification for concepts would admittedly simplify template error messages, but it would do so by dramatically reducing the usefulness of generic programming -- a price I'm not willing to pay.

When I first read that paper, it scared me, because I assumed it was too late in the process for making serious changes to the spec. Turns out it wasn't, and the committee was willing to take dramatic action.

But apart from this, I think C++0x is in good shape. The remaining new features all look worthwhile.

Of course, there are plenty of existing features I'd love to remove. Primarily the vector<bool> specialization. There are other popular examples of features that didn't work out (the export keyword, exception specifications), but the vector specialization is the only one of them that can't be ignored. As long as we don't try to export templates, it doesn't matter that the keyword exists (and isn't implemented by compilers), and we can just refrain from using exception specs, but every time we need a vector of bools, we're bitten by the stupid premature optimization that slipped into the current standard.

Unfortunately, it seems like they've given up on removing it. (Last I checked, it wasn't even deprecated).

Of course, plenty of old C cruft could be ditched too, but recently, I've discovered that the one change I'd really love to see is...... ditching the Iostreams library. Toss it out, and build a new STL-style I/O library based on generic programming.

The current OOP-styled Iostreams library is ugly, slow, overcomplicated and inflexible. There's too much voodoo involved in defining new streams, too few standard stream types involved, too little flexibility (the problem that made me realize how limited the library is, was that I needed to extract a float from a string. Easy to do with stringstream, but if you need to do it often, you don't want to have to copy the input string every time (as the stringstream does) -- where's the stream that works on an existing iterator range? Or a raw array, even?)

Throw IOstreams out, develop a modern replacement, and C++ will be vastly improved.

And perhaps do something about the string class as well. It works sort of ok'ish as it is now, but really, what's with the huge number of member functions? Most of them would work better, and be more general, as free functions. Too much of the standard library relies specifically on the string class, when it could in principle work with any container, or even an iterator (std::getline, I'm looking at you)

jalf
Awesome, absolutely great answer! (OK, some of that was to get over the 15-char thing)
anon
I've found you can just insert 15 spaces after the first word. They get compressed down to a single space when displayed, but you get over the 15 char limit :D
jalf
Yep, iostreams are horrible - we should really get something better. In fact, I would like to see a better (and smaller) string class as well, but that is not going to happen.
Nemanja Trifunovic
Both of these (iostreams, string) are pure library concepts. This is really where something like boost can come into it's own. If worthy replacement libraries were developed there, then they may well get "standardised" (as has happened to a lot of other boost libraries).
Richard Corden
I doubt new replacement libraries would be added, no matter how good they were. They'd have to offer something significantly new, and the standard would be left with two (conflicting) string classes. But yes, they could be developed as libraries outside the standard.
jalf
Thing about iostreams and strings is that they really are good enough for almost all purposes. They're usable. It's not much worse than religiously omitting exception specifications.
David Thornley
I disagree. Iostreams are so painful they're almost useless at anything more complex than Hello World. String is *good enough*, yeah, but iostreams? It's pretty telling that this is about the only case where a significant number of C++ programmers *still* prefer the C equivalents. printf is unsafe as hell, but it's usable.
jalf
if you want a few examples of where they fail, here's a very incomplete list:cout << "hello " << "world" won't be written out atomically. Other threads might jump in after "hello" and print something out. This makes composing output in a thread-safe way pretty tricky. wifstream can't actually handle wide characters. It reads char's, and internally widens them to wchar_t. istream has some very weird ways to handle leftover whitespace (every beginner struggles with simple tasks like "wait for enter to be pressed, then read more input".
jalf
+2  A: 

Do whatever you want with concepts, but for god's sake keep threads and atomics, we absolutely need them. Perhaps add thread groups and support for cooperative threads a.k.a. fibers. IMO these are far more important than concepts, because everyone uses/will soon be using threads.

Helltone
hehe, I think threads are pretty safe now. Partly because they're the only major flagship feature left, and partly because as far as I know they're pretty well integrated into the draft standard already, so there aren't really any problems surrounding them.
jalf
+1  A: 

I'd like to remove =delete.

There's already a common and accepted idiom for acheiving the same effect (declare the function in question as private). I think this feature will just generate lots of 'I used =delete to remove a base class function from my derived class, but it can still be called using a base class pointer' questions.

Not to mention confusing people between the (now) two meanings of the delete keyword.

Joe Gauterin