Bjarne's CppCon 2018 talk "Concepts: The Future of Generic Programming" answers that question clearly.
In his talk, Bjarne says:
* Concepts are NOT types of types. They are NOT type classes.
* Concepts can take more than one argument.
* Concept is a specification of what one or more types can do.
At around 1:06:30 in his talk Bjarne says:
* "it's just like defining functions, you *ARE* DEFINING FUNCTIONS".
-----
If concepts ARE functions why don't they look like functions?
Perhaps they should?
-----
template<typename X> using Value_type = X::value_type;
template<typename X> using Iterator_of = X::iterator;
template<typename For, typename For2, typename Out>
concept Mergable =
ForwardIterator<For>
&& ForwardIterator<For2>
&& OutputIterator<Out>
&& Assignable<Value_type<For>,Value_type<Out>>
&& Assignable<Value_type<For2>,Value_type<Out>>
&& Comparable<Value_type<For>,Value_type<For2>>;
He says: "This document proposes to extend functions to let them operate directly on types and concepts.
The goal is to allow writing metaprogramming in the most intuitive and consistent way with the rest of the language."
J. Monnon says:
Here is an example of a type function:
ForwardIterator IteratorType(typename T) {
// In a type function, an `if` behaves as a `if constexpr`.
if (Container(T)) // `Container` is a concept
return T::iterator;
else if (Array(T)) // `Array` is a concept
return Decay(T);
}
// On call site:
typename I = IteratorType(C);
I find this function as a variable thing confusing to coming to terms with what Concepts actually are.
If Concepts ARE functions as Bjarne says, why shouldn't they look and be composed using functional notation?It seems I'm not alone in this feeling. J. Monnon proposes this:
Type functions and beyond
An exploration of type functions and concept functions
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0844r0.htmlHe says: "This document proposes to extend functions to let them operate directly on types and concepts.
The goal is to allow writing metaprogramming in the most intuitive and consistent way with the rest of the language."J. Monnon says:
Here is an example of a type function:
ForwardIterator IteratorType(typename T) {
// In a type function, an `if` behaves as a `if constexpr`.
if (Container(T)) // `Container` is a concept
return T::iterator;
else if (Array(T)) // `Array` is a concept
return Decay(T);
}// On call site:
typename I = IteratorType(C);
J. Monnon says:
"A type function is always executed at compile-time. Here, it takes a type T and returns another type that models the ForwardIterator concept. Type functions allow a natural and straightforward notation to manipulate types."This also justifies his comment which I emphasise: // In a type function, an `if` behaves as a `if constexpr`.At this time, I agree with J. Monnon's proposal. I find it intuitive and insightful if I understand it correctly.
If J. Monnon's paper has been discussed at any length anywhere, can someone please tell me the outcome?His proposal appeared on Reddit at one point but attracted a near zero response there, which stunned me.
I'd certainly like to see more commentary on that proposal here before the next Standards meeting that is imminent.I may be wrong, but doesn't the D language go this route also? What is so wrong with that approach that C++ goes it's own way?There is more I would like to say about Concepts such as why I hate the syntax as currently proposed.
But for now, I'd really like to focus this discussion on the main elements I've raised.
1. If concepts ARE functions, why aren't we defining and using them with function like syntax? And using () not <>.
2. It seems J. Monnon's proposal is making the same point as I am, only much better? Can we please address all that he proposes?
3. I feel a more formal response to J. Monnon's paper from the main proponents of Concepts as currently defined should be made before concepts get wired in any further in it's current direction?I know many people would like Concepts be the marquee feature of C++20, but to me Concepts still seem quite away from where I'd like them to be.
Even Bjarne can only 'begrudgingly live' with the current syntax.
All this flux and begrudging really doesn't suggest to me that Concepts are ready to go for C++20.
This is even before any of my comments or J. Monnon's paper is taken into account.
Right now, I feel that if Modules and Coroutines were the only main features that hit for C++20, I'd be happy with that.
If people can explain why my comments are on the mark or misplaced and what the issues are with J. Monnon's proposal, I'd be grateful.
Thanks
A few thoughts on Concepts:As Concepts have evolved, I have found it difficult to get a handle on what Concepts actually are.
i.e.: Are Concepts functions, types, or something else?
Bjarne's CppCon 2018 talk "Concepts: The Future of Generic Programming" answers that question clearly.In his talk, Bjarne says:
* Concepts are NOT types of types. They are NOT type classes.
At around 1:06:30 in his talk Bjarne says:
* "it's just like defining functions, you *ARE* DEFINING FUNCTIONS".
The Concepts defined in Bjarne's talk look more like variable definitions *defined* in what feels (to me) like an odd mix of logic and type like syntax:template<typename X> using Value_type = X::value_type;
template<typename X> using Iterator_of = X::iterator;template<typename For, typename For2, typename Out>
concept Mergable =
ForwardIterator<For>
&& ForwardIterator<For2>
&& OutputIterator<Out>
&& Assignable<Value_type<For>,Value_type<Out>>
&& Assignable<Value_type<For2>,Value_type<Out>>
&& Comparable<Value_type<For>,Value_type<For2>>;The above looks like a variable definition. If it is not, then is it right that it looks like one?
It's a definition, with conditional logic et al. i.e it uses &&. etc. like an inline function.So why are we defining it NOT using function like snytax?
Why is this a good thing?
1. If concepts ARE functions, why aren't we defining and using them with function like syntax? And using () not <>.
2. It seems J. Monnon's proposal is making the same point as I am, only much better? Can we please address all that he proposes?
3. I feel a more formal response to J. Monnon's paper from the main proponents of Concepts as currently defined should be made before concepts get wired in any further in it's current direction?I know many people would like Concepts be the marquee feature of C++20, but to me Concepts still seem quite away from where I'd like them to be.
Even Bjarne can only 'begrudgingly live' with the current syntax.
All this flux and begrudging really doesn't suggest to me that Concepts are ready to go for C++20.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/17eb2726-8feb-4cdf-a58e-43d6dc81549a%40isocpp.org.
It might be useful to have a SmallerThan<int, int> concept to check whether a type-erased type whose size is only known numerically can fit into an SBO buffer.It's a bit of a stretch, but might be a good case for keeping value concepts in, even if they only have rare usefulness.
On Wednesday, October 24, 2018 at 9:09:52 PM UTC-4, gmis...@gmail.com wrote:A few thoughts on Concepts:As Concepts have evolved, I have found it difficult to get a handle on what Concepts actually are.
i.e.: Are Concepts functions, types, or something else?Something else.Bjarne's CppCon 2018 talk "Concepts: The Future of Generic Programming" answers that question clearly.In his talk, Bjarne says:
* Concepts are NOT types of types. They are NOT type classes.Well, they sort-of are. To a first approximation, they're predicates (type -> bool), which can be understood as partitions of the set of all types.For any type T, either T is-a Range or T is-not-a Range. So the set of Ranges is a subset of the set of all possible types.BUT! Look closer and there are at least three caveats.(1) Concepts have deep structure known as "normal form"; see below.(2) Concepts don't have to map (type -> bool); you can have multi-parameter concepts such as ConvertibleTo<T,U>, which are not as easily to gloss as predicates over single types. (But darned if the Concepts TS doesn't try! For any type T, either T is-a ConvertibleTo<U> or T is-not-a ConvertibleTo<U>.)(3) Concepts don't have to accept types at all. For example, you can make a concept that maps (int -> bool).template<int V>concept EvenValue = ((V % 2) == 0);I don't think this kind of concept is useful in real code (I'd prefer this kind of concept be kicked out of the Working Draft before C++2a is shipped). But you definitely can't by any mental gymnastics claim that concept `EvenValue` is a "type function" or a "type of types" or anything remotely like that.At around 1:06:30 in his talk Bjarne says:
* "it's just like defining functions, you *ARE* DEFINING FUNCTIONS".I believe that was an ad-lib not to be taken 100% literally. To a first approximation, a concept like Mergeable is a function mapping an ordered tuple of types to a bool. But that doesn't mean that all concepts ever must be thought of as functions.That way lies functional programming and madness. ;)
2. It seems J. Monnon's proposal is making the same point as I am, only much better? Can we please address all that he proposes?I think P0844 "Type functions and beyond" is thought-provoking. It's very large, though, which I believe is why it's targeted at SG7 Compile-Time Programming (formerly SG7 Reflection).P0844 major section 3, "Concepts introducing types," seems to ignore the existence of non-type concepts in the Working Draft. Perhaps there should be a concerted effort to kick non-type concepts out of the Working Draft in order to gain some freedom of motion for these recurring theories of "concepts == types of types."I do not believe that P0844 is making the same points (or, asking for clarification on the same points) as you are. I have only skimmed P0844, but it does not seem to be engaging with Concepts-as-they-are at all; it seems to be trying to reuse Concepty words to refer to elements of the author's more naïve "types of types" theory.(More naïve is not necessarily bad! I think C++2a Concepts is far too much of an experts-only feature, and we could use a lot more naiveté in this area.)3. I feel a more formal response to J. Monnon's paper from the main proponents of Concepts as currently defined should be made before concepts get wired in any further in it's current direction?I know many people would like Concepts be the marquee feature of C++20, but to me Concepts still seem quite away from where I'd like them to be.
Even Bjarne can only 'begrudgingly live' with the current syntax.
All this flux and begrudging really doesn't suggest to me that Concepts are ready to go for C++20.FWIW, I agree with your conclusion.The question is, do C++2a Concepts need wholesale kicking-out, as happened in C++11? or can they be rescued by judicious cuts?The other question is, can anyone stop Concepts at this point or are the wise people getting out of the way of the train? (Cynic says: observe the recent formation of EWGI and LEWGI for those people tired of engaging with C++2a issues and eager to move on to C++2b.)–Arthur
There is a fair amount of history here. The model you are
describing was the basis for the Concepts Lite design that
eventually became the Concepts TS. WG21 moved on from that model
when integrating Concepts into C++20. Though concept definitions
are, effectively, constexpr predicates, specifying them as a new
kind of entity avoids a fair amount of special casing while also
leaving more room for future evolution.
You might appreciate the analysis at http://honermann.net/blog/2016/03/24/refining-concepts-the-quiddity-of-concept-definitions
Tom.
On Sunday, October 28, 2018 at 9:27:58 AM UTC+13, Arthur O'Dwyer wrote:
On Wednesday, October 24, 2018 at 9:09:52 PM UTC-4, gmis...@gmail.com wrote:A few thoughts on Concepts:As Concepts have evolved, I have found it difficult to get a handle on what Concepts actually are.
i.e.: Are Concepts functions, types, or something else?Something else.
[...] To a first approximation, they're predicates (type -> bool), which can be understood as partitions of the set of all types.
For any type T, either T is-a Range or T is-not-a Range. So the set of Ranges is a subset of the set of all possible types.BUT! Look closer and there are at least three caveats.(1) Concepts have deep structure known as "normal form"; see below.
(2) Concepts don't have to map (type -> bool); you can have multi-parameter concepts such as ConvertibleTo<T,U> [...](3) Concepts don't have to accept types at all. [...]
At around 1:06:30 in his talk Bjarne says:
* "it's just like defining functions, you *ARE* DEFINING FUNCTIONS".
I believe that was an ad-lib not to be taken 100% literally. To a first approximation, a concept like Mergeable [emphasis added —A] is a function mapping an ordered tuple of types to a bool. But that doesn't mean that all concepts ever must be thought of as functions.
See I think it can be taken pretty much 100% literally.From what I can tell, a Concept is 100% a constexpr function. A concept function verifies that a given list of types (passed to that function) passed to it conform to a specification - as defined by the logic of that function. The name of the function signifies what the concept is.
The function returns true if the types passed to the function meet the requirements of logic of the function and false if they do not.There may be more to how the compiler deals with such a function, but it seems to me that this minimum I've described above is true.Can we agree this far?
If a concrete type is passed to a function as a parameter whose type is constrained by a Concept, the Concept function is called with the concrete type and if it returns false, it yields a compilation error.
If a concrete type is returned from a function and assigned to a Concept variable the same check is performed. I'm sure this is reasonably off base but it seems like the gist of things. If this is correct or not though isn't the core of anything to me though. It's just how I'm visualizing it at the moment before I understand this more and subsumption and all of that.
Why does thinking of all concepts as functions madness? Because it seems to me that's exactly [emphasis added —A] what all concepts as currently discussed are.
[...]
Please see my CppCon 2018 talk "Concepts as she is spoke" for a truly painful amount of information on how Concepts are different from plain old variable templates.
[...] I think Concept definitions need to retain a similar functional feel and that means exposing Concepts to look more like the functions and enabling them to be defined more like that. Or at least it's not clear to me why we can't and shouldn't go further down that road.