Ranges, Concepts, and the Future of the Standard Library

Frequent readers of this blog know that over the past year, I’ve been working on a modern range library suitable for standardization, integrating good ideas from hither and thither — particularly from Sean Parent and Andrew Sutton — resulting in a library that’s available immediately, and a proposal to the standardization committee. This week I presented my work to the C++ Committee Meeting in Urbana-Champaign. The ensuing the discussion has implications for the future of the Standard Library.

Ranges Evening Session

I presented my ranges work on Wednesday evening to about 60 committee members. I’m happy to report that it was very warmly received. The committee liked the design of my ranges library and wants to see it in a standard ASAP. The feeling of the group was that the changes were big enough that they wanted them in a separate document known as a TS or a Technical Specification rather than in the official C++ standard. That way, we can flush out potential problems before baking it.

Some people might be disappointed that ranges will not be in C++17, but let me assure you that this is a Very Good Thing. Vendors have been proactive about implementing and shipping TS’s quickly, and there’s a chance we might get ranges into users’ hands more quickly this way. It also means that since we’re targeting a TS, we can be far more ambitious. Had we tried to squeeze this into C++17, we would have had to gut the proposal and standardize a very small, very conservative subset of functionality. By going the TS route, we can get much more cool stuff out the door much faster, and ship incremental updates as they become ready.

If any part of the Ranges TS looks especially promising and noncontroversial, it can be air-lifted into C++17.

The Future of the Standard Library

With the dawn of Concepts Lite as a language feature, the next obvious step is to use the feature to improve the Standard Library. During the ranges discussion, it seemed generally accepted that it will be impossible (or at least very undesirable) to add concepts to the library in a way that doesn’t break somebody’s code. The committee hates to break working code. One possibility would be to ship a new version of the library alongside the old. Users could then migrate at their leisure. That possibility was openly discussed to much head-nodding.

If that happens, we would be free to make changes to the Standard Library, not only to leverage Concepts Lite but also to support ranges, increase uniformity and expressive power, ease-of-use, safety, and to fix some long-standing issues. Whatever we end up with would look a lot like the current Standard Library, and of course existing code would continue to work.

Let me emphasize that this is my opinion of the general feeling in the room. The committee has not voted on this. What is clear is that work will now begin on a version of the STL that uses Concepts Lite and that looks a lot like my range-v3 library, and that this version will not make a priority of perfect backwards compatibility. That work will go into a Technical Specification, and vendors will start shipping it in a std::experimental namespace as soon as it hits the presses. I couldn’t be more excited!

Edited to clarify what is my opinion and what is a possible future.

20 Replies to “Ranges, Concepts, and the Future of the Standard Library”

  1. By completely backwards compatible version of the lib: it means the sentinel iterator for checking end is gone and we come back to the old way in this flavour of the lib? Or this is still considered compatible?

    • Sentinels will stay in the Ranges TS. Note that the Ranges TS will be in a separate namespace so we don’t have to worry about backwards compatibility (although we would want to keep gratuitous differences to a minimum). And even though sentinels wouldn’t be a breaking change even if it were made directly in std:: (which nobody is suggesting at this point), I personally think it would be questionable at best without Concepts.

  2. Eric, that’s great news. I’ve been looking at all your work from afar but I’m not even surprised by this warm reception. Good luck for the next steps 😀

  3. Well, I think if we don’t have a range library for C++17, it would still be a performance and modeling improvement to have the sentinels replacement for end iterators. I don’t know about the implications of that change, I just know that it is nice to have typed end iterators directly into std namespace. Many people will not use a TS just because of availability, since it would add a dependency and portability is a concern, for example for me usually. We have to make code working in 3 major compilers: clang, gcc and MSVC. Guess which one is the problematic one 😀

    • It’s a tough sell, adding sentinels without concepts. Without having an easy way for library vendors to express the EqualityComparable constraint, it’s easy for users to get tripped up in a way that leads to really horrible error messages.

  4. This is simply amazing. Such high level containers manipulation…
    This will be a new way of doing lots of stuff.
    Being these new features, some documentation could be very useful.. Where could i look for reference for zip, flatten etc.. Python? Haskell?

    • You mean you don’t just know? 😉 Yes, documentation would be very useful. I have a quick-start here, but that’s all for now. Until I write some docs, your best reference is the source code, I’m afraid. There are a couple of examples in the examples/ directory, and all the tests in test/. Those should give you a good idea how to use this stuff.

      • I just missed the tests folder.. My bad.
        I’ve already checked the source (bit too much of templates and decltypes for my head 🙂 ), and also the examples.
        Will read tests right now! Thanks again for you great work

  5. Pingback: Red Hat at the ISO C++ Standards Meeting (November 2014): Library | Red Hat Developer Blog

  6. Is split on actions and view necessary? It could be decided on call site what version is required. If arg is && we steal resources and do operation on them, or if it & we use lazy evaluation.

    This could be used too for preventing misuse. e.g. you could forbid using view on temporally data.

    • Eager and lazy evaluation offer different tradeoffs. Eager can, reuse memory, returning the same type as passed in. But a pipeline of eager actions makes multiple passes over the data. In contrast, a pipline of lazy evaluators only makes one pass over the data, but it can’t return an object of the same type.

      They’re both valid. Users should be able to say which they want. Using an expression’s value category (rvalue vs. lvalue) to make the choice is confusing and surprising. It means that a user who refactors this code:

      auto x = read() | remove(y);
      

      … to this:

      auto tmp = read();
      auto x = tmp | remove(y);
      

      … has completely changed the semantics of their code. That’s Bad.

  7. I have just discovered you work: it is really impressive. Thank you for the hard work!

    I was just wondering, is your work also a distant descendant of, or was in part inspired by, Ada ranges?

Leave a Reply

Your email address will not be published. Required fields are marked *

*