Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Static If I Had a Hammer

Download

Right click “Save as…”

Slides

All right, the C++11 Standard is done. Can we go home? Definitely not - progress waits for no one.

For all its might, C++11 is not addressing a few basic needs in template programming. For example, you'd hate to have to define a new function or indeed a whole new class wherever you need an "if" statement; yet, this is exactly what we do for template code. Also, conditional overloading using the likes of std::enable_if is syntactically bulky and semantically ham-fisted (as is visible with constructors and other special functions).

This talk describes a new proposal (joint work with Herb Sutter and Walter Bright): a "static if" construct that works much like "if", just during compilation. It's reminiscent of #if, just done copiously right.

With "static if" a lot of generic code becomes radically simpler, which in turn enables idioms that today are too complex to be usable. This proposal for C++ benefits from a large body of experience within the D programming language.

Follow the Discussion

  • thesaintthesaint

    Your talks were both great ;). I really hope you get this into the standard as soon as possible! Seems like it is even possible to get C++ back on the rail without a complete redesign, like D. Even though I like the idea of D it will always impose a great barrier from programmers to switch. So it would be great if we could get C++ to be usable again. Your talks are were the fun stuff begins, but unfortunately, with current C++ it was rather annoying, and surely no fun...

  • paulpaul

    Now, we just need to for loop to go over tuples, not just ranges. That I think is a much needed feature from D.

  • Ben HansonBen Hanson

    I am very interested to see how static if stacks up against the refactored concepts. Maybe there will be a place for both, or even some kind of merger. The static if proposal certainly looks a lot easier, but I can see why if could be seen as a bit of a hack. On the other hand, the concept proposal still strikes me as looking rather too 'academic'.

    This all leaves me quite conflicted. My instinct is to trust Bjarne, as ever since originally reading "The Design and Evolution of C++" I have been aware of his very powerful problem solving skills, that really get to the heart of the matter. On the other hand, I deeply sympathise with Andrei's desire to keep things 'simple'.

    Interesting times ahead in any case!

  • StefanStefan

    Any chance that more of the talks will be posted online? I could not watch Andrei's talk live, nor the closing panel... :(

  • @Ben Hanson: static if and concepts really do two different things. While Andrei presented many things that overlap with concepts, they're different tools for different jobs. Concepts do two very important jobs.

    First, they provide a way to easily tell *exactly* what a type has to do in order to be used in a template. This prevents user code from having to parse through a million errors to figure out what went wrong. Yes, Clang is great in this regard, but it's still verbose over what concepts provide, and look at how much time clang's developers spent on getting those errors tamed. With a proper language feature, it's simple and trivial for compiler writers.

    The second job, which `static if` cannot emulate, is verifying that the template *itself* uses the template parameter in the prescribed manor. This is *very important* during the development of a template. If you take a ForwardIterator, but you do -- on it, you've changed what your iterator means all by accident. This is an easy mistake to make and requires a lot of testing to find. Or you use concepts and get it for free.

    At the same time, `static if` is much more free-form. It's #define, only it's actually part of the language. There are a lot of things you can do with `static if` that you can't with concepts.

    `static if` is like a pencil, while concepts are like paintbrushes. They both can be used to "draw", but they make very different kinds of drawings. If you use pencils to "paint" a painting, you can only get black-and-white. That's better than nothing, but not nearly as good as if you had a paintbrush and a set of paints, is it?
  • Any chance that more of the talks will be posted online? I could not watch Andrei's talk live, nor the closing panel... Sad

     

    It's up now. Cool

  • Ben HansonBen Hanson

    @Alfonse:

    Thanks for your reply.

    > static if and concepts really do two different things. While Andrei presented
    > many things that overlap with concepts, they're different tools for different
    > jobs.

    I'm hoping this is the case. Bjarne didn't seem convinced, although to be fair he did say that it all needed thinking through in more detail. As it's early days no doubt the details will be thrashed out over time. The fact that Herb supports static if is also a major plus.

    > First, they provide a way to easily tell *exactly* what a type has to do in
    > order to be used in a template. This prevents user code from having to parse
    > through a million errors to figure out what went wrong. Yes, Clang is great
    > in this regard, but it's still verbose over what concepts provide, and look
    > at how much time clang's developers spent on getting those errors tamed. With
    > a proper language feature, it's simple and trivial for compiler writers.

    Clangs error messages look like another complimentary feature too, as they address code other than templates. Bjarne made the point that concepts aren't just about better error msgs. I of course agree that concepts will help a lot (as did Chandler).

    > The second job, which `static if` cannot emulate, is verifying that the
    > template *itself* uses the template parameter in the prescribed manor. This
    > is *very important* during the development of a template. If you take a
    > ForwardIterator, but you do -- on it, you've changed what your iterator means
    > all by accident. This is an easy mistake to make and requires a lot of
    > testing to find. Or you use concepts and get it for free.

    OK. I have actually experienced the very example you give in my own library!

    > At the same time, `static if` is much more free-form. It's #define, only it's
    > actually part of the language. There are a lot of things you can do with
    > `static if` that you can't with concepts.

    It certainly looks very powerful and of course easy to understand. Bjarne felt it was a bit of a hack! Maybe he'll come round once all the details have been worked through.

    Regards,

    Ben

  • paulpaul

    Actually I use these set of macros to help make enable_if look a lot better:

    #define ERROR_PARENTHESIS_MUST_BE_PLACED_AROUND_THE_RETURN_TYPE(...) __VA_ARGS__>::type
    #define FUNCTION_REQUIRES(...) typename boost::enable_if<boost::mpl::and_<__VA_ARGS__, boost::mpl::bool_<true> >, ERROR_PARENTHESIS_MUST_BE_PLACED_AROUND_THE_RETURN_TYPE
    #define EXCLUDE(...) typename boost::mpl::not_<typename boost::mpl::or_<__VA_ARGS__, boost::mpl::bool_<false> >::type >::type

    #define CLASS_REQUIRES(...) typename boost::enable_if<boost::mpl::and_<__VA_ARGS__, boost::mpl::bool_<true> > >::type

    Then the uninitialized_fill could be defined like this:

    template<class It, class T>
    FUNCTION_REQUIRES
    (
    is_forward_iterator<It>,
    is_convertible<T, decltype(*b)>
    )
    (void) uninitialized_fill(It b, It e, const T& x)
    {
    ...
    }

    Parenthesis are required around the return though. If you forget them, the compile will say something like 'ERROR_PARENTHESIS_MUST_BE_PLACED_AROUND_THE_RETURN_TYPE' is undefined. As a friendly reminder of the parenthesis. The EXCLUDE is useful, because the traits don't have an hierarchy. So if you wanted uninitialized_fill for forward_iterator and random_access_iterator you need to define them like this:

    template<class It, class T>
    FUNCTION_REQUIRES
    (
    is_forward_iterator<It>,
    is_convertible<T, decltype(*b)>,
    EXCLUDE(is_random_access_iterator<It>)
    )
    (void) uninitialized_fill(It b, It e, const T& x)
    {
    ...
    }

    template<class It, class T>
    FUNCTION_REQUIRES
    (
    is_random_access_iterator<It>,
    is_convertible<T, decltype(*b)>
    )
    (void) uninitialized_fill(It b, It e, const T& x)
    {
    ...
    }

  • Notice how Andrei is using an Apple laptop. o_0

  • codecode

    And what exactly does this buy us over concepts?

    It seems like a cheap hack, and while it may work for D, I am not looking forward to have this "feature" in C++. There are enough ways to do most things as is, we need more well though-out solutions.

  • ChicoChico

    static if stroustrup had a hammer: http://imgur.com/a/fqgzk

  • sulfidesulfide

    just because he works at Microsoft doesn't mean he can't use a superior product

  • Gavin BeattyGavin Beatty

    Andrei works for Facebook - visible in his title slide

  • ZenJuZenJu

    The idea of "static if" is great! We're using the semantics anyway in the ugly form of std::enable_if, therefore what is required is a better syntax (so that people other than the library author may understand what's going on)
    "static if" is fine as a concept, but syntactically it is an absolute no-go that it abuses the curly brace syntax in a way that does not respect scope.
    What about something like a non-macro #if, #endif?

  • FarewellFarewell

    > "static if" is fine as a concept, but syntactically it is an absolute no-go that it abuses the curly brace syntax in a way that does not respect scope.

    The world is change, so wipe away your tears and get used to it...

  • getitrightgetitright

    I agree that syntax is an abomination, and probably the best suggestion so far is to extend preprocessor #if/else/endif if they refer to the compile-time constants inside templates to be deferred to the time of instantiation. That would cover the existing use and the 'static if'.

  • RandomRandom

    So, when is this going to be a part of C++? Can't wait!

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.