--
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/1abe0443-19be-4aff-8627-e87d1807b901%40isocpp.org.
In section 1.1, the template parameters list doesn't include template template parameters:
template <template <typename> class T>
I suggest also noting that in the concept constrained case, the kind of template parameter can be any of type, non-type, or template (according to the concept's prototype template parameter; see http://eel.is/c++draft/temp.param#10)
In section 1.2, the example code binds 'r' to two different things (a template parameter, and a function parameter). Perhaps you meant this?
template <Regular R>
void foo(R & r)
In section 1.2, the statement that "lambda cannot be constrained" is no longer true; P0766 [1] as adopted in Albuquerque provides for requires clauses in lambda expressions.
In section 2.1: support for 'auto' as a function parameter was rejected (for now) in Albuquerque when P0766 [1] was discussed. This will be revisited in Jacksonville.
In section 2.4.2, I recommend making it ill-formed for *any* constraints to be specified with the initial 'auto' in a function declaration that includes a trailing return type (don't just require that the constraints match).
I like the discussion in 2.4.4; I don't think I've seen anyone suggest use of concept names in place of 'typename' for dependent name disambiguation. I'm not yet sure if this is a good idea, but it is interesting to think about. I presume that the named concept's prototype parameter must be a type template parameter for use in place of 'typename'. Perhaps you could also allow a concept with a prototype template template parameter to be used in place of 'template' disambiguation. Would you also allow a concept with a non-type prototype template parameter to be used where 'typename' and 'template' disambiguation is not required? I'm not sure that this is useful, nor whether it is reasonably possible within the existing grammar.
In section 2.4.5, I believe it is already allowed to specify constrained parameters in template alias declarations. I don't understand the final example; is 'Stream' effectively a concept alias (I assume 'Iterable' names a concept)? That declaration also looks like a partial specialization of a template alias, but those don't exist. Perhaps you intended 'template<Serializable T> using Stream = Iterable<T>'?
In section 2.4.6, there is no explanation of *why* you feel constraints would be actively harmful in the cases mentioned. The meta-classes proposal includes the ability to associate a constraint with a class template definition that would require all instantiations to satisfy the constraints; I find that potentially useful.
In section 2.5: I think it is potentially useful to allow constraints to be specified on pointers and references just as we can with existing type qualifiers. For example:
auto * PointerToIntegral p = ...; // The type of 'p' must satisfy PointerToIntegral.
In section 3, note that 'void foo(ConceptName auto a, decltype(a) b)' is *not* equivalent to the consistent resolution behavior specified in the concepts TS because the type of the argument for 'b' does not contribute to type deduction. See P0725 [2] for some discussion of this. Specifying consistent resolution when concept names are not required to deduce the same type requires a template header. For example:
template<ConceptName typename T> void foo(T a, T b);
Overall, I think the paper would benefit from more separation of motivation from what is actually proposed. I find the discussion sometimes makes it confusing exactly what is and is not proposed.
What I would really like to see is for you, Jacob Riedle and Thomas Köppe to join forces and author a single paper that presents the motivation for these designs, the design options and tradeoffs, and a single proposal. Ideally, the paper would be presented in a form that enabled EWG to vote on (and finally, hopefully, settle) a number of design issues:
- Whether an abbreviated function syntax must have a 'template' keyword in the declaration.
- Consistent-resolution vs independent-resolution.
- Concepts-as-qualifiers (adjectives) vs concepts-as-type-specifiers.
Le mer. 15 nov. 2017 à 16:57, Tom Honermann <t...@honermann.net> a écrit :
I like the discussion in 2.4.4; I don't think I've seen anyone suggest use of concept names in place of 'typename' for dependent name disambiguation. I'm not yet sure if this is a good idea, but it is interesting to think about. I presume that the named concept's prototype parameter must be a type template parameter for use in place of 'typename'. Perhaps you could also allow a concept with a prototype template template parameter to be used in place of 'template' disambiguation. Would you also allow a concept with a non-type prototype template parameter to be used where 'typename' and 'template' disambiguation is not required? I'm not sure that this is useful, nor whether it is reasonably possible within the existing grammar.
The idea comes P0634, and the general observation that typename is one of this thing that gets mindlessly and grudgingly added by junior developers when the compiler is unhappy. Hopefully, replacing that keyword with actual information will make people think more about what they are doing, and add information for subsequent readers. And typename was already a constraint in that it force the type of the identifier to be a type. If that make sense.
If I understand you correctly, what your propose would be like having a constrained "valuename" ? The compilers could probably deal with it, however would it add readability ?You probably don't want to loose the "this is a type" information for the human reader.
In section 2.4.5, I believe it is already allowed to specify constrained parameters in template alias declarations. I don't understand the final example; is 'Stream' effectively a concept alias (I assume 'Iterable' names a concept)? That declaration also looks like a partial specialization of a template alias, but those don't exist. Perhaps you intended 'template<Serializable T> using Stream = Iterable<T>'?
The idea that actually was suggested by several people independently, was to allow a an alias of a template type to be more constrained than the original type. in this poorly made and explained example, Stream is an alias on the Iterate template type, however it puts additional requirements on the type ( or non type ) of its template parameter. In insight, it may be worth of its own paper. I wouldn't say it's a specialization, since it does not affect the declaration.
In section 2.5: I think it is potentially useful to allow constraints to be specified on pointers and references just as we can with existing type qualifiers. For example:
auto * PointerToIntegral p = ...; // The type of 'p' must satisfy PointerToIntegral.
Maybe ? I feel like this would have very limited use. We have syntax to describe qualifiers, I don't think concepts add a lot information there.But why not, as long as compilers writers have no reasons to be opposed to it.
In section 3, note that 'void foo(ConceptName auto a, decltype(a) b)' is *not* equivalent to the consistent resolution behavior specified in the concepts TS because the type of the argument for 'b' does not contribute to type deduction. See P0725 [2] for some discussion of this. Specifying consistent resolution when concept names are not required to deduce the same type requires a template header. For example:
template<ConceptName typename T> void foo(T a, T b);
That's true. And I'm not arguing against that syntax. I'm arguing that in functions template with auto parameter, each constraint should only apply to the type immediately following.Note that this does not break your example, ConceptName only appears once in front of T.
Hello, I wanted to share my thoughts on the broad topic of "Concepts as Adjectives".I believe they are not as innocent as presented.
First, a new category of user provided entities is silently introduced - type decorators. This is bigger a change then implied.
Up until this point all decorations were either keywords or attributes, and now we have something which looks like a type (or even a template!), used as a qualifier to some other (real) type or auto.
Sooner or later people will start asking, why I just can write only the decorator and the type be deduced, which the paper actually allow. In that case question arises do why do we need this new category in the first place.
Second. Consider const Point arg. const is not about the type, it's about the variable. The fact that C++ handles const as a different type of Point is an implementation detail.However "type decorations" will be all about the type, in that one line we will have some decorations which semantically are about the variable and others about the type of it! This is bound to lead to confusion.
Also. const int a; will always bind to an int b, but a MyClass c, might not bind to MyConstraign MyClass d; Yet both are spelled out with the same syntax, both are "a case where one is just more constrained then the other", but in practice mean different things.
Third. Consider A auto a = ...; B int b = ...; From the C++ rules so far we might consider both of these are semantically the same, just in the second case the auto is spelled out. In fact however these two, are radically different - the first is constrained type, the other is constrained value. This can be confusing no matter how we look at it - if we look from variable declaration PoV we expect both to be types (but they are not) if we look at template argument declaration PoV (<auto I>, <int I>) we expect both to be a value, which is also not true!
The confusion with out continues with the fact A auto means one thing in code (as return value, variable or argument) and different as template param.f(A auto a){}; A auto a; A auto f() {} are (radically) different then template<B auto I>.Yes, one can argue this is already the case, but this does not help either, not to mention auto as function params is not yet in.
Forth. Decorations are, by there nature, an ad hoc tool - to have something existing and to further specify it in the place of use. Constrained types are not like that, ad hoc constrain creation is unlikely. Swappable Sortable Writable foo; in the real world will likely be just FooConcept foo; semantically. It is very unlikely one will need to mix and match constrains on the go and pay the syntax, maintenance, visual noise tax.
I believe we should streamline Concepts as much as possible actually removing features and "optional syntaxes" before adding new ones.
Am Samstag, 6. Januar 2018 14:14:52 UTC+1 schrieb mihailn...@gmail.com:Hello, I wanted to share my thoughts on the broad topic of "Concepts as Adjectives".I believe they are not as innocent as presented.Yes, in my opinion, Concepts as adjectives/qualifiers are very very powerful and in no way a diffident solution.
First, a new category of user provided entities is silently introduced - type decorators. This is bigger a change then implied.When I first wrote "Concepts are Adjectives, Not Nouns", I very well perceived them to be ground breaking.
Up until this point all decorations were either keywords or attributes, and now we have something which looks like a type (or even a template!), used as a qualifier to some other (real) type or auto.I agree, that it introduces identifiers (in constrast to keyword) as qualifiers, which is unprecedented by now.However, this identifier is hardly visually ambiguated with a type name, because it ultimately is followed by a concrete type (least common case), "auto" or "typename" (most common cases).In all situations, the noun is (in 9 of 10 cases) the last identifier, which sets it visually apart.In the latter two cases, the noun is a keyword and therefore additionally visually set apart.
Sooner or later people will start asking, why I just can write only the decorator and the type be deduced, which the paper actually allow. In that case question arises do why do we need this new category in the first place.Because sometimes, we want to declare a constrained type (Sortable typename S) and sometimes we want to declare a variable of constrained type (Sortable auto s).If you ask me, I am against making the noun optional in any case. Actually for the same reason that C++ discourages "const" to implicitly stand for "const int" (as in C).
Second. Consider const Point arg. const is not about the type, it's about the variable. The fact that C++ handles const as a different type of Point is an implementation detail.However "type decorations" will be all about the type, in that one line we will have some decorations which semantically are about the variable and others about the type of it! This is bound to lead to confusion.Wait, do you think going from "template<typename T>" (without concepts) to "template<Sortable T>" is less confusing?Suddenly, we don't know whether T is a type after all?!Also. const int a; will always bind to an int b, but a MyClass c, might not bind to MyConstraign MyClass d; Yet both are spelled out with the same syntax, both are "a case where one is just more constrained then the other", but in practice mean different things.Firstly, this argument is not working for me, since const int& will not bind to a int&. Secondly:If (which I assume) MyClass is a concrete type,
- either MyConstrain is a Value-Constraint
(in which case we face same "issue" (IMO, that's a feature), that Concept TS faces),- or MyConstrain is a Type-Constraint
(in which case "MyClass" does very well bind to "MyConstraint MyClass", given MyClass after all meets MyConstraint and doesn't generate a compiler error)
Third. Consider A auto a = ...; B int b = ...; From the C++ rules so far we might consider both of these are semantically the same, just in the second case the auto is spelled out. In fact however these two, are radically different - the first is constrained type, the other is constrained value. This can be confusing no matter how we look at it - if we look from variable declaration PoV we expect both to be types (but they are not) if we look at template argument declaration PoV (<auto I>, <int I>) we expect both to be a value, which is also not true!I understand your concerns. However, this is not how I and Corentin propose Concepts.Whether a Concept constraints the type or the value of a variable depends on the concept, not on whether we "spell out the auto"."Even" in the phrases "Even int i" and "Even auto i", will always constrain the values of i.In the latter phrase however, "auto" is allowed to deduce to any type (including int),for which the property "Even" is decidable (depending on the definition, probably for number-like types).The confusion with out continues with the fact A auto means one thing in code (as return value, variable or argument) and different as template param.f(A auto a){}; A auto a; A auto f() {} are (radically) different then template<B auto I>.Yes, one can argue this is already the case, but this does not help either, not to mention auto as function params is not yet in.I AM in favor of "auto" having the same meaning (regarding your concerns) across its usages.This is the way I proposed it and I believe Corentin would too.
Forth. Decorations are, by there nature, an ad hoc tool - to have something existing and to further specify it in the place of use. Constrained types are not like that, ad hoc constrain creation is unlikely. Swappable Sortable Writable foo; in the real world will likely be just FooConcept foo; semantically. It is very unlikely one will need to mix and match constrains on the go and pay the syntax, maintenance, visual noise tax.For the sake of argument, it's irrelevant how likely this feature is used.But if at all unlikely, this is a feature, not a bug. Nobody forces you to chain concepts this way.Apart from that, I hardly believe, you will write a named concept for each and every such Concept-based function.Why would you do so, if you only needed to chain the Concepts once for the whole function?
I believe we should streamline Concepts as much as possible actually removing features and "optional syntaxes" before adding new ones.I agree with you here, although I don't find "Concepts TS revisited" to make things consistent enough.When ansering to your concerns, I hope to have understood you correctly for the most part.If not, please clarify those mistakes.Yours,Jakob
--
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/16c7eb00-967f-49d4-8bd8-38900f4c5cae%40isocpp.org.
Third. Consider A auto a = ...; B int b = ...; From the C++ rules so far we might consider both of these are semantically the same, just in the second case the auto is spelled out. In fact however these two, are radically different - the first is constrained type, the other is constrained value. This can be confusing no matter how we look at it - if we look from variable declaration PoV we expect both to be types (but they are not) if we look at template argument declaration PoV (<auto I>, <int I>) we expect both to be a value, which is also not true!I understand your concerns. However, this is not how I and Corentin propose Concepts.Whether a Concept constraints the type or the value of a variable depends on the concept, not on whether we "spell out the auto"."Even" in the phrases "Even int i" and "Even auto i", will always constrain the values of i.In the latter phrase however, "auto" is allowed to deduce to any type (including int),for which the property "Even" is decidable (depending on the definition, probably for number-like types).
--
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/c7a4678b-5a2f-457e-9be4-3979506ce4dd%40isocpp.org.
My example was not very clear, but issue is still there, I believe - copyConstructable T will not bind to any T, however const T does not impose restrictions to the incoming T.const is not a required clause, copyConstructable is, yet both are used exactly the same way.This mixing of qualifiers could be confusing - sometimes it is about the type, sometimes it is about the value, sometime it is about the variable.
Third. Consider A auto a = ...; B int b = ...; From the C++ rules so far we might consider both of these are semantically the same, just in the second case the auto is spelled out. In fact however these two, are radically different - the first is constrained type, the other is constrained value. This can be confusing no matter how we look at it - if we look from variable declaration PoV we expect both to be types (but they are not) if we look at template argument declaration PoV (<auto I>, <int I>) we expect both to be a value, which is also not true!I understand your concerns. However, this is not how I and Corentin propose Concepts.Whether a Concept constraints the type or the value of a variable depends on the concept, not on whether we "spell out the auto"."Even" in the phrases "Even int i" and "Even auto i", will always constrain the values of i.In the latter phrase however, "auto" is allowed to deduce to any type (including int),for which the property "Even" is decidable (depending on the definition, probably for number-like types).Then we still can't tell if the concept is about the type or the value. Wasn't it one of the original goals to have that distinction?In any case, I understand variable declaration is a separate issue!