Topic: [c++std-core-27261] An


Author: Bjarne Stroustrup <bjarne@stroustrup.com>
Date: Sat, 07 Mar 2015 16:55:47 -0500
Raw View
This is a multi-part message in MIME format.
--------------040702070504010209010407
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

If someone has a proposal for changes to the concepts TS, I suggest they=20
write a paper for the evolution group to consider.

We have discussed "auto" and concepts for years (I first described "void=20
f(auto);" to the EWG in 2004 or so) and I have seen little new or in=20
terms of facilities or technical arguments in this long thread.


On 3/7/2015 4:17 PM, David Rodr=C3=ADguez Ibeas wrote:
> When I went over the concepts paper there were a couple of things that=20
> troubled me a bit (not a lot) and that are relevant to this=20
> discussion.  The first one is that the syntax does not call out that=20
> the identifier names a concept.  This is also the case in C++14, C++11=20
> and C++03, so nothing new, just adding one more dimension (before, a=20
> new type could be added that changed the meaning of an identifier),=20
> but with concepts and a non-distinguishible syntax now we have more=20
> interactions.
>
> The second thing that concerned me is the variety of syntaxes to=20
> represent constrained templates.  This is driven by two conflicting=20
> goals: terseness and expressive power.  In addition to that, I=20
> disliked the fact that the use of a place-holder type has different=20
> semantics: 'void f(auto x, auto y)' introduces two unrelated types for=20
> a and b, while 'void f(concept a, concept b)' introduces a single type=20
> for both a and b.
>
> An alternative syntax that came to mind, was to use the syntax for the=20
> template introduction as a placeholder: 'void f(concept{T} x,=20
> concept{U} y)' would introduce two types T and U, both satisfying the=20
> 'concept' after the introduction of the type with 'concept{T}', the=20
> identifier T could be reused to represent the same type for different=20
> parameters: 'void f(concept{T} x, T y)' [equivalent to the Concepts=20
> TS: 'void f(concept x, concept y)'.  Compared with the previous=20
> syntax, there is a bit of overhead, but I don't consider that to be a=20
> *lot* of overhead.  Another advantage of this syntax is that in a=20
> concise form you can allow for multiple arguments to have different=20
> types satisfying the same concept: 'bool equal(FwdIter{It1} first, It1=20
> last, FwdIter{It2} first2, It2 last2)'.  This is currently not allowed=20
> in the concepts TS with the more concise syntax.
>
> As far as I know, this syntax is illegal in the language at this=20
> point, so it is clearly identifiable as relating to a concept, and=20
> could even be used to drive lookup to ignore types when searching for=20
> the identifier 'concept'.  The same syntax could be allowed (not=20
> required) for the auto placeholder to enable an unconstrained template=20
> in which two arguments are of the same type: void f(auto{T} x, T y).
>
> Similar to the template introduction case, it would be possible to use=20
> the syntax to introduce multiple types at once: 'bool=20
> equal(Comparable{T,U} const & x, U const & y) { return x =3D=3D y; }' If=
=20
> this is allowed, there would not be a need to have the template=20
> introduction syntax. This is really the same thing, except that it=20
> would not appear outside of the argument list, but inlined with the=20
> parameters, which makes it a valid alternative for lambas=20
> [](Comparable{T,U} const & x, U const & y) { return x =3D=3D y; }.
>
> Whether this is the good solution or something else is, I'd like to=20
> have less alternative syntaxes, and I am willing to pay a bit on=20
> terseness (this is not a huge difference) for clarity, reducing the=20
> alternatives and flexibility.
>
>     David
>
> * An open question, for which I don't have a good answer is whether=20
> the syntax should be composable: bool f(concept1{concept2{T},=20
> concept3{U}} t, U u) meaning:
>
> template <typename T, typename U>
> requires concept2<T> and concept3<U> and concept1<T,U> // pseudo code,=20
> not sure if this is valid syntax
> bool f(T t, U u);
>
> * One thing that bothers me of this syntax (but that is also a problem=20
> in the template introduction one) is whether all identifiers inside=20
> the {} create new template parameters or if we can find a way of=20
> referring to identifiers in the scope of the declaration:
>
> void f(auto{T} t) {
>    [=3Dt](Comparable{U,T} x) { return u =3D=3D t; } // 1
> }
>
> Is there a possible concise syntax that unambiguously allows us to=20
> state that 'T' is not a type introduced by 'Comparable{U,T}'? I have=20
> considered some alternatives but I am not too fond of any of them, the=20
> one that seems lighter would be abusing additional curlies:
>
> Comparable{T, {U}} t // This introduces a new type T, but looks up U=20
> in the current scope, requires Comparable<T,U>, decltype(t) =3D=3D T
> Comparable{{T}, U} u // This introduces a new type U, but looks up T=20
> in the current scope, requires Comparable<T,U>, decltype(u) =3D=3D U (i.e=
..=20
> the syntax 'concept{x,y,z}' is equivalent to introducing the unescaped=20
> (by lack of a better name) types as template arguments and the=20
> subsitution of the placeholder for the first such introduced type.
>
> On Sat, Mar 7, 2015 at 12:20 PM, Jonathan Wakely <cxx@kayari.org=20
> <mailto:cxx@kayari.org>> wrote:
>
>     This wild speculation seems off-topic on c++std-core, can it be
>     continued just at std-discussion and/or std-proposals?
>
>     On 7 March 2015 at 16:51, Vicente J. Botet Escriba wrote:
>     > Le 06/03/15 19:58, Tony Van Eerd a =C3=A9crit :
>     >
>     > If all we need is auto, then is the next step:
>     >
>     > struct X
>     > {
>     >     int x;
>     >     auto y;
>     > };
>     >
>     > X is obviously a template?
>     > So is Y:
>     >
>     > struct Y
>     > {
>     >     int x;
>     >     ForwardIterator y;
>     > };
>     >
>     > =E2=80=8E?
>     >
>     > (Again, I'm not actually against 'auto means template
>     function'=E2=80=8E; I just
>     > bring up counter arguments to be comfortable that we explored
>     the design
>     > space and that we have a path of consistency going forward)
>     >
>     >
>     > While for template functions the type is deduced, how could you
>     deduce the
>     > type for auto or ForwardIterator. How would you declare an
>     instance of X, or
>     > a parameter of type X.
>     >
>     > X<???> v;
>     >
>     > what if we had
>     >
>     > struct X
>     > {
>     >     auto x;
>     >     auto y;
>     > };
>     >
>     > X<???, ???> v;
>     >
>     > Should the parameters need to be given in the order of
>     declaration of the
>     > auto/Concept data members?
>     >
>     > I find this confusing.
>     >
>     > Vicente
>
>     --
>
>     ---
>     You received this message because you are subscribed to the Google
>     Groups "ISO C++ Standard - Discussion" group.
>     To unsubscribe from this group and stop receiving emails from it,
>     send an email to std-discussion+unsubscribe@isocpp.org
>     <mailto:std-discussion%2Bunsubscribe@isocpp.org>.
>     To post to this group, send email to std-discussion@isocpp.org
>     <mailto:std-discussion@isocpp.org>.
>     Visit this group at
>     http://groups.google.com/a/isocpp.org/group/std-discussion/.
>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-discussion+unsubscribe@isocpp.org.
To post to this group, send email to std-discussion@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discuss=
ion/.

--------------040702070504010209010407
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    If someone has a proposal for changes to the concepts TS, I suggest
    they write a paper for the evolution group to consider.<br>
    <br>
    We have discussed "auto" and concepts for years (I first described
    "void f(auto);" to the EWG in 2004 or so) and I have seen little new
    or in terms of facilities or technical arguments in this long
    thread.<br>
    <br>
    <br>
    <div class=3D"moz-cite-prefix">On 3/7/2015 4:17 PM, David Rodr=C3=ADgue=
z
      Ibeas wrote:<br>
    </div>
    <blockquote
cite=3D"mid:CAD6_Qj_u=3Dtcm97+Ctx++gVxG7jPTWef_8jZ6-TJJPgFOr5cNsA@mail.gmai=
l.com"
      type=3D"cite">
      <div dir=3D"ltr">When I went over the concepts paper there were a
        couple of things that troubled me a bit (not a lot) and that are
        relevant to this discussion.=C2=A0 The first one is that the syntax
        does not call out that the identifier names a concept.=C2=A0 This i=
s
        also the case in C++14, C++11 and C++03, so nothing new, just
        adding one more dimension (before, a new type could be added
        that changed the meaning of an identifier), but with concepts
        and a non-distinguishible syntax now we have more interactions.
        <div><br>
        </div>
        <div>The second thing that concerned me is the variety of
          syntaxes to represent constrained templates.=C2=A0 This is driven
          by two conflicting goals: terseness and expressive power.=C2=A0 I=
n
          addition to that, I disliked the fact that the use of a
          place-holder type has different semantics: 'void f(auto x,
          auto y)' introduces two unrelated types for a and b, while
          'void f(concept a, concept b)' introduces a single type for
          both a and b.</div>
        <div><br>
        </div>
        <div>An alternative syntax that came to mind, was to use the
          syntax for the template introduction as a placeholder: 'void
          f(concept{T} x, concept{U} y)' would introduce two types T and
          U, both satisfying the 'concept' after the introduction of the
          type with 'concept{T}', the identifier T could be reused to
          represent the same type for different parameters: 'void
          f(concept{T} x, T y)' [equivalent to the Concepts TS: 'void
          f(concept x, concept y)'.=C2=A0 Compared with the previous syntax=
,
          there is a bit of overhead, but I don't consider that to be a
          *lot* of overhead.=C2=A0 Another advantage of this syntax is that
          in a concise form you can allow for multiple arguments to have
          different types satisfying the same concept: 'bool
          equal(FwdIter{It1} first, It1 last, FwdIter{It2} first2, It2
          last2)'.=C2=A0 This is currently not allowed in the concepts TS
          with the more concise syntax.</div>
        <div><br>
        </div>
        <div>As far as I know, this syntax is illegal in the language at
          this point, so it is clearly identifiable as relating to a
          concept, and could even be used to drive lookup to ignore
          types when searching for the identifier 'concept'.=C2=A0 The same
          syntax could be allowed (not required) for the auto
          placeholder to enable an unconstrained template in which two
          arguments are of the same type: void f(auto{T} x, T y).</div>
        <div><br>
        </div>
        <div>Similar to the template introduction case, it would be
          possible to use the syntax to introduce multiple types at
          once: 'bool equal(Comparable{T,U} const &amp; x, U const &amp;
          y) { return x =3D=3D y; }' If this is allowed, there would not be
          a need to have the template introduction syntax. This is
          really the same thing, except that it would not appear outside
          of the argument list, but inlined with the parameters, which
          makes it a valid alternative for lambas [](Comparable{T,U}
          const &amp; x, U const &amp; y) { return x =3D=3D y; }.</div>
        <div><br>
        </div>
        <div>Whether this is the good solution or something else is, I'd
          like to have less alternative syntaxes, and I am willing to
          pay a bit on terseness (this is not a huge difference) for
          clarity, reducing the alternatives and flexibility.</div>
        <div><br>
        </div>
        <div>=C2=A0 =C2=A0 David</div>
        <div><br>
        </div>
        <div>* An open question, for which I don't have a good answer is
          whether the syntax should be composable: bool
          f(concept1{concept2{T}, concept3{U}} t, U u) meaning:</div>
        <div><br>
        </div>
        <div>template &lt;typename T, typename U&gt;=C2=A0</div>
        <div>requires concept2&lt;T&gt; and concept3&lt;U&gt; and
          concept1&lt;T,U&gt; // pseudo code, not sure if this is valid
          syntax</div>
        <div>bool f(T t, U u);</div>
        <div><br>
        </div>
        <div>* One thing that bothers me of this syntax (but that is
          also a problem in the template introduction one) is whether
          all identifiers inside the {} create new template parameters
          or if we can find a way of referring to identifiers in the
          scope of the declaration:</div>
        <div><br>
        </div>
        <div>void f(auto{T} t) {</div>
        <div>=C2=A0 =C2=A0[=3Dt](Comparable{U,T} x) { return u =3D=3D t; } =
// 1</div>
        <div>}</div>
        <div><br>
        </div>
        <div>Is there a possible concise syntax that unambiguously
          allows us to state that 'T' is not a type introduced by
          'Comparable{U,T}'? I have considered some alternatives but I
          am not too fond of any of them, the one that seems lighter
          would be abusing additional curlies:</div>
        <div><br>
        </div>
        <div>Comparable{T, {U}} t // This introduces a new type T, but
          looks up U in the current scope, requires
          Comparable&lt;T,U&gt;, decltype(t) =3D=3D T</div>
        <div>Comparable{{T}, U} u // This introduces a new type U, but
          looks up T in the current scope, requires
          Comparable&lt;T,U&gt;, decltype(u) =3D=3D U (i.e. the syntax
          'concept{x,y,z}' is equivalent to introducing the unescaped
          (by lack of a better name) types as template arguments and the
          subsitution of the placeholder for the first such introduced
          type.</div>
      </div>
      <div class=3D"gmail_extra"><br>
        <div class=3D"gmail_quote">On Sat, Mar 7, 2015 at 12:20 PM,
          Jonathan Wakely <span dir=3D"ltr">&lt;<a moz-do-not-send=3D"true"
              href=3D"mailto:cxx@kayari.org" target=3D"_blank">cxx@kayari.o=
rg</a>&gt;</span>
          wrote:<br>
          <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">This wild
            speculation seems off-topic on c++std-core, can it be<br>
            continued just at std-discussion and/or std-proposals?<br>
            <div>
              <div class=3D"h5"><br>
                On 7 March 2015 at 16:51, Vicente J. Botet Escriba
                wrote:<br>
                &gt; Le 06/03/15 19:58, Tony Van Eerd a =C3=A9crit :<br>
                &gt;<br>
                &gt; If all we need is auto, then is the next step:<br>
                &gt;<br>
                &gt; struct X<br>
                &gt; {<br>
                &gt;=C2=A0 =C2=A0 =C2=A0int x;<br>
                &gt;=C2=A0 =C2=A0 =C2=A0auto y;<br>
                &gt; };<br>
                &gt;<br>
                &gt; X is obviously a template?<br>
                &gt; So is Y:<br>
                &gt;<br>
                &gt; struct Y<br>
                &gt; {<br>
                &gt;=C2=A0 =C2=A0 =C2=A0int x;<br>
                &gt;=C2=A0 =C2=A0 =C2=A0ForwardIterator y;<br>
                &gt; };<br>
                &gt;<br>
                &gt; =E2=80=8E?<br>
                &gt;<br>
                &gt; (Again, I'm not actually against 'auto means
                template function'=E2=80=8E; I just<br>
                &gt; bring up counter arguments to be comfortable that
                we explored the design<br>
                &gt; space and that we have a path of consistency going
                forward)<br>
                &gt;<br>
                &gt;<br>
                &gt; While for template functions the type is deduced,
                how could you deduce the<br>
                &gt; type for auto or ForwardIterator. How would you
                declare an instance of X, or<br>
                &gt; a parameter of type X.<br>
                &gt;<br>
                &gt; X&lt;???&gt; v;<br>
                &gt;<br>
                &gt; what if we had<br>
                &gt;<br>
                &gt; struct X<br>
                &gt; {<br>
                &gt;=C2=A0 =C2=A0 =C2=A0auto x;<br>
                &gt;=C2=A0 =C2=A0 =C2=A0auto y;<br>
                &gt; };<br>
                &gt;<br>
                &gt; X&lt;???, ???&gt; v;<br>
                &gt;<br>
                &gt; Should the parameters need to be given in the order
                of declaration of the<br>
                &gt; auto/Concept data members?<br>
                &gt;<br>
                &gt; I find this confusing.<br>
                &gt;<br>
                &gt; Vicente<br>
                <br>
                --<br>
                <br>
                ---<br>
              </div>
            </div>
            You received this message because you are subscribed to the
            Google Groups "ISO C++ Standard - Discussion" group.<br>
            To unsubscribe from this group and stop receiving emails
            from it, send an email to <a moz-do-not-send=3D"true"
              href=3D"mailto:std-discussion%2Bunsubscribe@isocpp.org">std-d=
iscussion+unsubscribe@isocpp.org</a>.<br>
            To post to this group, send email to <a
              moz-do-not-send=3D"true"
              href=3D"mailto:std-discussion@isocpp.org">std-discussion@isoc=
pp.org</a>.<br>
            Visit this group at <a moz-do-not-send=3D"true"
              href=3D"http://groups.google.com/a/isocpp.org/group/std-discu=
ssion/"
              target=3D"_blank">http://groups.google.com/a/isocpp.org/group=
/std-discussion/</a>.<br>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Discussion&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-discussion+unsubscribe@isocpp.org">std-discus=
sion+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-discussion@isocp=
p.org">std-discussion@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-discussion/">http://groups.google.com/a/isocpp.org/group/std-discussion=
/</a>.<br />

--------------040702070504010209010407--

.