Topic: Question about P0121R0 (Concepts TS)
Author: Andrei L <aendaerel@gmail.com>
Date: Mon, 23 Nov 2015 20:27:37 -0800 (PST)
Raw View
------=_Part_6104_304087845.1448339257221
Content-Type: multipart/alternative;
boundary="----=_Part_6105_223689246.1448339257221"
------=_Part_6105_223689246.1448339257221
Content-Type: text/plain; charset=UTF-8
Hello,
I've been reading through the paper and noticed this:
<..> An abbreviated function template is equivalent to a function template
> (14.6.6) whose template-parameter-list includes one invented
> template-parameter for each occurrence of a placeholder in the
> parameter-declaration-clause, in order of appearance <..>
>
Is this means that in such code:
template <typename T>
concept bool R = CheckSomething<T>;
auto foo(R a, R b) { /* ... */ }
parameters `a' and `b' have the same type? And if so, why? What is the
rationale behind that?
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_6105_223689246.1448339257221
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hello,<br><br>I've been reading through the paper and =
noticed this:<br><br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border=
-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quo=
te"><..> An abbreviated function template is equivalent to a function=
template (14.6.6) whose template-parameter-list includes one invented temp=
late-parameter for each occurrence of a placeholder in the parameter-declar=
ation-clause, in order of appearance <..><br></blockquote><br>Is this=
means that in such code:<br><span style=3D"font-family: courier new,monosp=
ace;"><br></span><div style=3D"margin-left: 40px;"><span style=3D"font-fami=
ly: courier new,monospace;">template <typename T></span><br><span sty=
le=3D"font-family: courier new,monospace;"></span><span style=3D"font-famil=
y: courier new,monospace;">concept bool R =3D CheckSomething<T>;</spa=
n><br><span style=3D"font-family: courier new,monospace;"></span><br><span =
style=3D"font-family: courier new,monospace;"></span><span style=3D"font-fa=
mily: courier new,monospace;">auto foo(R a, R b) { /* ... */ }</span><br></=
div><span style=3D"font-family: courier new,monospace;"></span><span style=
=3D"font-family: courier new,monospace;"></span><br><div style=3D"text-alig=
n: left;">parameters `a' and `b' have the same type? And if so, why=
? What is the rationale behind that?<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6105_223689246.1448339257221--
------=_Part_6104_304087845.1448339257221--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 23 Nov 2015 20:45:07 -0800 (PST)
Raw View
------=_Part_5943_688582974.1448340307852
Content-Type: multipart/alternative;
boundary="----=_Part_5944_628471929.1448340307852"
------=_Part_5944_628471929.1448340307852
Content-Type: text/plain; charset=UTF-8
On Monday, November 23, 2015 at 11:27:37 PM UTC-5, Andrei L wrote:
>
> Hello,
>
> I've been reading through the paper and noticed this:
>
> <..> An abbreviated function template is equivalent to a function template
>> (14.6.6) whose template-parameter-list includes one invented
>> template-parameter for each occurrence of a placeholder in the
>> parameter-declaration-clause, in order of appearance <..>
>>
>
> Is this means that in such code:
>
> template <typename T>
> concept bool R = CheckSomething<T>;
>
> auto foo(R a, R b) { /* ... */ }
>
> parameters `a' and `b' have the same type? And if so, why? What is the
> rationale behind that?
>
Because the meaning of that function can be one of two things: either `a`
and `b` must have the same type, or they may not. And there are valid use
cases where users will want one or the other.
You can always use full template syntax to express either one:
template<R T1, R T2> auto different(T1 t1, T2 t2);
template<R T> auto same(T t1, T t2);
But for shortened syntax, you have to pick one. And there are two criteria
for which to prefer:
1) Which one will users find more useful?
2) Which one will be the least confusing?
If you see the same typename in a parameter list, it's the same type. So it
would be very confusing to have something that *looks* like a typename, but
doesn't quite act like one. That is, the behavior they choose is the least
surprising to users.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5944_628471929.1448340307852
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Monday, November 23, 2015 at 11:27:37 PM UTC-5, Andrei L wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Hello,<br><br>=
I've been reading through the paper and noticed this:<br><br><blockquot=
e style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);=
padding-left:1ex" class=3D"gmail_quote"><..> An abbreviated function =
template is equivalent to a function template (14.6.6) whose template-param=
eter-list includes one invented template-parameter for each occurrence of a=
placeholder in the parameter-declaration-clause, in order of appearance &l=
t;..><br></blockquote><br>Is this means that in such code:<br><span styl=
e=3D"font-family:courier new,monospace"><br></span><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:courier new,monospace">template <type=
name T></span><br><span style=3D"font-family:courier new,monospace"></sp=
an><span style=3D"font-family:courier new,monospace">concept bool R =3D Che=
ckSomething<T>;</span><br><span style=3D"font-family:courier new,mono=
space"></span><br><span style=3D"font-family:courier new,monospace"></span>=
<span style=3D"font-family:courier new,monospace">auto foo(R a, R b) { /* .=
... */ }</span><br></div><span style=3D"font-family:courier new,monospace"><=
/span><span style=3D"font-family:courier new,monospace"></span><br><div sty=
le=3D"text-align:left">parameters `a' and `b' have the same type? A=
nd if so, why? What is the rationale behind that?<br></div></div></blockquo=
te><div><br>Because the meaning of that function can be one of two things: =
either `a` and `b` must have the same type, or they may not. And there are =
valid use cases where users will want one or the other.<br><br>You can alwa=
ys use full template syntax to express either one:<br><br><div class=3D"pre=
ttyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(=
187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-wo=
rd;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">R T1</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> R T2</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
different</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T1 t1</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> T2 t2</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">template</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">R T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> same</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">T t1</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> T t2</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">);</span></div></code></div><br=
>But for shortened syntax, you have to pick one. And there are two criteria=
for which to prefer:<br><br>1) Which one will users find more useful?<br><=
br>2) Which one will be the least confusing?<br><br>If you see the same typ=
ename in a parameter list, it's the same type. So it would be very conf=
using to have something that <i>looks</i> like a typename, but doesn't =
quite act like one. That is, the behavior they choose is the least surprisi=
ng to users.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5944_628471929.1448340307852--
------=_Part_5943_688582974.1448340307852--
.
Author: Zhihao Yuan <zy@miator.net>
Date: Mon, 23 Nov 2015 23:09:39 -0600
Raw View
On Mon, Nov 23, 2015 at 10:45 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
>
>
> 1) Which one will users find more useful?
>
> 2) Which one will be the least confusing?
My list for these has one more item -- "Which one causes less trouble?"
For all functions accepting >1 arguments utilizing hierarchy concepts
(where you need tag dispatching today, like STL iterators), you cannot
use terse syntax as specified today; for all functions perfect forwarding
>1 constrained arguments of the same concept, you cannot use terse
syntax as specified today (because C&& cannot be T& and T&& at the
same time). The designers know these, but they don't think it's worthy
to drop the same type requirement.
And I understand that there is no way you can convince all people
about whether a "preference" is right or wrong.
So I come with a conservative idea: how about a sign to opt-out such
a requirement:
auto f(R a, R' b); // a single quote after the concept, reads "R prime"
// you can have R'', R''', etc.; the number of ' has no limit, but you won't
// overuse it, right?
--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://bit.ly/blog4bsd
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Andrei L <aendaerel@gmail.com>
Date: Tue, 24 Nov 2015 14:19:03 +0500
Raw View
--001a113b7e9c334b61052545d5df
Content-Type: text/plain; charset=UTF-8
Well, that is exactly what i thought about reason to make it this way. But
in my opinion, this is clearly wrong.
If you see the same typename in a parameter list, it's the same type.
>
Agreed.
it would be very confusing to have something that *looks* like a typename,
> but doesn't quite act like one.
>
Not agreed.
I think, if one knows that there are such things as type constraints, then
one knows that they are not types, and what is their purpose. If one
doesn't know what is type constraint, one should learn.
And when one learned, will such thing as Callable, or Iterable, or Movable,
or any other *well named* constraint ever look like a type-name? And good
IDE with syntax highlight makes it even easier to distinguish what is type
and what is not.
It's not a problem at all, because for a new guy, everything looks scary
and unclear and confusing.
Also, given this function, where `auto' is a placeholder for a type that is
will be deduced,
auto foo(auto a, auto b)
can we strictly say that its parameters are of the same type?
And given this function, where `C' is a constraint,
auto foo(C a, C b)
can we strictly say that its parameters are of the same type?
Kind of, right? `C' and `C', same thing, but isn't that essentially a
shorthand for this?
auto foo(C<auto> a, C<auto> b)
Which is reads, as i see, "deduced types for parameters `a' and `b' must
meet requirement C". Not, "a and b have the same type which must meet
requirement C", there is no notion that `a' and `b' have same type. So,
they should not be of the same type.
And we also have variadic templates! Lets take a look
auto foo(C ...args)
And somehow, at least in current GCC implementation, such call is perfectly
valid
foo(1, "2", 3.0);
Here we deduce, and there we're not.
We can also think about it this way:
Suppose we wrote a function
auto foo(auto... ps) // types of the parameters will be deduced
And called it this way
foo(1, "2", 3.0) // called foo<int, char[2], double>(1, "2", 3.0)
Then we realized that we need first parameter to have a name
auto foo(auto a1, auto... ps) // types of the parameters still will be
deduced
foo(1, "2", 3.0) // called foo<int, char[2], double>(1, "2", 3.0)
And the we've also, given a name to a second parameter (for some reason)
auto foo(auto a1, auto a2, auto... ps) // types of the parameters still
will be deduced
foo(1, "2", 3.0) // called foo<int, char[2], double>(1, "2", 3.0)
So, what we did here. We had a function with some set of parameters. Then
we've took a couple (from that set), and gave them a names. Is something
happened with their types? No.
And now, lets constrain them
auto foo(C a1, C a2, C... ps)
Bam! Somehow `a1' and `a2' must be of the same type (and everything in ps
is not). Isn't type constraint supposed to just check a type (one type, one
type at one place, not everything around it) to meet requirements?
You can always use full template syntax to express either one:
>
> template<R T1, R T2> auto different(T1 t1, T2 t2);
>
> template<R T> auto same(T t1, T t2);
>
Yes, and you are forced to always fallback to full template, when you need
to allow parameters of different types. But you generally don't care about
exact type when you check if type of given argument meets some
requirements. That is the purpose of type constraint, to don't care about
exact type. If you need exact type, use exact type.
With inverted rules, if i say, "function `same' must take arguments of the
same type", then, with help of template-introduction, i can write it like
this:
R {T} auto same(T a1, T a2)
Here, no need to use full template syntax.
I could also write this function
R {T} auto same_not_all(T a1, T a2, R a3) // is a1, a2 and a3 here have
same type with current rules?
and that one
auto can_be_same(R a1, R a2)
and no `template <blah blah>' is needed.
So, what i want to say,
If we have a template function that accepts argument of any type, and we
want it to accept argument of some particular type, we constrain it.
If we have a template function that accepts unknown amount of arguments
(parameter pack), and we want it to accept only particular amount, we
constrain it.
If we have a function that accepts an int and only valid int for that
function is in range from 42 to 4242, we constrain it.
If there is something free, and we need it to be less free, we constrain it.
From wide to narrow, from any to exact.
2015-11-24 9:45 GMT+05:00 Nicol Bolas <jmckesson@gmail.com>:
>
>
> On Monday, November 23, 2015 at 11:27:37 PM UTC-5, Andrei L wrote:
>>
>> Hello,
>>
>> I've been reading through the paper and noticed this:
>>
>> <..> An abbreviated function template is equivalent to a function
>>> template (14.6.6) whose template-parameter-list includes one invented
>>> template-parameter for each occurrence of a placeholder in the
>>> parameter-declaration-clause, in order of appearance <..>
>>>
>>
>> Is this means that in such code:
>>
>> template <typename T>
>> concept bool R = CheckSomething<T>;
>>
>> auto foo(R a, R b) { /* ... */ }
>>
>> parameters `a' and `b' have the same type? And if so, why? What is the
>> rationale behind that?
>>
>
> Because the meaning of that function can be one of two things: either `a`
> and `b` must have the same type, or they may not. And there are valid use
> cases where users will want one or the other.
>
> You can always use full template syntax to express either one:
>
> template<R T1, R T2> auto different(T1 t1, T2 t2);
>
> template<R T> auto same(T t1, T t2);
>
> But for shortened syntax, you have to pick one. And there are two criteria
> for which to prefer:
>
> 1) Which one will users find more useful?
>
> 2) Which one will be the least confusing?
>
> If you see the same typename in a parameter list, it's the same type. So
> it would be very confusing to have something that *looks* like a
> typename, but doesn't quite act like one. That is, the behavior they choose
> is the least surprising to users.
>
> --
>
> ---
> 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-proposals+unsubscribe@isocpp.org.
>
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a113b7e9c334b61052545d5df
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div><div><div><div>Well, that is exactly what i thou=
ght about reason to make it this way. But in my opinion, this is clearly wr=
ong.<br><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px s=
olid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">If you see th=
e same typename in a parameter list, it's the same type.<br></blockquot=
e><div><br>Agreed.<br><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"=
>it would be very confusing to have something that <i>looks</i> like a type=
name, but doesn't quite act like one.<br></blockquote><div><br></div><d=
iv>Not agreed. <br></div></div><div>=C2=A0<br></div><div>I
think, if one knows that there are such things as type constraints,=20
then one knows that they are not types, and what is their purpose. If=20
one doesn't know what is type constraint, one should learn.<br><br>And =
when one learned, will such thing as Callable, or Iterable, or Movable, or =
any other <i>well named</i>
constraint ever look like a type-name? And good IDE with syntax=20
highlight makes it even easier to distinguish what is type and what is=20
not.<br><br></div><div>It's not a problem at all, because for a new guy=
, everything looks scary and unclear and confusing.<br><br></div><div>Also,=
given this function, where `auto' is a placeholder for a type that is =
will be deduced,<div style=3D"margin-left:40px"><br><span style=3D"font-fam=
ily:monospace,monospace">auto foo(auto a, auto b)</span><br></div><br></div=
><div>can we strictly say that its parameters are of the same type?<br></di=
v><div><br>And given this function, where `C' is a constraint,<div styl=
e=3D"margin-left:40px"><br></div><div style=3D"margin-left:40px"><span styl=
e=3D"font-family:monospace,monospace">auto foo(C a, C b)</span><br></div><b=
r></div><div>can we strictly say that its parameters are of the same type?<=
br><br></div><div>Kind of, right? `C' and `C', same thing, but isn&=
#39;t that essentially a shorthand for this?<br><div style=3D"margin-left:4=
0px"><br></div><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace">auto foo(C<auto> a, C<auto> b)</span><br><b=
r></div>Which
is reads, as i see, "deduced types for parameters `a' and `b'=
must meet=20
requirement C". Not, "a and b have the same type which must meet=
=20
requirement C", there is no notion that `a' and `b' have same =
type. So,=20
they should not be of the same type.<br><br></div>And we also have variadic=
templates! Lets take a look<br><div style=3D"margin-left:40px"><br></div><=
div style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospa=
ce">auto foo(C ...args)</span><br><br></div>And somehow, at least in curren=
t GCC implementation, such call is perfectly valid<br><div style=3D"margin-=
left:40px"><br></div><div style=3D"margin-left:40px"><span style=3D"font-fa=
mily:monospace,monospace">foo(1, "2", 3.0);</span><br><br></div>H=
ere we deduce, and there we're not.<br><br></div>We can also think abou=
t it this way:<br><br></div>Suppose we wrote a function<br><br><div style=
=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">auto =
foo(auto... ps) // types of the parameters will be deduced<br></span></div>=
<br>And called it this way<br><br><div style=3D"margin-left:40px"><span sty=
le=3D"font-family:monospace,monospace">foo(1, "2", 3.0) // called=
foo<int, char[2], double>(1, "2", 3.0)</span><br></div></d=
iv><div><span style=3D"font-family:monospace,monospace"></span><br>Then we =
realized that we need first parameter to have a name<br><br><div style=3D"m=
argin-left:40px"><span style=3D"font-family:monospace,monospace">auto foo(a=
uto a1, auto... ps) // types of the parameters still will be deduced</span>=
<br></div><br></div><div><span style=3D"font-family:monospace,monospace"></=
span><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,m=
onospace">foo(1, "2", 3.0) // called foo<int, char[2], double&=
gt;(1, "2", 3.0)</span></div></div><br>And the we've also, gi=
ven a name to a second parameter (for some reason)<br><br></div><div style=
=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">auto =
foo(auto a1, auto a2, auto... ps) // types of the parameters still will be =
deduced</span><br></div><br></div><div><span style=3D"font-family:monospace=
,monospace"></span><div style=3D"margin-left:40px"><span style=3D"font-fami=
ly:monospace,monospace">foo(1, "2", 3.0) // called foo<int, ch=
ar[2], double>(1, "2", 3.0)<br></span></div><br></div>So, what=
we did here. We had a function with some set of parameters. Then we've=
took a couple (from that set), and gave them a names. Is something happene=
d with their types? No.<br><div><br><div><span style=3D"font-family:monospa=
ce,monospace"></span><div>And now, lets constrain them<br></div><br><div st=
yle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">au=
to foo(C a1, C a2, C... ps)<br></span></div><br></div>Bam! Somehow `a1'=
and `a2' must be of the same type (and everything in ps is not). Isn&#=
39;t type constraint supposed to just check a type (one type, one type at o=
ne place, not everything around it) to meet requirements?<br><br><blockquot=
e style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);=
padding-left:1ex" class=3D"gmail_quote">You can always use full template sy=
ntax to express either one:<br><br><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;w=
ord-wrap:break-word"><code><div><span style=3D"color:rgb(0,0,136)">template=
</span><span style=3D"color:rgb(102,102,0)"><</span><span style=3D"color=
:rgb(0,0,0)">R T1</span><span style=3D"color:rgb(102,102,0)">,</span><span =
style=3D"color:rgb(0,0,0)"> R T2</span><span style=3D"color:rgb(102,102,0)"=
>></span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:r=
gb(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> different</span><=
span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)=
">T1 t1</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"c=
olor:rgb(0,0,0)"> T2 t2</span><span style=3D"color:rgb(102,102,0)">);</span=
><span style=3D"color:rgb(0,0,0)"><br><br></span><span style=3D"color:rgb(0=
,0,136)">template</span><span style=3D"color:rgb(102,102,0)"><</span><sp=
an style=3D"color:rgb(0,0,0)">R T</span><span style=3D"color:rgb(102,102,0)=
">></span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> same</span><span=
style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">T =
t1</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:=
rgb(0,0,0)"> T t2</span><span style=3D"color:rgb(102,102,0)">);</span></div=
></code></div></blockquote><div><br></div><div>Yes, and you are forced to a=
lways fallback to full template, when you need to allow parameters of diffe=
rent types. But you generally don't care about exact type when you chec=
k if type of given argument meets some requirements. That is the purpose of=
type constraint, to don't care about exact type. If you need exact typ=
e, use exact type.<br><br><br></div><div>With inverted rules, if i say, &qu=
ot;function `same' must take arguments of the same type", then, wi=
th help of template-introduction, i can write it like this:<br><br><div sty=
le=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">R {=
T} auto same(T a1, T a2)</span><br></div><div><span style=3D"font-family:mo=
nospace,monospace"><br></span></div><div><span style=3D"font-family:monospa=
ce,monospace"><font face=3D"arial,helvetica,sans-serif">Here, no need to us=
e full template syntax.</font><br></span></div><div><span style=3D"font-fam=
ily:arial,helvetica,sans-serif"><br>I could also write this function</span>=
<span style=3D"font-family:monospace,monospace"><br><br></span></div><div><=
div style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospa=
ce">R {T} auto same_not_all(T a1, T a2, R a3) // is a1, a2 and a3 here have=
same type with current rules?<br></span></div><br></div><div>and that one<=
br><br><div style=3D"margin-left:40px"><font face=3D"monospace,monospace">a=
uto can_be_same(R a1, R a2)</font><br></div><br></div><div>and no `template=
<blah blah>' is needed.<br></div><div><br>So, what i want to say=
,<br><br>If we have a template function that accepts argument of any type,=
=20
and we want it to accept argument of some particular type, we constrain=20
it.<br><div>If we have a template function that accepts unknown=20
amount of arguments (parameter pack), and we want it to accept only=20
particular amount, we constrain it.<br></div>If we have a function that acc=
epts an int and only valid int for that function is in range from 42 to 424=
2, we constrain it.<br></div><div><br>If there is something free, and we ne=
ed it to be less free, we constrain it.<br><br></div><div>From wide to narr=
ow, from any to exact.<br></div><div><span style=3D"font-family:monospace,m=
onospace"></span><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace"></span></div></div></div></div></div><div class=3D"gm=
ail_extra"><br><div class=3D"gmail_quote">2015-11-24 9:45 GMT+05:00 Nicol B=
olas <span dir=3D"ltr"><<a href=3D"mailto:jmckesson@gmail.com" target=3D=
"_blank">jmckesson@gmail.com</a>></span>:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><span class=3D""><br><br>On Monday, November 23, 2015 at 11:27:37 PM UT=
C-5, Andrei L wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
">Hello,<br><br>I've been reading through the paper and noticed this:<b=
r><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid r=
gb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><..> An abbre=
viated function template is equivalent to a function template (14.6.6) whos=
e template-parameter-list includes one invented template-parameter for each=
occurrence of a placeholder in the parameter-declaration-clause, in order =
of appearance <..><br></blockquote><br>Is this means that in such cod=
e:<br><span style=3D"font-family:courier new,monospace"><br></span><div sty=
le=3D"margin-left:40px"><span style=3D"font-family:courier new,monospace">t=
emplate <typename T></span><br><span style=3D"font-family:courier new=
,monospace"></span><span style=3D"font-family:courier new,monospace">concep=
t bool R =3D CheckSomething<T>;</span><br><span style=3D"font-family:=
courier new,monospace"></span><br><span style=3D"font-family:courier new,mo=
nospace"></span><span style=3D"font-family:courier new,monospace">auto foo(=
R a, R b) { /* ... */ }</span><br></div><span style=3D"font-family:courier =
new,monospace"></span><span style=3D"font-family:courier new,monospace"></s=
pan><br><div style=3D"text-align:left">parameters `a' and `b' have =
the same type? And if so, why? What is the rationale behind that?<br></div>=
</div></blockquote></span><div><br>Because the meaning of that function can=
be one of two things: either `a` and `b` must have the same type, or they =
may not. And there are valid use cases where users will want one or the oth=
er.<br><br>You can always use full template syntax to express either one:<b=
r><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,=
187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><d=
iv><span style=3D"color:#008">template</span><span style=3D"color:#660"><=
;</span><span style=3D"color:#000">R T1</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> R T2</span><span style=3D"color:#660">>=
;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">auto<=
/span><span style=3D"color:#000"> different</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">T1 t1</span><span style=3D"color:#660"=
>,</span><span style=3D"color:#000"> T2 t2</span><span style=3D"color:#660"=
>);</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#0=
08">template</span><span style=3D"color:#660"><</span><span style=3D"col=
or:#000">R T</span><span style=3D"color:#660">></span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">auto</span><span style=3D"color=
:#000"> same</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">T t1</span><span style=3D"color:#660">,</span><span style=3D"color:#0=
00"> T t2</span><span style=3D"color:#660">);</span></div></code></div><br>=
But for shortened syntax, you have to pick one. And there are two criteria =
for which to prefer:<br><br>1) Which one will users find more useful?<br><b=
r>2) Which one will be the least confusing?<br><br>If you see the same type=
name in a parameter list, it's the same type. So it would be very confu=
sing to have something that <i>looks</i> like a typename, but doesn't q=
uite act like one. That is, the behavior they choose is the least surprisin=
g to users.<span class=3D"HOEnZb"><font color=3D"#888888"><br></font></span=
></div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.</font></span><div class=3D=
"HOEnZb"><div class=3D"h5"><br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a113b7e9c334b61052545d5df--
.
Author: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 24 Nov 2015 02:07:44 -0800 (PST)
Raw View
------=_Part_1839_430757607.1448359664991
Content-Type: multipart/alternative;
boundary="----=_Part_1840_985262738.1448359664991"
------=_Part_1840_985262738.1448359664991
Content-Type: text/plain; charset=UTF-8
It's a source of endless confusion, I've seen many people asking the same
question for the last years.
You can
search https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/concepts
for relevant threads.
The main motivation is a shorter notation for functions taking two
iterators of the same type - void foo(Iterator begin, Iterator end) or
similar, they are considered a common case.
This motivation is pretty unconvincing given the arrival of ranges and
Iterator/Sentinel pairs, but the TS authors seem to stand as a wall on
defense of this rule. On the last year CppCon talk A. Sutton basically
answered something like "Because we work on this for years and know better
what you want" on another question "Why the same type?".
On Tuesday, November 24, 2015 at 7:27:37 AM UTC+3, Andrei L wrote:
>
> Hello,
>
> I've been reading through the paper and noticed this:
>
> <..> An abbreviated function template is equivalent to a function template
>> (14.6.6) whose template-parameter-list includes one invented
>> template-parameter for each occurrence of a placeholder in the
>> parameter-declaration-clause, in order of appearance <..>
>>
>
> Is this means that in such code:
>
> template <typename T>
> concept bool R = CheckSomething<T>;
>
> auto foo(R a, R b) { /* ... */ }
>
> parameters `a' and `b' have the same type? And if so, why? What is the
> rationale behind that?
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1840_985262738.1448359664991
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">It's a source of endless confusion, I've seen many=
people asking the same question for the last years.<div>You can search=C2=
=A0https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/concepts=
for relevant threads.</div><div>The main motivation is a shorter notation =
for functions taking two iterators of the same type - void foo(Iterator beg=
in, Iterator end) or similar, they are considered a common case.</div><div>=
This motivation is pretty unconvincing given the arrival of ranges and Iter=
ator/Sentinel pairs, but the TS authors seem to stand as a wall on defense =
of this rule. On the last year CppCon talk A. Sutton basically answered som=
ething like "Because we work on this for years and know better what yo=
u want" on another question "Why the same type?".<br><br>On =
Tuesday, November 24, 2015 at 7:27:37 AM UTC+3, Andrei L wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Hello,<br><br>I've be=
en reading through the paper and noticed this:<br><br><blockquote style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex" class=3D"gmail_quote"><..> An abbreviated function template is=
equivalent to a function template (14.6.6) whose template-parameter-list i=
ncludes one invented template-parameter for each occurrence of a placeholde=
r in the parameter-declaration-clause, in order of appearance <..><br=
></blockquote><br>Is this means that in such code:<br><span style=3D"font-f=
amily:courier new,monospace"><br></span><div style=3D"margin-left:40px"><sp=
an style=3D"font-family:courier new,monospace">template <typename T><=
/span><br><span style=3D"font-family:courier new,monospace"></span><span st=
yle=3D"font-family:courier new,monospace">concept bool R =3D CheckSomething=
<T>;</span><br><span style=3D"font-family:courier new,monospace"></sp=
an><br><span style=3D"font-family:courier new,monospace"></span><span style=
=3D"font-family:courier new,monospace">auto foo(R a, R b) { /* ... */ }</sp=
an><br></div><span style=3D"font-family:courier new,monospace"></span><span=
style=3D"font-family:courier new,monospace"></span><br><div style=3D"text-=
align:left">parameters `a' and `b' have the same type? And if so, w=
hy? What is the rationale behind that?<br></div></div></blockquote></div></=
div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1840_985262738.1448359664991--
------=_Part_1839_430757607.1448359664991--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 24 Nov 2015 09:10:53 -0800 (PST)
Raw View
------=_Part_490_871810957.1448385053676
Content-Type: multipart/alternative;
boundary="----=_Part_491_847337448.1448385053676"
------=_Part_491_847337448.1448385053676
Content-Type: text/plain; charset=UTF-8
On Tuesday, November 24, 2015 at 4:19:06 AM UTC-5, Andrei L wrote:
>
> Well, that is exactly what i thought about reason to make it this way. But
> in my opinion, this is clearly wrong.
>
> If you see the same typename in a parameter list, it's the same type.
>>
>
> Agreed.
>
> it would be very confusing to have something that *looks* like a
>> typename, but doesn't quite act like one.
>>
>
> Not agreed.
>
> I think, if one knows that there are such things as type constraints,
>
Well, that right there causes the confusion.
In my mind, the point of terse template function syntax is that the user *doesn't
care* if it's a type constraint or not. That you could take `auto foo(T t1,
T t2)` and turn it into `auto foo(C t1, C t2)` (where C is a concept that
matches T), and the only visible difference (besides which types are
allowed) is that you can't get a function pointer to it. As far as the user
is concerned, it works just like `int` or `vector<T>`. It looks like a
typename and it behaves like a typename.
If the user has to "know that there are such things as type constraints",
then I would say the syntax isn't doing its job.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_491_847337448.1448385053676
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Tuesday, November 24, 2015 at 4:19:06 AM UTC-5, Andrei L wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div><div=
><div><div>Well, that is exactly what i thought about reason to make it thi=
s way. But in my opinion, this is clearly wrong.<br><br><blockquote style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex" class=3D"gmail_quote">If you see the same typename in a paramete=
r list, it's the same type.<br></blockquote><div><br>Agreed.<br><br><bl=
ockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,20=
4,204);padding-left:1ex" class=3D"gmail_quote">it would be very confusing t=
o have something that <i>looks</i> like a typename, but doesn't quite a=
ct like one.<br></blockquote><div><br></div><div>Not agreed. <br></div></di=
v><div>=C2=A0<br></div><div>I
think, if one knows that there are such things as type constraints,</div><=
/div></div></div></div></div></div></blockquote><div><br>Well, that right t=
here causes the confusion.<br><br>In my mind, the point of terse template f=
unction syntax is that the user <i>doesn't care</i> if it's a type =
constraint or not. That you could take `auto foo(T t1, T t2)` and turn it i=
nto `auto foo(C t1, C t2)` (where C is a concept that matches T), and the o=
nly visible difference (besides which types are allowed) is that you can=
9;t get a function pointer to it. As far as the user is concerned, it works=
just like `int` or `vector<T>`. It looks like a typename and it beha=
ves like a typename.<br><br>If the user has to "know that there are su=
ch things as type constraints", then I would say the syntax isn't =
doing its job.</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_491_847337448.1448385053676--
------=_Part_490_871810957.1448385053676--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 24 Nov 2015 09:15:40 -0800 (PST)
Raw View
------=_Part_6944_643662818.1448385340450
Content-Type: multipart/alternative;
boundary="----=_Part_6945_1107802244.1448385340451"
------=_Part_6945_1107802244.1448385340451
Content-Type: text/plain; charset=UTF-8
On Tuesday, November 24, 2015 at 5:07:45 AM UTC-5, Vadim Petrochenkov wrote:
>
> It's a source of endless confusion, I've seen many people asking the same
> question for the last years.
>
And I'm sure there would be just as much confusion if it were the other way
around. If you're going to have terse syntax, you have to pick some answer.
And there will be people who want/expect the other way to be the default.
Personally, I like that answer, but I'm against terse syntax altogether...
> You can search
> https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/concepts
> for relevant threads.
> The main motivation is a shorter notation for functions taking two
> iterators of the same type - void foo(Iterator begin, Iterator end) or
> similar, they are considered a common case.
>
They're not "considered" a common case; in the absence of the Ranges TS, it
*is* a common case.
This motivation is pretty unconvincing given the arrival of ranges and
> Iterator/Sentinel pairs,
>
Iterator/Sentinel pairs don't use the same concept, so this rule will in no
way inhibit the ability of users to use terse syntax for ranges.
The motivation is still there because users will need to be able to have
multiple parameters of the same type. Iterators are just a prominent
example of this.
but the TS authors seem to stand as a wall on defense of this rule. On the
> last year CppCon talk A. Sutton basically answered something like "Because
> we work on this for years and know better what you want" on another
> question "Why the same type?".
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_6945_1107802244.1448385340451
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, November 24, 2015 at 5:07:45 AM UTC-5, Vadim P=
etrochenkov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">It's a source of endless confusion, I've seen many people aski=
ng the same question for the last years.</div></blockquote><div><br>And I&#=
39;m sure there would be just as much confusion if it were the other way ar=
ound. If you're going to have terse syntax, you have to pick some answe=
r. And there will be people who want/expect the other way to be the default=
..<br><br>Personally, I like that answer, but I'm against terse syntax a=
ltogether...<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div>You can search=C2=A0<a href=3D"https://groups.google.co=
m/a/isocpp.org/forum/?fromgroups#!forum/concepts" target=3D"_blank" rel=3D"=
nofollow" onmousedown=3D"this.href=3D'https://groups.google.com/a/isocp=
p.org/forum/?fromgroups#!forum/concepts';return true;" onclick=3D"this.=
href=3D'https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum=
/concepts';return true;">https://groups.google.<wbr>com/a/isocpp.org/fo=
rum/?<wbr>fromgroups#!forum/concepts</a> for relevant threads.</div><div>Th=
e main motivation is a shorter notation for functions taking two iterators =
of the same type - void foo(Iterator begin, Iterator end) or similar, they =
are considered a common case.</div></div></blockquote><div><br>They're =
not "considered" a common case; in the absence of the Ranges TS, =
it <i>is</i> a common case.<br><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div>This motivation is pretty unconvincing giv=
en the arrival of ranges and Iterator/Sentinel pairs,</div></div></blockquo=
te><div><br>Iterator/Sentinel pairs don't use the same concept, so this=
rule will in no way inhibit the ability of users to use terse syntax for r=
anges.<br><br>The motivation is still there because users will need to be a=
ble to have multiple parameters of the same type. Iterators are just a prom=
inent example of this.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div>but the TS authors seem to stand as a wall on d=
efense of this rule. On the last year CppCon talk A. Sutton basically answe=
red something like "Because we work on this for years and know better =
what you want" on another question "Why the same type?".</di=
v></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6945_1107802244.1448385340451--
------=_Part_6944_643662818.1448385340450--
.
Author: Nevin Liber <nevin@cplusplusguy.com>
Date: Tue, 24 Nov 2015 13:06:28 -0600
Raw View
--089e0141a1625216a105254e0cea
Content-Type: text/plain; charset=UTF-8
On 24 November 2015 at 04:07, Vadim Petrochenkov <
vadim.petrochenkov@gmail.com> wrote:
> It's a source of endless confusion, I've seen many people asking the same
> question for the last years.
> You can search
> https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/concepts
> for relevant threads.
> The main motivation is a shorter notation for functions taking two
> iterators of the same type - void foo(Iterator begin, Iterator end) or
> similar, they are considered a common case.
>
While I don't consider that particularly motivating (because in most of
those algorithms begin..end is a range and end is usually just a sentinel
which does not need to be the same type as begin; typically the only
operation performed on it is equality comparing it with an iterator that
has the same type as begin, unless it is a random access iterator, in which
case one might calculate end - begin), at the end of the day, we have to
pick whether the terse syntax should under constrain (by allowing them to
be two different types) or over constrain (by requiring them to be the same
type). While I personally prefer the former, it isn't a strong enough
preference to push any farther than bringing it up with those immersed in
getting Concepts out the door (which I did a while back).
That being said, I do find Zhihao's idea intriguing...
--
Nevin ":-)" Liber <mailto:nevin@cplusplusguy.com <nevin@eviloverlord.com>>
+1-847-691-1404
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0141a1625216a105254e0cea
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 24 November 2015 at 04:07, Vadim Petrochenkov <span dir=
=3D"ltr"><<a href=3D"mailto:vadim.petrochenkov@gmail.com" target=3D"_bla=
nk">vadim.petrochenkov@gmail.com</a>></span> wrote:<br><div class=3D"gma=
il_extra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr">It's a source of endless confusion, I've seen many people=
asking the same question for the last years.<div>You can search=C2=A0<a hr=
ef=3D"https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/conce=
pts" target=3D"_blank">https://groups.google.com/a/isocpp.org/forum/?fromgr=
oups#!forum/concepts</a> for relevant threads.</div><div>The main motivatio=
n is a shorter notation for functions taking two iterators of the same type=
- void foo(Iterator begin, Iterator end) or similar, they are considered a=
common case.</div></div></blockquote><div><br></div><div>While I don't=
consider that particularly motivating (because in most of those algorithms=
begin..end is a range and end is usually just a sentinel which does not ne=
ed to be the same type as begin; typically the only operation performed on =
it is equality comparing it with an iterator that has the same type as begi=
n, unless it is a random access iterator, in which case one might calculate=
end - begin), at the end of the day, we have to pick whether the terse syn=
tax should under constrain (by allowing them to be two different types) or =
over constrain (by requiring them to be the same type).=C2=A0 While I perso=
nally prefer the former, it isn't a strong enough preference to push an=
y farther than bringing it up with those immersed in getting Concepts out t=
he door (which I did a while back).</div><div><br></div><div>That being sai=
d, I do find Zhihao's idea intriguing...<br clear=3D"all"><div><br></di=
v>-- <br><div class=3D"gmail_signature"><div dir=3D"ltr">=C2=A0Nevin "=
:-)" Liber=C2=A0 <mailto:<a href=3D"mailto:nevin@eviloverlord.com" =
target=3D"_blank">nevin@cplusplusguy.com</a>>=C2=A0 +1-847-691-1404<br><=
/div></div>
</div></div></div>
</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0141a1625216a105254e0cea--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Tue, 24 Nov 2015 21:43:53 +0100
Raw View
--047d7ba975305ec6df05254f666e
Content-Type: text/plain; charset=UTF-8
On Tue, Nov 24, 2015 at 6:09 AM, Zhihao Yuan <zy@miator.net> wrote:
> So I come with a conservative idea: how about a sign to opt-out such
> a requirement:
>
> auto f(R a, R' b); // a single quote after the concept, reads "R prime"
> // you can have R'', R''', etc.; the number of ' has no limit, but you
> won't
> // overuse it, right?
I was thinking something similar, but using indexes somehow:
auto f(R.0 a, R.1 b)
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7ba975305ec6df05254f666e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Nov 24, 2015 at 6:09 AM, Zhihao Yuan <span dir=3D"ltr"><<a href=3D"m=
ailto:zy@miator.net" target=3D"_blank">zy@miator.net</a>></span> wrote:<=
br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:soli=
d;padding-left:1ex">So I come with a conservative idea: how about a sign to=
opt-out such<br>
a requirement:<br>
<br>
=C2=A0 auto f(R a, R' b);=C2=A0 // a single quote after the concept, re=
ads "R prime"<br>
=C2=A0 // you can have R'', R''', etc.; the number of &=
#39; has no limit, but you won't<br>
=C2=A0 // overuse it, right?</blockquote><div>=C2=A0</div><div>I was thinki=
ng something similar, but using indexes somehow:</div><div><br></div><div><=
div>auto f(R.0 a, R.1 b)</div></div><div><br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7ba975305ec6df05254f666e--
.
Author: Casey Carter <cartec69@gmail.com>
Date: Tue, 24 Nov 2015 12:48:18 -0800 (PST)
Raw View
------=_Part_28_995085506.1448398098375
Content-Type: multipart/alternative;
boundary="----=_Part_29_1577473584.1448398098375"
------=_Part_29_1577473584.1448398098375
Content-Type: text/plain; charset=UTF-8
On Tuesday, November 24, 2015 at 1:07:11 PM UTC-6, Nevin Liber wrote:
>
> at the end of the day, we have to pick whether the terse syntax should
> under constrain (by allowing them to be two different types) or over
> constrain (by requiring them to be the same type). While I personally
> prefer the former, it isn't a strong enough preference to push any farther
> than bringing it up with those immersed in getting Concepts out the door
> (which I did a while back).
>
>
This exactly. There are reasons both for and against any particular set of
semantics for terse syntax. Either we pick one, and usages that would be
simpler to express with another use the longer syntax, or we pick none and
all usages use the long syntax. The committee deliberated and decided it
was better to pick one than zero. Honestly it makes little difference,
since the majority of usages need to refer to the parameter types either in
the return type or in a requires clause. When that's the case it's
preferable to use the longer syntax and have reasonable names for parameter
types than use the terse syntax and sprinkle decltype(foo) and
decltype(bar) everywhere.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_29_1577473584.1448398098375
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, November 24, 2015 at 1:07:11 PM UTC-6, Nevin L=
iber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv><div class=3D"gmail_quote"><div>at the end of the day, we have to pick w=
hether the terse syntax should under constrain (by allowing them to be two =
different types) or over constrain (by requiring them to be the same type).=
=C2=A0 While I personally prefer the former, it isn't a strong enough p=
reference to push any farther than bringing it up with those immersed in ge=
tting Concepts out the door (which I did a while back).</div><div><br></div=
></div></div></div></blockquote><div><br></div><div>This exactly. There are=
reasons both for and against any particular set of semantics for terse syn=
tax. Either we pick one, and usages that would be simpler to express with a=
nother use the longer syntax, or we pick none and all usages use the long s=
yntax. The committee deliberated and decided it was better to pick one than=
zero. Honestly it makes little difference, since the majority of usages ne=
ed to refer to the parameter types either in the return type or in a requir=
es clause. When that's the case it's preferable to use the longer s=
yntax and have reasonable names for parameter types than use the terse synt=
ax and sprinkle decltype(foo) and decltype(bar) everywhere.</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_29_1577473584.1448398098375--
------=_Part_28_995085506.1448398098375--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 24 Nov 2015 22:51:54 +0200
Raw View
On 24 November 2015 at 22:43, Andrew Tomazos <andrewtomazos@gmail.com> wrote:
> On Tue, Nov 24, 2015 at 6:09 AM, Zhihao Yuan <zy@miator.net> wrote:
>>
>> So I come with a conservative idea: how about a sign to opt-out such
>> a requirement:
>>
>> auto f(R a, R' b); // a single quote after the concept, reads "R prime"
>> // you can have R'', R''', etc.; the number of ' has no limit, but you
>> won't
>> // overuse it, right?
>
>
> I was thinking something similar, but using indexes somehow:
>
> auto f(R.0 a, R.1 b)
At this point I must advise caution against getting ahead of design
rationale with
outlandish syntax suggestions.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Tue, 24 Nov 2015 21:54:57 +0100
Raw View
--047d7bb70c7ef5b62b05254f8dcf
Content-Type: text/plain; charset=UTF-8
On Tue, Nov 24, 2015 at 6:10 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> In my mind, the point of terse template function syntax is that the user *doesn't
> care* if it's a type constraint or not. That you could take `auto foo(T
> t1, T t2)` and turn it into `auto foo(C t1, C t2)` (where C is a concept
> that matches T), and the only visible difference (besides which types are
> allowed) is that you can't get a function pointer to it. As far as the user
> is concerned, it works just like `int` or `vector<T>`. It looks like a
> typename and it behaves like a typename.
>
If we think of a concept as a compile-time interface (where a pure virtual
class is a run-time interface), then we would expect:
class Animal { ... };
class Dog : Animal { ... };
class Cat : Animal { ... };
void f(const Animal& a, const Animal& b);
Dog dog;
Cat cat;
f(dog, cat);
This argues for allowing different types.
However, as others have pointed out there is a long form for expressing
either option, so the short-hand default isn't as important. Concepts has
been bouncing around in design phase for many many years so at some point
we need to hold our nose and get fracking v1 out the door.
It will ship in GCC 6.0 and implementation is partially completed in Clang
too. Don't know about MSVC or EDG, they gave me the silent treatment.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7bb70c7ef5b62b05254f8dcf
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Nov 24, 2015 at 6:10 PM, Nicol Bolas <span dir=3D"ltr"><<a href=3D"m=
ailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-lef=
t-style:solid;padding-left:1ex"><div>In my mind, the point of terse templat=
e function syntax is that the user <i>doesn't care</i> if it's a ty=
pe constraint or not. That you could take `auto foo(T t1, T t2)` and turn i=
t into `auto foo(C t1, C t2)` (where C is a concept that matches T), and th=
e only visible difference (besides which types are allowed) is that you can=
't get a function pointer to it. As far as the user is concerned, it wo=
rks just like `int` or `vector<T>`. It looks like a typename and it b=
ehaves like a typename.</div></blockquote><div>=C2=A0</div><div>If we think=
of a concept as a compile-time interface (where a pure virtual class is a =
run-time interface), then we would expect:</div><div><br></div><div>=C2=A0 =
=C2=A0class Animal { ... };</div><div>=C2=A0 =C2=A0class=C2=A0Dog : Animal =
{ ... };</div><div>=C2=A0 =C2=A0class=C2=A0Cat : Animal { ... };</div><div>=
<br></div><div>=C2=A0 =C2=A0void f(const Animal& a, const Animal& b=
);</div><div><br></div><div>=C2=A0 =C2=A0Dog dog;</div><div>=C2=A0 =C2=A0Ca=
t cat;</div><div><br></div><div>=C2=A0 =C2=A0f(dog, cat);</div><div><br></d=
iv><div>This argues for allowing different types.</div></div><br></div><div=
class=3D"gmail_extra">However, as others have pointed out there is a long =
form for expressing either option, so the short-hand default isn't as i=
mportant.=C2=A0 Concepts has been bouncing around in design phase for many =
many years so at some point we need to hold our nose and get fracking v1 ou=
t the door.</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_e=
xtra">It will ship in GCC 6.0 and implementation is partially completed in =
Clang too.=C2=A0 Don't know about MSVC or EDG, they gave me the silent =
treatment.</div><div class=3D"gmail_extra"><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7bb70c7ef5b62b05254f8dcf--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 24 Nov 2015 14:32:19 -0800
Raw View
On Monday 23 November 2015 20:27:37 Andrei L wrote:
> Hello,
>
> I've been reading through the paper and noticed this:
>
> <..> An abbreviated function template is equivalent to a function template
>
> > (14.6.6) whose template-parameter-list includes one invented
> > template-parameter for each occurrence of a placeholder in the
> > parameter-declaration-clause, in order of appearance <..>
>
> Is this means that in such code:
>
> template <typename T>
> concept bool R = CheckSomething<T>;
>
> auto foo(R a, R b) { /* ... */ }
>
> parameters `a' and `b' have the same type? And if so, why? What is the
> rationale behind that?
Whichever way you choose, you're going to disappoint someone.
I've seen arguments for and against specifying the same type and it's easy to
argue for the other side. One example for both cases:
compare(InputIterator begin1, InputIterator end1, InputIterator begin2)
Here, begin2 does not need to have the same type as begin1 and end1. In fact,
one could argue that even begin1 and end1 need not be the same type, so long
as they're comparable to one another. But the most common case is that begin1
and end1 have the same type.
In fact, the requirement that begin1 and end1 be comparable should be part of
the concept signature, which means a function that would accept two different
iterator types would need to be:
compare(InputIterator begin1,
InputIteratorComparableTo<decltype(begin1)> end1,
InputIterator begin2)
And since the second iterator has a different declaration from the first, this
cannot be used as an argument for supporting the case where they need to be
different.
Anyway, maybe we should look into the principle of least surprise. Which case
would cause most surprise if used incorrectly?
a) the case where an API constrains the types more than it should
b) the case where an API fails to constrain the types as much as it should
In case a, the misuse would result in the compiler failing to compile and
reporting the reason why the concepts failed to match. In case b, the compiler
would accept the overload, proceed to instantiate the template, and possibly
run into an error later where the assumption failed.
Given that one of the stated goals of Concepts is to give us better error
messages because types are checked against the concept prior to the overload
selection, I'd say that the biggest surprise is case b.
That would support the solution as it is today: the same concept name used
more than once means the same type.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 24 Nov 2015 14:40:49 -0800
Raw View
On Tuesday 24 November 2015 21:54:57 Andrew Tomazos wrote:
> On Tue, Nov 24, 2015 at 6:10 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> > In my mind, the point of terse template function syntax is that the user
> > *doesn't care* if it's a type constraint or not. That you could take
> > `auto foo(T t1, T t2)` and turn it into `auto foo(C t1, C t2)` (where C
> > is a concept that matches T), and the only visible difference (besides
> > which types are allowed) is that you can't get a function pointer to it.
> > As far as the user is concerned, it works just like `int` or `vector<T>`.
> > It looks like a typename and it behaves like a typename.
>
> If we think of a concept as a compile-time interface (where a pure virtual
> class is a run-time interface), then we would expect:
>
> class Animal { ... };
> class Dog : Animal { ... };
> class Cat : Animal { ... };
>
> void f(const Animal& a, const Animal& b);
>
> Dog dog;
> Cat cat;
>
> f(dog, cat);
>
> This argues for allowing different types.
That's an example of polymorphism but it's showing the same type: Animal. So I
don't agree with you that it argues for allowing different types.
It would argue for different type if you could compile:
class Shape {};
class Triangle : Shape {};
Triangle triangle;
f(dog, triangle);
And that's not the case.
Concepts are not base classes. Polymorphism implies that there are at least
two types in consideration: the interface type and the concrete type. You can
declare:
Animal *ptr = new Dog;
ptr = new Cat;
But you cannot do that for a concept:
InputIterator it = std::string::const_iterator{};
it = std::vector<int>::const_iterator{};
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 24 Nov 2015 15:01:51 -0800 (PST)
Raw View
------=_Part_5892_442684804.1448406111878
Content-Type: multipart/alternative;
boundary="----=_Part_5893_1907540473.1448406111879"
------=_Part_5893_1907540473.1448406111879
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
There is another aspect of this apart from which use case is more common,=
=20
or intuitive: How hard is it to express the other possible intent?
If a concept name means the same type for all parameters we need to do this=
=20
to declare the compare function mentioned above:
template<InputIterator I1, InputIterator I2> bool compare(I1 begin1, I1=20
end1, I2 begin2);=20
If each occurance of the InputIterator concept is separate we can still=20
write:
bool compare(InputIterator begin1, decltype(begin1) end1, InputIterator=20
begin2);
I thinks this speaks at least a little for allowing different types, as the=
=20
more limited requirement can still be expressed within the terse syntax.
Another issue regards the use of auto as the "catch all" type which works=
=20
according to the "separate paradigm:
*For a generic lambda, the closure type has a public inline function call=
=20
operator member template (14.5.2) whose template-parameter-list consists of=
=20
one invented type template-parameter for each occurrence of auto in the=20
lambda=E2=80=99s parameter-declaration-clause, in order of appearance*
To select the other option for limited template parameters seems to creat=
=20
anothre inconsistency.
I always considered the requirement that all variables declared in an auto=
=20
variable declaration have the same base type a mistake. Who can come up=20
with a case when reversing this decision breaks existing code. I tried this=
:
auto a=3D1, b=3D2.0;
which would conceivably change b from being an int initialized with a=20
double to a double, but the compiler didn't like that.
Apart from the quite obvious nicety of being able to write the above=20
declaration my main motivation was that for-init statements like this would=
=20
work naturally:
for (auto iter =3D vec.begin(), ix =3D 0; iter !=3D vec.end(), iter++, ix++=
)
....
Superficially this ship has long since sailed but if noone can find a use=
=20
case preventing the reversal of the decision we could possibly unify all=20
uses of auto and concepts if we go in the direction of separating each use.
Den tisdag 24 november 2015 kl. 23:32:23 UTC+1 skrev Thiago Macieira:
>
> On Monday 23 November 2015 20:27:37 Andrei L wrote:=20
> > Hello,=20
> >=20
> > I've been reading through the paper and noticed this:=20
> >=20
> > <..> An abbreviated function template is equivalent to a function=20
> template=20
> >=20
> > > (14.6.6) whose template-parameter-list includes one invented=20
> > > template-parameter for each occurrence of a placeholder in the=20
> > > parameter-declaration-clause, in order of appearance <..>=20
> >=20
> > Is this means that in such code:=20
> >=20
> > template <typename T>=20
> > concept bool R =3D CheckSomething<T>;=20
> >=20
> > auto foo(R a, R b) { /* ... */ }=20
> >=20
> > parameters `a' and `b' have the same type? And if so, why? What is the=
=20
> > rationale behind that?=20
>
> Whichever way you choose, you're going to disappoint someone.=20
>
> I've seen arguments for and against specifying the same type and it's eas=
y=20
> to=20
> argue for the other side. One example for both cases:=20
>
> compare(InputIterator begin1, InputIterator end1, InputIterator=
=20
> begin2)=20
>
> Here, begin2 does not need to have the same type as begin1 and end1. In=
=20
> fact,=20
> one could argue that even begin1 and end1 need not be the same type, so=
=20
> long=20
> as they're comparable to one another. But the most common case is that=20
> begin1=20
> and end1 have the same type.=20
>
> In fact, the requirement that begin1 and end1 be comparable should be par=
t=20
> of=20
> the concept signature, which means a function that would accept two=20
> different=20
> iterator types would need to be:=20
>
> compare(InputIterator begin1,=20
> InputIteratorComparableTo<decltype(begin1)> end1,=20
> InputIterator begin2)=20
>
> And since the second iterator has a different declaration from the first,=
=20
> this=20
> cannot be used as an argument for supporting the case where they need to=
=20
> be=20
> different.=20
>
> Anyway, maybe we should look into the principle of least surprise. Which=
=20
> case=20
> would cause most surprise if used incorrectly?=20
>
> a) the case where an API constrains the types more than it should=20
> b) the case where an API fails to constrain the types as much as it=20
> should=20
>
> In case a, the misuse would result in the compiler failing to compile and=
=20
> reporting the reason why the concepts failed to match. In case b, the=20
> compiler=20
> would accept the overload, proceed to instantiate the template, and=20
> possibly=20
> run into an error later where the assumption failed.=20
>
> Given that one of the stated goals of Concepts is to give us better error=
=20
> messages because types are checked against the concept prior to the=20
> overload=20
> selection, I'd say that the biggest surprise is case b.=20
>
> That would support the solution as it is today: the same concept name use=
d=20
> more than once means the same type.=20
>
> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org=20
> Software Architect - Intel Open Source Technology Center=20
> PGP/GPG: 0x6EF45358; fingerprint:=20
> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358=20
>
>
--=20
---=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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_5893_1907540473.1448406111879
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">There is another aspect of this apart from which use case =
is more common, or intuitive: How hard is it to express the other possible =
intent?<div><br></div><div>If a concept name means the same type for all pa=
rameters we need to do this to declare the compare function mentioned above=
:</div><div><br></div><div>template<InputIterator I1, InputIterator I2&g=
t; bool compare(I1 begin1, I1 end1, I2 begin2);=C2=A0</div><div><br></div><=
div>If each occurance of the InputIterator concept is separate we can still=
write:</div><div><br></div><div>bool compare(InputIterator begin1, decltyp=
e(begin1) end1, InputIterator begin2);<br></div><div><br></div><div>I think=
s this speaks at least a little for allowing different types, as the more l=
imited requirement can still be expressed within the terse syntax.</div><di=
v><br></div><div>Another issue regards the use of auto as the "catch a=
ll" type which works according to the "separate paradigm:</div><d=
iv><br></div><div><strong style=3D"font-size: 15px; font-family: Arial, =
9;Helvetica Neue', Helvetica, sans-serif; line-height: 19.5px; backgrou=
nd-color: rgb(255, 249, 227);">For a generic lambda, the closure type has a=
public inline function call operator member template (14.5.2) whose templa=
te-parameter-list consists of one invented type template-parameter for each=
occurrence of auto in the lambda=E2=80=99s parameter-declaration-clause, i=
n order of appearance</strong><br></div><div><strong style=3D"font-size: 15=
px; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; li=
ne-height: 19.5px; background-color: rgb(255, 249, 227);"><br></strong></di=
v><div><font face=3D"Arial, Helvetica Neue, Helvetica, sans-serif" size=3D"=
2"><span style=3D"line-height: 19.5px; background-color: rgb(255, 249, 227)=
;">To select the other option for limited template parameters seems to crea=
t anothre inconsistency.</span></font></div><div><br></div><div>I always co=
nsidered the requirement that all variables declared in an auto variable de=
claration have the same base type a mistake. Who can come up with a case wh=
en reversing this decision breaks existing code. I tried this:</div><div><b=
r></div><div>auto a=3D1, b=3D2.0;<br></div><div><br></div><div>which would =
conceivably change b from being an int initialized with a double to a doubl=
e, but the compiler didn't like that.</div><div><br></div><div>Apart fr=
om the quite obvious nicety of being able to write the above declaration my=
main motivation was that for-init statements like this would work naturall=
y:</div><div><br></div><div>for (auto iter =3D vec.begin(), ix =3D 0; iter =
!=3D vec.end(), iter++, ix++)</div><div>=C2=A0 =C2=A0 ....</div><div><br></=
div><div>Superficially this ship has long since sailed but if noone can fin=
d a use case preventing the reversal of the decision we could possibly unif=
y all uses of auto and concepts if we go in the direction of separating eac=
h use.</div><div><br><br>Den tisdag 24 november 2015 kl. 23:32:23 UTC+1 skr=
ev Thiago Macieira:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Monday 2=
3 November 2015 20:27:37 Andrei L wrote:
<br>> Hello,
<br>>=20
<br>> I've been reading through the paper and noticed this:
<br>>=20
<br>> <..> An abbreviated function template is equivalent to a fun=
ction template
<br>>=20
<br>> > (14.6.6) whose template-parameter-list includes one invented
<br>> > template-parameter for each occurrence of a placeholder in th=
e
<br>> > parameter-declaration-clause, in order of appearance <..&g=
t;
<br>>=20
<br>> Is this means that in such code:
<br>>=20
<br>> template <typename T>
<br>> concept bool R =3D CheckSomething<T>;
<br>>=20
<br>> auto foo(R a, R b) { /* ... */ }
<br>>=20
<br>> parameters `a' and `b' have the same type? And if so, why?=
What is the
<br>> rationale behind that?
<br>
<br>Whichever way you choose, you're going to disappoint someone.
<br>
<br>I've seen arguments for and against specifying the same type and it=
's easy to=20
<br>argue for the other side. One example for both cases:
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0compare(InputIterator b=
egin1, InputIterator end1, InputIterator begin2)
<br>
<br>Here, begin2 does not need to have the same type as begin1 and end1. In=
fact,=20
<br>one could argue that even begin1 and end1 need not be the same type, so=
long=20
<br>as they're comparable to one another. But the most common case is t=
hat begin1=20
<br>and end1 have the same type.
<br>
<br>In fact, the requirement that begin1 and end1 be comparable should be p=
art of=20
<br>the concept signature, which means a function that would accept two dif=
ferent=20
<br>iterator types would need to be:
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0compare(InputIterator b=
egin1,=20
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0<wbr>InputIteratorComparableTo<<wbr>decltype(=
begin1)> end1,
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0InputIterator begin2)
<br>
<br>And since the second iterator has a different declaration from the firs=
t, this=20
<br>cannot be used as an argument for supporting the case where they need t=
o be=20
<br>different.
<br>
<br>Anyway, maybe we should look into the principle of least surprise. Whic=
h case=20
<br>would cause most surprise if used incorrectly?
<br>
<br>=C2=A0a) the case where an API constrains the types more than it should
<br>=C2=A0b) the case where an API fails to constrain the types as much as =
it should
<br>
<br>In case a, the misuse would result in the compiler failing to compile a=
nd=20
<br>reporting the reason why the concepts failed to match. In case b, the c=
ompiler=20
<br>would accept the overload, proceed to instantiate the template, and pos=
sibly=20
<br>run into an error later where the assumption failed.
<br>
<br>Given that one of the stated goals of Concepts is to give us better err=
or=20
<br>messages because types are checked against the concept prior to the ove=
rload=20
<br>selection, I'd say that the biggest surprise is case b.
<br>
<br>That would support the solution as it is today: the same concept name u=
sed=20
<br>more than once means the same type.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.goo=
gle.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQ=
jCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;" onclick=3D"this.href=3D&=
#39;http://www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46snt=
z\0751\46usg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;">maciei=
ra.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"_blank" rel=
=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google.com/url?q\7=
5http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJdo5_JYG1Dowztw=
AHAKs80XSA';return true;" onclick=3D"this.href=3D'http://www.google=
..com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJdo=
5_JYG1DowztwAHAKs80XSA';return true;">kde.org</a>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:
<br>=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C =C2=A0966C 33F5 F005 6EF4=
5358
<br>
<br></blockquote></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5893_1907540473.1448406111879--
------=_Part_5892_442684804.1448406111878--
.
Author: Andrei L <aendaerel@gmail.com>
Date: Wed, 25 Nov 2015 04:14:09 +0500
Raw View
--089e01177a4dc1d85a0525517fea
Content-Type: text/plain; charset=UTF-8
>
> One example for both cases:
>
compare(InputIterator begin1, InputIterator end1, InputIterator begin2)
>
>
Here, begin2 does not need to have the same type as begin1 and end1. In
> fact,
> one could argue that even begin1 and end1 need not be the same type, so
> long
> as they're comparable to one another. But the most common case is that
> begin1
> and end1 have the same type.
>
template <typename T>
concept bool InputIterator = Iterator<I> && requires (I i) { /* ... */ };
InputIterator {I} bool compare(I begin1, I end1, InputIterator begin2)
How about that one? Both are Iterators, both are comparable. begin2 not
required to be the same.
In fact, the requirement that begin1 and end1 be comparable should be part
> of
> the concept signature, which means a function that would accept two
> different
> iterator types would need to be:
>
> compare(InputIterator begin1,
> InputIteratorComparableTo<decltype(begin1)> end1,
> InputIterator begin2)
>
> And since the second iterator has a different declaration from the first,
> this
> cannot be used as an argument for supporting the case where they need to be
> different.
>
template <typename I, typename S>
concept bool InputIterator_Sentinel = InputIterator<I> &&
Iterator_Sentinel<I, S>
InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIterator
begin2)
Comparable, and not required to be the same.
Easy enough, i think.
2015-11-25 3:32 GMT+05:00 Thiago Macieira <thiago@macieira.org>:
> On Monday 23 November 2015 20:27:37 Andrei L wrote:
> > Hello,
> >
> > I've been reading through the paper and noticed this:
> >
> > <..> An abbreviated function template is equivalent to a function
> template
> >
> > > (14.6.6) whose template-parameter-list includes one invented
> > > template-parameter for each occurrence of a placeholder in the
> > > parameter-declaration-clause, in order of appearance <..>
> >
> > Is this means that in such code:
> >
> > template <typename T>
> > concept bool R = CheckSomething<T>;
> >
> > auto foo(R a, R b) { /* ... */ }
> >
> > parameters `a' and `b' have the same type? And if so, why? What is the
> > rationale behind that?
>
> Whichever way you choose, you're going to disappoint someone.
>
> I've seen arguments for and against specifying the same type and it's easy
> to
> argue for the other side. One example for both cases:
>
> compare(InputIterator begin1, InputIterator end1, InputIterator
> begin2)
>
> Here, begin2 does not need to have the same type as begin1 and end1. In
> fact,
> one could argue that even begin1 and end1 need not be the same type, so
> long
> as they're comparable to one another. But the most common case is that
> begin1
> and end1 have the same type.
>
> In fact, the requirement that begin1 and end1 be comparable should be part
> of
> the concept signature, which means a function that would accept two
> different
> iterator types would need to be:
>
> compare(InputIterator begin1,
> InputIteratorComparableTo<decltype(begin1)> end1,
> InputIterator begin2)
>
> And since the second iterator has a different declaration from the first,
> this
> cannot be used as an argument for supporting the case where they need to be
> different.
>
> Anyway, maybe we should look into the principle of least surprise. Which
> case
> would cause most surprise if used incorrectly?
>
> a) the case where an API constrains the types more than it should
> b) the case where an API fails to constrain the types as much as it should
>
> In case a, the misuse would result in the compiler failing to compile and
> reporting the reason why the concepts failed to match. In case b, the
> compiler
> would accept the overload, proceed to instantiate the template, and
> possibly
> run into an error later where the assumption failed.
>
> Given that one of the stated goals of Concepts is to give us better error
> messages because types are checked against the concept prior to the
> overload
> selection, I'd say that the biggest surprise is case b.
>
> That would support the solution as it is today: the same concept name used
> more than once means the same type.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
> PGP/GPG: 0x6EF45358; fingerprint:
> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
>
> --
>
> ---
> 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-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e01177a4dc1d85a0525517fea
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">One exam=
ple for both cases:</blockquote><blockquote style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_=
quote"><div>=C2=A0</div></blockquote><blockquote style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"g=
mail_quote">compare(InputIterator begin1, InputIterator end1, InputIterator=
begin2)<br></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">=
<div>=C2=A0</div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote"><div>Here, begin2 does not need to have the same type as begin1 and en=
d1. In fact,<br>
one could argue that even begin1 and end1 need not be the same type, so lon=
g<br>
as they're comparable to one another. But the most common case is that =
begin1<br>
and end1 have the same type. <br></div></blockquote><br><div><span style=3D=
"font-family:monospace,monospace"></span><div style=3D"margin-left:40px"><s=
pan style=3D"font-family:monospace,monospace">template <typename T></=
span><br><span style=3D"font-family:monospace,monospace">concept bool Input=
Iterator =3D Iterator<I> && requires (I i) { /* ... */ };</sp=
an><br><span style=3D"font-family:monospace,monospace"></span><br><span sty=
le=3D"font-family:monospace,monospace">InputIterator {I} bool compare(I beg=
in1, I end1, InputIterator begin2)</span><br></div><span style=3D"font-fami=
ly:monospace,monospace"></span><br></div><div>How about that one? Both are =
Iterators, both are comparable. begin2 not required to be the same.<br><div=
><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex" class=3D"gmail_quote">In fact, the require=
ment that begin1 and end1 be comparable should be part of<br>
the concept signature, which means a function that would accept two differe=
nt<br>
iterator types would need to be:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 compare(InputIterator begin1,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 InputIteratorCompar=
ableTo<decltype(begin1)> end1,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 InputIterator begin=
2)<br>
<br>
And since the second iterator has a different declaration from the first, t=
his<br>
cannot be used as an argument for supporting the case where they need to be=
<br>
different. <br></blockquote></div></div><div><br></div><div><div style=3D"m=
argin-left:40px"><span style=3D"font-family:monospace,monospace">template &=
lt;typename I, typename S></span><br><span style=3D"font-family:monospac=
e,monospace">concept bool InputIterator_Sentinel =3D InputIterator<I>=
&& Iterator_Sentinel<I, S></span><br><span style=3D"font-fam=
ily:monospace,monospace"></span><br><span style=3D"font-family:monospace,mo=
nospace">InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, Input=
Iterator begin2)<br></span></div><br></div><div>Comparable, and not require=
d to be the same.<br></div><div><br></div><div>Easy enough, i think.<br></d=
iv><div><span style=3D"font-family:monospace,monospace"></span></div></div>=
<div class=3D"gmail_extra"><br><div class=3D"gmail_quote">2015-11-25 3:32 G=
MT+05:00 Thiago Macieira <span dir=3D"ltr"><<a href=3D"mailto:thiago@mac=
ieira.org" target=3D"_blank">thiago@macieira.org</a>></span>:<br><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><span class=3D"">On Monday 23 November 2015 20:27:3=
7 Andrei L wrote:<br>
> Hello,<br>
><br>
> I've been reading through the paper and noticed this:<br>
><br>
> <..> An abbreviated function template is equivalent to a functio=
n template<br>
><br>
> > (14.6.6) whose template-parameter-list includes one invented<br>
> > template-parameter for each occurrence of a placeholder in the<br=
>
> > parameter-declaration-clause, in order of appearance <..><b=
r>
><br>
> Is this means that in such code:<br>
><br>
> template <typename T><br>
> concept bool R =3D CheckSomething<T>;<br>
><br>
> auto foo(R a, R b) { /* ... */ }<br>
><br>
> parameters `a' and `b' have the same type? And if so, why? Wha=
t is the<br>
> rationale behind that?<br>
<br>
</span>Whichever way you choose, you're going to disappoint someone.<br=
>
<br>
I've seen arguments for and against specifying the same type and it'=
;s easy to<br>
argue for the other side. One example for both cases:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 compare(InputIterator begin1, InputIterator end=
1, InputIterator begin2)<br>
<br>
Here, begin2 does not need to have the same type as begin1 and end1. In fac=
t,<br>
one could argue that even begin1 and end1 need not be the same type, so lon=
g<br>
as they're comparable to one another. But the most common case is that =
begin1<br>
and end1 have the same type.<br>
<br>
In fact, the requirement that begin1 and end1 be comparable should be part =
of<br>
the concept signature, which means a function that would accept two differe=
nt<br>
iterator types would need to be:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 compare(InputIterator begin1,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 InputIteratorCompar=
ableTo<decltype(begin1)> end1,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 InputIterator begin=
2)<br>
<br>
And since the second iterator has a different declaration from the first, t=
his<br>
cannot be used as an argument for supporting the case where they need to be=
<br>
different.<br>
<br>
Anyway, maybe we should look into the principle of least surprise. Which ca=
se<br>
would cause most surprise if used incorrectly?<br>
<br>
=C2=A0a) the case where an API constrains the types more than it should<br>
=C2=A0b) the case where an API fails to constrain the types as much as it s=
hould<br>
<br>
In case a, the misuse would result in the compiler failing to compile and<b=
r>
reporting the reason why the concepts failed to match. In case b, the compi=
ler<br>
would accept the overload, proceed to instantiate the template, and possibl=
y<br>
run into an error later where the assumption failed.<br>
<br>
Given that one of the stated goals of Concepts is to give us better error<b=
r>
messages because types are checked against the concept prior to the overloa=
d<br>
selection, I'd say that the biggest surprise is case b.<br>
<br>
That would support the solution as it is today: the same concept name used<=
br>
more than once means the same type.<br>
<br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" target=3D"_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:<br>
=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C=C2=A0 966C 33F5 F005 6EF4 535=
8<br>
<br>
--<br>
<br>
---<br>
<span class=3D"">You received this message because you are subscribed to th=
e Google Groups "ISO C++ Standard - Future Proposals" group.<br>
</span>To unsubscribe from this group and stop receiving emails from it, se=
nd an email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">st=
d-proposals+unsubscribe@isocpp.org</a>.<br>
<div class=3D"HOEnZb"><div class=3D"h5">To post to this group, send email t=
o <a href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.=
<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" rel=3D"noreferrer" target=3D"_blank">http://groups.google.c=
om/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e01177a4dc1d85a0525517fea--
.
Author: "T. C." <rs2740@gmail.com>
Date: Tue, 24 Nov 2015 15:31:10 -0800 (PST)
Raw View
------=_Part_5771_954353913.1448407870086
Content-Type: multipart/alternative;
boundary="----=_Part_5772_624632394.1448407870086"
------=_Part_5772_624632394.1448407870086
Content-Type: text/plain; charset=UTF-8
On Tuesday, November 24, 2015 at 6:01:52 PM UTC-5, Bengt Gustafsson wrote:
>
>
> If each occurance of the InputIterator concept is separate we can still
> write:
>
> bool compare(InputIterator begin1, decltype(begin1) end1, InputIterator
> begin2);
>
>
This is not equivalent to
template<InputIterator I1, InputIterator I2> bool compare(I1 begin1, I1
end1, I2 begin2);
decltype() is a non-deduced context, meaning that the first version accepts
all end1's that can be converted to begin1's type. The second one deduces
I1 independently from both arguments and requires that they match.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5772_624632394.1448407870086
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, November 24, 2015 at 6:01:52 PM UTC-5,=
Bengt Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div><br></div><div>If each occurance of the InputIterator conce=
pt is separate we can still write:</div><div><br></div><div>bool compare(In=
putIterator begin1, decltype(begin1) end1, InputIterator begin2);<br></div>=
<div><br></div></div></blockquote><div>=C2=A0</div><div>This is not equival=
ent to</div><div><br></div><div>template<InputIterator I1, InputIterator=
I2> bool compare(I1 begin1, I1 end1, I2 begin2);</div><div><br></div><d=
iv>decltype() is a non-deduced context, meaning that the first version acce=
pts all end1's that can be converted to begin1's type. The second o=
ne deduces I1 independently from both arguments and requires that they matc=
h.</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5772_624632394.1448407870086--
------=_Part_5771_954353913.1448407870086--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 24 Nov 2015 15:49:44 -0800
Raw View
On Wednesday 25 November 2015 04:14:09 Andrei L wrote:
> > And since the second iterator has a different declaration from the first,
> > this
> > cannot be used as an argument for supporting the case where they need to
> > be
> > different.
>
> template <typename I, typename S>
> concept bool InputIterator_Sentinel = InputIterator<I> &&
> Iterator_Sentinel<I, S>
>
> InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIterator
> begin2)
>
> Comparable, and not required to be the same.
>
> Easy enough, i think.
Indeed.
But what I said above still applies: since you used a different declaration,
it does not support the argument that two InputIterator uses in the same
declaration should be different.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Andrei L <aendaerel@gmail.com>
Date: Wed, 25 Nov 2015 07:53:57 +0500
Raw View
--001a113b1a48d262df05255491e1
Content-Type: text/plain; charset=UTF-8
>
> But what I said above still applies: since you used a different
> declaration,
> it does not support the argument that two InputIterator uses in the same
> declaration should be different.
I'm not making an argument that two iterators should be different. Also, i
am not talking about STL's "common case" which is not common, but the only
possible. And let's not forget about RangesTS, and STL2, where that "common
case" is not so common.
I'm saying that type checking has nothing to do with defining parameters of
a function. It's just none of its business. User defines parameters. User
defines their types. User decides, if they are of the same type or not.
merge(Container src_a, Container src_b, Container output)
Do i want `src_a', `src_b' and `output' be of the same type? No. - But,
because `Container' placed where types are placed, someone might think that
it's a type. That is confusing for that someone, lets make types the same.
- Okay, but what is about ones who is not confused, who actually learned
the language? Why make them pay and suffer? Is ones who don't learned
prioritized over ones who learned?
And how is that even possible that someone will try to use a function like
above, without actually knowing what is a `Container'? If you have a docs,
you'll read that `merge' is a template function that accepts three objects,
types of which meet a requirements of the `Container' concept. And if you
doesn't have a docs you will go to source code and see for yourself that
`Container' is not a type.
I say, there is no source of confusion. Right now, confusion is not in the
heads of a users.
Oh, and that terse syntax hides that it's a template function. - But that
is not a problem. It is purpose of that syntax, to get rid of template
boilerplate, no? And if that is a problem, why introduce it in the first
place? Why ever introduce new, actually simplified syntax? What for? We can
use current.
Which case would cause most surprise if used incorrectly?
>
>
a) the case where an API constrains the types more than it should
> b) the case where an API fails to constrain the types as much as it should
Who writes an API? A human. It so happens that people make mistakes. So the
second case is not surprising at all.
On the other hand, if i read a sentence and i see what is happening here,
what words are used, and what they mean (what they actually mean and not
some meaning invented from nothing), and then someone says that completely
different things happening, that is where confusion will rise.
you used a different declaration
>
I used different declaration to show that i don't need InputIterator to
force same type for begin and end, if i need same types i define them to be
the same. Just like i do right now, by the way, by writing
template <typename I, typename O>
O copy(I begin, I end, O out)
I don't need obscure rules to define begin and end to be of the same type.
I can use template-introduction for that, which is perfectly suitable. And
by allowing constrained parameters with same constraints be of different
types, it's will be also easier to write functions where you just doesn't
care about actual types. And if it's not enough, you always have usual
template syntax, for both cases. Cake for you, and cake for you. Everyone
is happy.
2015-11-25 4:49 GMT+05:00 Thiago Macieira <thiago@macieira.org>:
> On Wednesday 25 November 2015 04:14:09 Andrei L wrote:
> > > And since the second iterator has a different declaration from the
> first,
> > > this
> > > cannot be used as an argument for supporting the case where they need
> to
> > > be
> > > different.
> >
> > template <typename I, typename S>
> > concept bool InputIterator_Sentinel = InputIterator<I> &&
> > Iterator_Sentinel<I, S>
> >
> > InputIterator_Sentinel {I, S} bool compare(I begin1, S end1,
> InputIterator
> > begin2)
> >
> > Comparable, and not required to be the same.
> >
> > Easy enough, i think.
>
> Indeed.
>
> But what I said above still applies: since you used a different
> declaration,
> it does not support the argument that two InputIterator uses in the same
> declaration should be different.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
> PGP/GPG: 0x6EF45358; fingerprint:
> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
>
> --
>
> ---
> 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-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a113b1a48d262df05255491e1
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">But=
what I said above still applies: since you used a different declaration,<b=
r>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, bu=
t the only possible. And let's not forget about RangesTS, and STL2, whe=
re that "common case" is not so common.<br><br>I'm saying tha=
t type checking has nothing to do with defining parameters
of a function. It's just none of its business. User defines parameters=
.. User defines their types. User decides, if they are of the same type or n=
ot.<br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace">merge(</span><span style=3D"font-family:monospace,mon=
ospace">Container src_a, </span><span style=3D"font-family:monospace,monosp=
ace">Container src_b, Container output)</span></div><div><br></div><div>Do =
i want `src_a', `src_b' and `output' be of the same type? No. -=
But, because `Container' placed where types are placed, someone might =
think that it's a type. That is confusing for that someone, lets make t=
ypes the same. - Okay, but what is about ones who is not confused, who actu=
ally learned the language? Why make them pay and suffer? Is ones who don=
9;t learned prioritized over ones who learned?<br><br>And how is that even =
possible that someone will try to use a function like above, without actual=
ly knowing what is a `Container'? If you have a docs, you'll read t=
hat `merge' is a template function that accepts three objects, types of=
which meet a requirements of the `Container' concept. And if you doesn=
't have a docs you will go to source code and see for yourself that `Co=
ntainer' is not a type.<br><br>I say, there is no source of confusion. =
Right now, confusion is not in the heads of a users.<br></div><div><br>Oh, =
and that terse syntax hides that it's a template function. - But that i=
s not a problem. It is purpose of that syntax, to get rid of template boile=
rplate, no? And if that is a problem, why introduce it in the first place? =
Why ever introduce new, actually simplified syntax? What for? We can use cu=
rrent.<br></div><div><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">=
Which case would cause most surprise if used incorrectly?<br></blockquote><=
blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,=
204,204);padding-left:1ex" class=3D"gmail_quote"><div>=C2=A0</div></blockqu=
ote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb=
(204,204,204);padding-left:1ex" class=3D"gmail_quote">a) the case where an =
API constrains the types more than it should<br>b) the case where an API fa=
ils to constrain the types as much as it should</blockquote><div><br></div>=
<div>Who writes an API? A human. It so happens that people make mistakes. S=
o the second case is not surprising at all.<br><br></div><div>On the other =
hand, if i read a sentence and i see what is happening here, what words are=
used, and what they mean (what they actually mean and not some meaning inv=
ented from nothing), and then someone says that completely different things=
happening, that is where confusion will rise.<br><br><blockquote style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex" class=3D"gmail_quote">you used a different declaration<br></blockquo=
te><div><br></div><div>I used different declaration to show that i don'=
t need InputIterator to force same type for begin and end, if i need same t=
ypes i define them to be the same. Just like i do right now, by the way, by=
writing<br><div style=3D"margin-left:40px"><br></div><div style=3D"margin-=
left:40px"><font face=3D"monospace,monospace">template <typename I, type=
name O><br></font></div><div style=3D"margin-left:40px"><font face=3D"mo=
nospace,monospace">O copy(I begin, I end, O out)<br><br></font></div>I don&=
#39;t need obscure rules to define begin and end to be of the same type. I =
can use template-introduction for that, which is perfectly suitable. And by=
allowing constrained parameters with same constraints be of different type=
s, it's will be also easier to write functions where you just doesn'=
;t care about actual types. And if it's not enough, you always have usu=
al template syntax, for both cases. Cake for you, and cake for you. Everyon=
e is happy.<br></div></div></div></div><div class=3D"gmail_extra"><br><div =
class=3D"gmail_quote">2015-11-25 4:49 GMT+05:00 Thiago Macieira <span dir=
=3D"ltr"><<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiag=
o@macieira.org</a>></span>:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span cl=
ass=3D"">On Wednesday 25 November 2015 04:14:09 Andrei L wrote:<br>
> > And since the second iterator has a different declaration from th=
e first,<br>
> > this<br>
> > cannot be used as an argument for supporting the case where they =
need to<br>
> > be<br>
> > different.<br>
><br>
> template <typename I, typename S><br>
> concept bool InputIterator_Sentinel =3D InputIterator<I> &&a=
mp;<br>
> Iterator_Sentinel<I, S><br>
><br>
> InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIter=
ator<br>
> begin2)<br>
><br>
> Comparable, and not required to be the same.<br>
><br>
> Easy enough, i think.<br>
<br>
</span>Indeed.<br>
<br>
But what I said above still applies: since you used a different declaration=
,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" target=3D"_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:<br>
=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C=C2=A0 966C 33F5 F005 6EF4 535=
8<br>
<br>
--<br>
<br>
---<br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" rel=3D"noreferrer" target=3D"_blank">http://groups.google.c=
om/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a113b1a48d262df05255491e1--
.
Author: Andrei L <aendaerel@gmail.com>
Date: Wed, 25 Nov 2015 07:56:11 +0500
Raw View
--001a1136b0bad5312f052554999a
Content-Type: text/plain; charset=UTF-8
>
> Given that one of the stated goals of Concepts is to give us better error
> messages because types are checked against the concept prior to the
> overload
> selection
>
Error messages.. I've seen some beginners asking programming questions, and
you know what? Some of them can't even understand what compiler says about
that missed semicolon at the end of line. That's where great confusion
happens.
2015-11-25 3:32 GMT+05:00 Thiago Macieira <thiago@macieira.org>:
> On Monday 23 November 2015 20:27:37 Andrei L wrote:
> > Hello,
> >
> > I've been reading through the paper and noticed this:
> >
> > <..> An abbreviated function template is equivalent to a function
> template
> >
> > > (14.6.6) whose template-parameter-list includes one invented
> > > template-parameter for each occurrence of a placeholder in the
> > > parameter-declaration-clause, in order of appearance <..>
> >
> > Is this means that in such code:
> >
> > template <typename T>
> > concept bool R = CheckSomething<T>;
> >
> > auto foo(R a, R b) { /* ... */ }
> >
> > parameters `a' and `b' have the same type? And if so, why? What is the
> > rationale behind that?
>
> Whichever way you choose, you're going to disappoint someone.
>
> I've seen arguments for and against specifying the same type and it's easy
> to
> argue for the other side. One example for both cases:
>
> compare(InputIterator begin1, InputIterator end1, InputIterator
> begin2)
>
> Here, begin2 does not need to have the same type as begin1 and end1. In
> fact,
> one could argue that even begin1 and end1 need not be the same type, so
> long
> as they're comparable to one another. But the most common case is that
> begin1
> and end1 have the same type.
>
> In fact, the requirement that begin1 and end1 be comparable should be part
> of
> the concept signature, which means a function that would accept two
> different
> iterator types would need to be:
>
> compare(InputIterator begin1,
> InputIteratorComparableTo<decltype(begin1)> end1,
> InputIterator begin2)
>
> And since the second iterator has a different declaration from the first,
> this
> cannot be used as an argument for supporting the case where they need to be
> different.
>
> Anyway, maybe we should look into the principle of least surprise. Which
> case
> would cause most surprise if used incorrectly?
>
> a) the case where an API constrains the types more than it should
> b) the case where an API fails to constrain the types as much as it should
>
> In case a, the misuse would result in the compiler failing to compile and
> reporting the reason why the concepts failed to match. In case b, the
> compiler
> would accept the overload, proceed to instantiate the template, and
> possibly
> run into an error later where the assumption failed.
>
> Given that one of the stated goals of Concepts is to give us better error
> messages because types are checked against the concept prior to the
> overload
> selection, I'd say that the biggest surprise is case b.
>
> That would support the solution as it is today: the same concept name used
> more than once means the same type.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
> PGP/GPG: 0x6EF45358; fingerprint:
> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
>
> --
>
> ---
> 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-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a1136b0bad5312f052554999a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">Given th=
at one of the stated goals of Concepts is to give us better error<br>
messages because types are checked against the concept prior to the overloa=
d<br>
selection<br></blockquote><div><br></div>Error messages.. I've seen som=
e beginners asking programming questions,
and you know what? Some of them can't even understand what compiler=20
says about that missed semicolon at the end of line. That's where great=
=20
confusion happens.</div><div class=3D"gmail_extra"><br><div class=3D"gmail_=
quote">2015-11-25 3:32 GMT+05:00 Thiago Macieira <span dir=3D"ltr"><<a h=
ref=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a=
>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">On Monday =
23 November 2015 20:27:37 Andrei L wrote:<br>
> Hello,<br>
><br>
> I've been reading through the paper and noticed this:<br>
><br>
> <..> An abbreviated function template is equivalent to a functio=
n template<br>
><br>
> > (14.6.6) whose template-parameter-list includes one invented<br>
> > template-parameter for each occurrence of a placeholder in the<br=
>
> > parameter-declaration-clause, in order of appearance <..><b=
r>
><br>
> Is this means that in such code:<br>
><br>
> template <typename T><br>
> concept bool R =3D CheckSomething<T>;<br>
><br>
> auto foo(R a, R b) { /* ... */ }<br>
><br>
> parameters `a' and `b' have the same type? And if so, why? Wha=
t is the<br>
> rationale behind that?<br>
<br>
</span>Whichever way you choose, you're going to disappoint someone.<br=
>
<br>
I've seen arguments for and against specifying the same type and it'=
;s easy to<br>
argue for the other side. One example for both cases:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 compare(InputIterator begin1, InputIterator end=
1, InputIterator begin2)<br>
<br>
Here, begin2 does not need to have the same type as begin1 and end1. In fac=
t,<br>
one could argue that even begin1 and end1 need not be the same type, so lon=
g<br>
as they're comparable to one another. But the most common case is that =
begin1<br>
and end1 have the same type.<br>
<br>
In fact, the requirement that begin1 and end1 be comparable should be part =
of<br>
the concept signature, which means a function that would accept two differe=
nt<br>
iterator types would need to be:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 compare(InputIterator begin1,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 InputIteratorCompar=
ableTo<decltype(begin1)> end1,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 InputIterator begin=
2)<br>
<br>
And since the second iterator has a different declaration from the first, t=
his<br>
cannot be used as an argument for supporting the case where they need to be=
<br>
different.<br>
<br>
Anyway, maybe we should look into the principle of least surprise. Which ca=
se<br>
would cause most surprise if used incorrectly?<br>
<br>
=C2=A0a) the case where an API constrains the types more than it should<br>
=C2=A0b) the case where an API fails to constrain the types as much as it s=
hould<br>
<br>
In case a, the misuse would result in the compiler failing to compile and<b=
r>
reporting the reason why the concepts failed to match. In case b, the compi=
ler<br>
would accept the overload, proceed to instantiate the template, and possibl=
y<br>
run into an error later where the assumption failed.<br>
<br>
Given that one of the stated goals of Concepts is to give us better error<b=
r>
messages because types are checked against the concept prior to the overloa=
d<br>
selection, I'd say that the biggest surprise is case b.<br>
<br>
That would support the solution as it is today: the same concept name used<=
br>
more than once means the same type.<br>
<br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" target=3D"_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:<br>
=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C=C2=A0 966C 33F5 F005 6EF4 535=
8<br>
<br>
--<br>
<br>
---<br>
<span class=3D"">You received this message because you are subscribed to th=
e Google Groups "ISO C++ Standard - Future Proposals" group.<br>
</span>To unsubscribe from this group and stop receiving emails from it, se=
nd an email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">st=
d-proposals+unsubscribe@isocpp.org</a>.<br>
<div class=3D"HOEnZb"><div class=3D"h5">To post to this group, send email t=
o <a href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.=
<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" rel=3D"noreferrer" target=3D"_blank">http://groups.google.c=
om/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a1136b0bad5312f052554999a--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 24 Nov 2015 23:07:13 -0800 (PST)
Raw View
------=_Part_6364_1251366605.1448435233252
Content-Type: multipart/alternative;
boundary="----=_Part_6365_1197490493.1448435233253"
------=_Part_6365_1197490493.1448435233253
Content-Type: text/plain; charset=UTF-8
On Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:
>
> But what I said above still applies: since you used a different
>> declaration,
>> it does not support the argument that two InputIterator uses in the same
>> declaration should be different.
>
>
> I'm not making an argument that two iterators should be different. Also, i
> am not talking about STL's "common case" which is not common, but the only
> possible. And let's not forget about RangesTS, and STL2, where that "common
> case" is not so common.
>
> I'm saying that type checking has nothing to do with defining parameters
> of a function. It's just none of its business. User defines parameters.
> User defines their types. User decides, if they are of the same type or not.
>
> merge(Container src_a, Container src_b, Container output)
>
> Do i want `src_a', `src_b' and `output' be of the same type? No.
>
I would say that your `merge` function here is underconstrained. Why?
Because even if those different `Container` instances could deduce
different types, those three different types need to have something in
common. Namely, that the value type from `src_a` and `src_b` are
convertible to the value type for `output`.
So if you actually applied all of the constraints that your function needs,
you *couldn't* use terse syntax. So this is not an example of the problem.
And I think that leads to an interesting question. How often do you have a
function which:
1) Takes two arguments that can be of different types.
2) Those two arguments are constrained by the same concept.
3) There are no additional constraints on those types that would prevent
you from using terse syntax.
Take your suggestion for `compare`. The first range and second range need
not be the same types. *But*, they do need to have comparable value types.
And a properly constrained template function will apply that constraint, so
that users who pass the wrong things will get reasonable errors. And you
can't apply such a constraint with terse syntax.
I'd bet that 90% of the time that #1 and #2 are true, there's probably some
additional constraint that your function requires of those two types.
- But, because `Container' placed where types are placed, someone might
> think that it's a type. That is confusing for that someone, lets make types
> the same. - Okay, but what is about ones who is not confused, who actually
> learned the language? Why make them pay and suffer? Is ones who don't
> learned prioritized over ones who learned?
>
Why make the language more confusing to users? Why make people *have* to
learn esoteric rules?
*Somebody* will be inconvenienced no matter what you do. Why is your side
the one that deserves to have the special syntax? Indeed, you seem to argue
exactly why they shouldn't: because they're the ones who are willing to
learn and use arcane rules. And therefore, they will be less inconvenienced
by such arcane rules than if you do it the other way around.
And how is that even possible that someone will try to use a function like
> above, without actually knowing what is a `Container'?
>
The same way that people use std::vector without knowing that the type it
takes actually has minimum requirements.
> If you have a docs, you'll read that `merge' is a template function that
> accepts three objects, types of which meet a requirements of the
> `Container' concept. And if you doesn't have a docs you will go to source
> code and see for yourself that `Container' is not a type.
>
> I say, there is no source of confusion. Right now, confusion is not in the
> heads of a users.
>
> Oh, and that terse syntax hides that it's a template function. - But that
> is not a problem. It is purpose of that syntax, to get rid of template
> boilerplate, no?
>
The purpose of terse syntax is to minimize template boilerplate in the most
common and useful of cases. It is not intended to be a full-fledged
*replacement* for declaring template functions. There will always be cases
where you need to use full template syntax.
The question is why should your case be the one that gets favoritism?
> I used different declaration to show that i don't need InputIterator to
> force same type for begin and end, if i need same types i define them to be
> the same. Just like i do right now, by the way, by writing
>
> template <typename I, typename O>
> O copy(I begin, I end, O out)
>
> I don't need obscure rules to define begin and end to be of the same type.
> I can use template-introduction for that, which is perfectly suitable. And
> by allowing constrained parameters with same constraints be of different
> types, it's will be also easier to write functions where you just doesn't
> care about actual types. And if it's not enough, you always have usual
> template syntax, for both cases. Cake for you, and cake for you. Everyone
> is happy.
>
Nobody has contested that full template syntax can do either one. Nobody
has suggested that having terse syntax use one way means that the other way
becomes impossible.
The question is who gets to use the simple syntax. Simply declaring that
the other side can still use full template syntax is basically saying, "why
don't you just let us win? After all, if you do, you lose."
Do a lot of people find this kind of argument convincing?
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_6365_1197490493.1448435233253
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><blockquote style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex" class=3D"gmail_quote">But what I said above still applies: since=
you used a different declaration,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, bu=
t the only possible. And let's not forget about RangesTS, and STL2, whe=
re that "common case" is not so common.<br><br>I'm saying tha=
t type checking has nothing to do with defining parameters
of a function. It's just none of its business. User defines parameters=
.. User defines their types. User decides, if they are of the same type or n=
ot.<br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace">merge(</span><span style=3D"font-family:monospace,mon=
ospace">Container src_a, </span><span style=3D"font-family:monospace,monosp=
ace">Container src_b, Container output)</span></div><div><br></div><div>Do =
i want `src_a', `src_b' and `output' be of the same type? No.</=
div></div></blockquote><div><br>I would say that your `merge` function here=
is underconstrained. Why? Because even if those different `Container` inst=
ances could deduce different types, those three different types need to hav=
e something in common. Namely, that the value type from `src_a` and `src_b`=
are convertible to the value type for `output`.<br><br>So if you actually =
applied all of the constraints that your function needs, you <i>couldn'=
t</i> use terse syntax. So this is not an example of the problem.<br><br>An=
d I think that leads to an interesting question. How often do you have a fu=
nction which:<br><br>1) Takes two arguments that can be of different types.=
<br><br>2) Those two arguments are constrained by the same concept.<br><br>=
3) There are no additional constraints on those types that would prevent yo=
u from using terse syntax.<br><br>Take your suggestion for `compare`. The f=
irst range and second range need not be the same types. <i>But</i>, they do=
need to have comparable value types. And a properly constrained template f=
unction will apply that constraint, so that users who pass the wrong things=
will get reasonable errors. And you can't apply such a constraint with=
terse syntax.<br><br>I'd bet that 90% of the time that #1 and #2 are t=
rue, there's probably some additional constraint that your function req=
uires of those two types.<br><br><i></i></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div>- But, because `Container' placed=
where types are placed, someone might think that it's a type. That is =
confusing for that someone, lets make types the same. - Okay, but what is a=
bout ones who is not confused, who actually learned the language? Why make =
them pay and suffer? Is ones who don't learned prioritized over ones wh=
o learned?<br></div></div></blockquote><div><br>Why make the language more =
confusing to users? Why make people <i>have</i> to learn esoteric rules?<br=
><br><i>Somebody</i> will be inconvenienced no matter what you do. Why is y=
our side the one that deserves to have the special syntax? Indeed, you seem=
to argue exactly why they shouldn't: because they're the ones who =
are willing to learn and use arcane rules. And therefore, they will be less=
inconvenienced by such arcane rules than if you do it the other way around=
..<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div>And how is that even possible that someone will try to use a functio=
n like above, without actually knowing what is a `Container'?</div></di=
v></blockquote><div><br>The same way that people use std::vector without kn=
owing that the type it takes actually has minimum requirements.<br>=C2=A0</=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>If y=
ou have a docs, you'll read that `merge' is a template function tha=
t accepts three objects, types of which meet a requirements of the `Contain=
er' concept. And if you doesn't have a docs you will go to source c=
ode and see for yourself that `Container' is not a type.<br><br>I say, =
there is no source of confusion. Right now, confusion is not in the heads o=
f a users.<br></div><div><br>Oh, and that terse syntax hides that it's =
a template function. - But that is not a problem. It is purpose of that syn=
tax, to get rid of template boilerplate, no?</div></div></blockquote><div><=
br>The purpose of terse syntax is to minimize template boilerplate in the m=
ost common and useful of cases. It is not intended to be a full-fledged <i>=
replacement</i> for declaring template functions. There will always be case=
s where you need to use full template syntax.<br><br>The question is why sh=
ould your case be the one that gets favoritism?<br>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div><div></div><div=
>I used different declaration to show that i don't need InputIterator t=
o force same type for begin and end, if i need same types i define them to =
be the same. Just like i do right now, by the way, by writing<br><div style=
=3D"margin-left:40px"><br></div><div style=3D"margin-left:40px"><font face=
=3D"monospace,monospace">template <typename I, typename O><br></font>=
</div><div style=3D"margin-left:40px"><font face=3D"monospace,monospace">O =
copy(I begin, I end, O out)<br><br></font></div>I don't need obscure ru=
les to define begin and end to be of the same type. I can use template-intr=
oduction for that, which is perfectly suitable. And by allowing constrained=
parameters with same constraints be of different types, it's will be a=
lso easier to write functions where you just doesn't care about actual =
types. And if it's not enough, you always have usual template syntax, f=
or both cases. Cake for you, and cake for you. Everyone is happy.<br></div>=
</div></div></div></blockquote><div><br>Nobody has contested that full temp=
late syntax can do either one. Nobody has suggested that having terse synta=
x use one way means that the other way becomes impossible.<br><br>The quest=
ion is who gets to use the simple syntax. Simply declaring that the other s=
ide can still use full template syntax is basically saying, "why don&#=
39;t you just let us win? After all, if you do, you lose."</div><br>Do=
a lot of people find this kind of argument convincing?<br>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6365_1197490493.1448435233253--
------=_Part_6364_1251366605.1448435233252--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Wed, 25 Nov 2015 19:47:33 +0100
Raw View
--089e013d0f802708cd052561e427
Content-Type: text/plain; charset=UTF-8
On Tue, Nov 24, 2015 at 11:40 PM, Thiago Macieira <thiago@macieira.org>
wrote:
> On Tuesday 24 November 2015 21:54:57 Andrew Tomazos wrote:
> > On Tue, Nov 24, 2015 at 6:10 PM, Nicol Bolas <jmckesson@gmail.com>
> wrote:
> > > In my mind, the point of terse template function syntax is that the
> user
> > > *doesn't care* if it's a type constraint or not. That you could take
> > > `auto foo(T t1, T t2)` and turn it into `auto foo(C t1, C t2)` (where C
> > > is a concept that matches T), and the only visible difference (besides
> > > which types are allowed) is that you can't get a function pointer to
> it.
> > > As far as the user is concerned, it works just like `int` or
> `vector<T>`.
> > > It looks like a typename and it behaves like a typename.
> >
> > If we think of a concept as a compile-time interface (where a pure
> virtual
> > class is a run-time interface), then we would expect:
> >
> > class Animal { ... };
> > class Dog : Animal { ... };
> > class Cat : Animal { ... };
> >
> > void f(const Animal& a, const Animal& b);
> >
> > Dog dog;
> > Cat cat;
> >
> > f(dog, cat);
> >
> > This argues for allowing different types.
>
> That's an example of polymorphism but it's showing the same type: Animal.
> So I
> don't agree with you that it argues for allowing different types.
>
It's kind of subjective I guess. The types of the arguments to the
function call expression are Dog and Cat. Likewise in the following:
concept Animal ...;
class Dog { ... };
static_assert(Dog conforms to Animal);
class Cat { ... };
static_assert(Cat conforms to Animal);
void f(Animal a, Animal b);
Dog dog;
Cat cat;
f(dog, cat);
I argue that both this example and the previous are similar in important
ways.
The mechanics of derived-to-base conversions, base class subobjects,
reference binding, etc, etc - are secondary to how the language should work
at a conceptual level. They are just a means to an end.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e013d0f802708cd052561e427
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Tue, Nov 24, 2015 at 11:40 PM, Thiago Macieira <span dir=3D"ltr"><=
;<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.o=
rg</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D""=
>On Tuesday 24 November 2015 21:54:57 Andrew Tomazos wrote:<br>
> On Tue, Nov 24, 2015 at 6:10 PM, Nicol Bolas <<a href=3D"mailto:jmc=
kesson@gmail.com">jmckesson@gmail.com</a>> wrote:<br>
> > In my mind, the point of terse template function syntax is that t=
he user<br>
</span>> > *doesn't care* if it's a type constraint or not. T=
hat you could take<br>
<span class=3D"">> > `auto foo(T t1, T t2)` and turn it into `auto fo=
o(C t1, C t2)` (where C<br>
> > is a concept that matches T), and the only visible difference (be=
sides<br>
> > which types are allowed) is that you can't get a function poi=
nter to it.<br>
> > As far as the user is concerned, it works just like `int` or `vec=
tor<T>`.<br>
> > It looks like a typename and it behaves like a typename.<br>
><br>
> If we think of a concept as a compile-time interface (where a pure vir=
tual<br>
> class is a run-time interface), then we would expect:<br>
><br>
>=C2=A0 =C2=A0 class Animal { ... };<br>
>=C2=A0 =C2=A0 class Dog : Animal { ... };<br>
>=C2=A0 =C2=A0 class Cat : Animal { ... };<br>
><br>
>=C2=A0 =C2=A0 void f(const Animal& a, const Animal& b);<br>
><br>
>=C2=A0 =C2=A0 Dog dog;<br>
>=C2=A0 =C2=A0 Cat cat;<br>
><br>
>=C2=A0 =C2=A0 f(dog, cat);<br>
><br>
> This argues for allowing different types.<br>
<br>
</span>That's an example of polymorphism but it's showing the same =
type: Animal. So I<br>
don't agree with you that it argues for allowing different types.<br></=
blockquote><div><br></div><div>It's kind of subjective I guess.=C2=A0 T=
he types of the arguments to the function call expression are Dog and Cat.=
=C2=A0 Likewise in the following:</div><div><br></div><div>concept Animal .=
...;</div><div>class Dog { ... };</div><div>static_assert(Dog conforms to An=
imal);</div><div>class Cat { ... };</div><div>static_assert(Cat conforms to=
Animal);</div><div><br></div><div>void f(Animal a, Animal b);</div><div><b=
r></div><div>Dog dog;</div><div>Cat cat;</div><div><br></div><div>f(dog, ca=
t);</div><div><br></div><div>I argue that both this example and the previou=
s are similar in important ways.</div><div><br></div><div>The mechanics of =
derived-to-base conversions, base class subobjects, reference binding, etc,=
etc - are secondary to how the language should work at a conceptual level.=
=C2=A0 They are just a means to an end.</div><div><br></div></div></div></d=
iv>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e013d0f802708cd052561e427--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 25 Nov 2015 11:50:33 -0800
Raw View
On Wednesday 25 November 2015 19:47:33 Andrew Tomazos wrote:
> concept Animal ...;
> class Dog { ... };
> static_assert(Dog conforms to Animal);
> class Cat { ... };
> static_assert(Cat conforms to Animal);
>
> void f(Animal a, Animal b);
>
> Dog dog;
> Cat cat;
>
> f(dog, cat);
>
> I argue that both this example and the previous are similar in important
> ways.
>
> The mechanics of derived-to-base conversions, base class subobjects,
> reference binding, etc, etc - are secondary to how the language should work
> at a conceptual level. They are just a means to an end.
In this case, the function f would be a template. And that's where things
become blurry, because if the arguments are templates, there's no automatic
casting to a base class.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Wed, 25 Nov 2015 21:14:26 +0100
Raw View
--001a114420aadd09d30525631aec
Content-Type: text/plain; charset=UTF-8
On Wed, Nov 25, 2015 at 8:50 PM, Thiago Macieira <thiago@macieira.org>
wrote:
> On Wednesday 25 November 2015 19:47:33 Andrew Tomazos wrote:
> > concept Animal ...;
> > class Dog { ... };
> > static_assert(Dog conforms to Animal);
> > class Cat { ... };
> > static_assert(Cat conforms to Animal);
> >
> > void f(Animal a, Animal b);
> >
> > Dog dog;
> > Cat cat;
> >
> > f(dog, cat);
> >
> > I argue that both this example and the previous are similar in important
> > ways.
> >
> > The mechanics of derived-to-base conversions, base class subobjects,
> > reference binding, etc, etc - are secondary to how the language should
> work
> > at a conceptual level. They are just a means to an end.
>
> In this case, the function f would be a template. And that's where things
> become blurry, because if the arguments are templates, there's no automatic
> casting to a base class.
Right, instead of derived-to-base conversion there is concept-conforming
type deduction. The former happens at run-time, the later happens at
compile-time. Beyond that, at a high-level, I think they are supposed to
be similar.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a114420aadd09d30525631aec
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Nov 25, 2015 at 8:50 PM, Thiago Macieira <span dir=3D"ltr"><<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
.8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">On Wedn=
esday 25 November 2015 19:47:33 Andrew Tomazos wrote:<br>
> concept Animal ...;<br>
> class Dog { ... };<br>
> static_assert(Dog conforms to Animal);<br>
> class Cat { ... };<br>
> static_assert(Cat conforms to Animal);<br>
><br>
> void f(Animal a, Animal b);<br>
><br>
> Dog dog;<br>
> Cat cat;<br>
><br>
> f(dog, cat);<br>
><br>
> I argue that both this example and the previous are similar in importa=
nt<br>
> ways.<br>
><br>
> The mechanics of derived-to-base conversions, base class subobjects,<b=
r>
> reference binding, etc, etc - are secondary to how the language should=
work<br>
> at a conceptual level.=C2=A0 They are just a means to an end.<br>
<br>
</span>In this case, the function f would be a template. And that's whe=
re things<br>
become blurry, because if the arguments are templates, there's no autom=
atic<br>
casting to a base class.</blockquote><div><br></div><div>Right, instead of =
derived-to-base conversion there is concept-conforming type deduction.=C2=
=A0 The former happens at run-time, the later happens at compile-time.=C2=
=A0 Beyond that, at a high-level, I think they are supposed to be similar.<=
/div><div><br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a114420aadd09d30525631aec--
.
Author: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Wed, 25 Nov 2015 12:44:07 -0800 (PST)
Raw View
------=_Part_986_548793745.1448484247206
Content-Type: multipart/alternative;
boundary="----=_Part_987_1106297863.1448484247206"
------=_Part_987_1106297863.1448484247206
Content-Type: text/plain; charset=UTF-8
In some languages both concept-like static polymorphism and OOP-style
dynamic polymorphism are even served by the same language feature.
On Wednesday, November 25, 2015 at 11:14:27 PM UTC+3, Andrew Tomazos wrote:
>
> On Wed, Nov 25, 2015 at 8:50 PM, Thiago Macieira <thi...@macieira.org
> <javascript:>> wrote:
>
>> On Wednesday 25 November 2015 19:47:33 Andrew Tomazos wrote:
>> > concept Animal ...;
>> > class Dog { ... };
>> > static_assert(Dog conforms to Animal);
>> > class Cat { ... };
>> > static_assert(Cat conforms to Animal);
>> >
>> > void f(Animal a, Animal b);
>> >
>> > Dog dog;
>> > Cat cat;
>> >
>> > f(dog, cat);
>> >
>> > I argue that both this example and the previous are similar in important
>> > ways.
>> >
>> > The mechanics of derived-to-base conversions, base class subobjects,
>> > reference binding, etc, etc - are secondary to how the language should
>> work
>> > at a conceptual level. They are just a means to an end.
>>
>> In this case, the function f would be a template. And that's where things
>> become blurry, because if the arguments are templates, there's no
>> automatic
>> casting to a base class.
>
>
> Right, instead of derived-to-base conversion there is concept-conforming
> type deduction. The former happens at run-time, the later happens at
> compile-time. Beyond that, at a high-level, I think they are supposed to
> be similar.
>
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_987_1106297863.1448484247206
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">In some languages both concept-like static polymorphism an=
d OOP-style dynamic polymorphism are even served by the same language featu=
re.<br><br>On Wednesday, November 25, 2015 at 11:14:27 PM UTC+3, Andrew Tom=
azos wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv><div class=3D"gmail_quote">On Wed, Nov 25, 2015 at 8:50 PM, Thiago Macie=
ira <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obf=
uscated-mailto=3D"XYUzdijdBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascri=
pt:';return true;">thi...@macieira.org</a>></span> wrote:<br><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><span>On Wednesday 25 November 2015 19:47:33 Andrew=
Tomazos wrote:<br>
> concept Animal ...;<br>
> class Dog { ... };<br>
> static_assert(Dog conforms to Animal);<br>
> class Cat { ... };<br>
> static_assert(Cat conforms to Animal);<br>
><br>
> void f(Animal a, Animal b);<br>
><br>
> Dog dog;<br>
> Cat cat;<br>
><br>
> f(dog, cat);<br>
><br>
> I argue that both this example and the previous are similar in importa=
nt<br>
> ways.<br>
><br>
> The mechanics of derived-to-base conversions, base class subobjects,<b=
r>
> reference binding, etc, etc - are secondary to how the language should=
work<br>
> at a conceptual level.=C2=A0 They are just a means to an end.<br>
<br>
</span>In this case, the function f would be a template. And that's whe=
re things<br>
become blurry, because if the arguments are templates, there's no autom=
atic<br>
casting to a base class.</blockquote><div><br></div><div>Right, instead of =
derived-to-base conversion there is concept-conforming type deduction.=C2=
=A0 The former happens at run-time, the later happens at compile-time.=C2=
=A0 Beyond that, at a high-level, I think they are supposed to be similar.<=
/div><div><br></div></div></div></div>
</blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_987_1106297863.1448484247206--
------=_Part_986_548793745.1448484247206--
.
Author: Andrei L <aendaerel@gmail.com>
Date: Thu, 26 Nov 2015 04:21:38 +0500
Raw View
--089e0117631165c9d0052565b8bc
Content-Type: text/plain; charset=UTF-8
>
> I would say that your `merge` function here is underconstrained. Why?
> Because even if those different `Container` instances could deduce
> different types, those three different types need to have something in
> common. Namely, that the value type from `src_a` and `src_b` are
> convertible to the value type for `output`.
>
But, nothing was said about what is a Container, here. Maybe it's enough.
Maybe Container, it is something that can hold some type T, which can hold
any other type. And maybe that `merge` function is not an analogue of
`merge` in STL. And of course, it's not an example of perfectly
constrained, function. One, most probably, would need to add additional
requires-clause.
So if you actually applied all of the constraints that your function needs,
> you *couldn't* use terse syntax.
>
> And I think that leads to an interesting question. How often do you have a
> function which:
>
> 1) Takes two arguments that can be of different types.
>
> 2) Those two arguments are constrained by the same concept.
>
> 3) There are no additional constraints on those types that would prevent
> you from using terse syntax.
>
> I'd bet that 90% of the time that #1 and #2 are true, there's probably
> some additional constraint that your function requires of those two types.
>
>
Take your suggestion for `compare`. The first range and second range need
> not be the same types. *But*, they do need to have comparable value
> types. And a properly constrained template function will apply that
> constraint, so that users who pass the wrong things will get reasonable
> errors. And you can't apply such a constraint with terse syntax.
>
That's why i am unhappy with current situation, i can apply additional
constraints.
InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIterator
begin2)
requires EquallyComparable<decltype(*begin1), decltype(*begin2)>
&& /* any additional constraints */
and if you need and actual type of begin2, and you don't want to use
decltype, you can use usual template syntax.
Why make the language more confusing to users? Why make people *have* to
> learn esoteric rules?
>
That is why i am here! Why? Rule that is made to make me, a user, less
confused, made me confused even before it came into effect!
> *Somebody* will be inconvenienced no matter what you do. Why is your side
> the one that deserves to have the special syntax? Indeed, you seem to argue
> exactly why they shouldn't: because they're the ones who are willing to
> learn and use arcane rules. And therefore, they will be less inconvenienced
> by such arcane rules than if you do it the other way around.
>
That is not an arcane rule. Again, what concept does (should do)? It
checks, that object of type T *behaves as you need*, not that everything
that behaves the same way have the same type.
Ducks, i brought you some amount of ducks. They look like a ducks, they
quack like a ducks, and you treat them like a ducks. But then, i take duck
consumes off, and you see that this is a cat, this is a dog, and this is a
horse! And quacking sounds was made with little speakers! What you will do,
put costumes back on, and say, "Nope, they're all ducks"?
And how is that even possible that someone will try to use a function like
>> above, without actually knowing what is a `Container'?
>>
>
> The same way that people use std::vector without knowing that the type it
> takes actually has minimum requirements.
>
People now what std::vector is. How it behaves, and how to use it. To call
a function F which takes object of type T, you *must*, know what you can
pass to that function, and what you get as a result.
The purpose of terse syntax is to minimize template boilerplate in the most
> common and useful of cases.
>
One of the most common and useful of cases:
auto copy(InputIterator begin, InputIterator end, OutputIterator out) ->
OutputIterator
requires /* ... */
Is this how it's written right now in GCC, Clang, MSVC? No (because it is
not time to rewrite it, but anyways), in GCC it is like that:
template<typename _II, typename _OI>
inline _OI
copy(_II __first, _II __last, _OI __result)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_II>)
__glibcxx_function_requires(_OutputIteratorConcept<_OI,
typename iterator_traits<_II>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
(std::__miter_base(__first), std::__miter_base(__last),
__result));
}
When GCC 6.0 will be released, will this function be made to use terse
syntax? Or __glibcxx_* macro will be redefined?
What about Eric Niebler's and Casey Carter's STL2 version?
template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
requires
models::IndirectlyCopyable<I, O>
tagged_pair<tag::in(I), tag::out(O)>
copy(I first, S last, O result)
{
for (; first != last; ++first, ++result) {
*result = *first;
}
return {__stl2::move(first), __stl2::move(result)};
}
It uses concepts already, but, where is a terse syntax here? Is someone
going to use it? Where is *the most common and useful of case*s applies?
STL1 is not the only now, and most probably, it will not use terse syntax.
And rule, that i am arguing about, is for terse syntax, and if it is not
going to be used, for whom that rule is?
<..> to minimize template boilerplate <..>. It is not intended to be a
> full-fledged *replacement* for declaring template functions.
>
I'm not suggesting to replace it. I'm saying that it could be minimized to
the ground.
There will always be cases where you need to use full template syntax.
Not arguing with that.
> Nobody has contested that full template syntax can do either one. Nobody
> has suggested that having terse syntax use one way means that the other way
> becomes impossible.
>
Suppose you writing a library with a lot of template functions. Some of
them take arguments of the same, type. Some of them not. Suppose you want
to constrain all you functions properly, so you use terse syntax for
parameters with same type and usual template syntax for parameters that
share same concept but not required to have same type.
Will you be writing it like that
template <R T2>
auto maybe_same(R p1, T2 p2)
auto same(R p1, R p2)
or for the sake of consistency, like that:
template <R T1, R T2>
auto maybe_same(T1 p1, T2 p2)
template <R T>
auto same(T p1, T p2)
?
Without same-type rule it could be written like that:
auto maybe_same(R p1, R p2)
R {T} auto same(T p1, T p2)
Aaand consistent version looks kinda, better than others.. maybe just more
familliar. But first version, i don't like it at all.
2015-11-25 12:07 GMT+05:00 Nicol Bolas <jmckesson@gmail.com>:
> On Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:
>>
>> But what I said above still applies: since you used a different
>>> declaration,
>>> it does not support the argument that two InputIterator uses in the same
>>> declaration should be different.
>>
>>
>> I'm not making an argument that two iterators should be different. Also,
>> i am not talking about STL's "common case" which is not common, but the
>> only possible. And let's not forget about RangesTS, and STL2, where that
>> "common case" is not so common.
>>
>> I'm saying that type checking has nothing to do with defining parameters
>> of a function. It's just none of its business. User defines parameters.
>> User defines their types. User decides, if they are of the same type or not.
>>
>> merge(Container src_a, Container src_b, Container output)
>>
>> Do i want `src_a', `src_b' and `output' be of the same type? No.
>>
>
> I would say that your `merge` function here is underconstrained. Why?
> Because even if those different `Container` instances could deduce
> different types, those three different types need to have something in
> common. Namely, that the value type from `src_a` and `src_b` are
> convertible to the value type for `output`.
>
> So if you actually applied all of the constraints that your function
> needs, you *couldn't* use terse syntax. So this is not an example of the
> problem.
>
> And I think that leads to an interesting question. How often do you have a
> function which:
>
> 1) Takes two arguments that can be of different types.
>
> 2) Those two arguments are constrained by the same concept.
>
> 3) There are no additional constraints on those types that would prevent
> you from using terse syntax.
>
> Take your suggestion for `compare`. The first range and second range need
> not be the same types. *But*, they do need to have comparable value
> types. And a properly constrained template function will apply that
> constraint, so that users who pass the wrong things will get reasonable
> errors. And you can't apply such a constraint with terse syntax.
>
> I'd bet that 90% of the time that #1 and #2 are true, there's probably
> some additional constraint that your function requires of those two types.
>
> - But, because `Container' placed where types are placed, someone might
>> think that it's a type. That is confusing for that someone, lets make types
>> the same. - Okay, but what is about ones who is not confused, who actually
>> learned the language? Why make them pay and suffer? Is ones who don't
>> learned prioritized over ones who learned?
>>
>
> Why make the language more confusing to users? Why make people *have* to
> learn esoteric rules?
>
> *Somebody* will be inconvenienced no matter what you do. Why is your side
> the one that deserves to have the special syntax? Indeed, you seem to argue
> exactly why they shouldn't: because they're the ones who are willing to
> learn and use arcane rules. And therefore, they will be less inconvenienced
> by such arcane rules than if you do it the other way around.
>
> And how is that even possible that someone will try to use a function like
>> above, without actually knowing what is a `Container'?
>>
>
> The same way that people use std::vector without knowing that the type it
> takes actually has minimum requirements.
>
>
>> If you have a docs, you'll read that `merge' is a template function that
>> accepts three objects, types of which meet a requirements of the
>> `Container' concept. And if you doesn't have a docs you will go to source
>> code and see for yourself that `Container' is not a type.
>>
>> I say, there is no source of confusion. Right now, confusion is not in
>> the heads of a users.
>>
>> Oh, and that terse syntax hides that it's a template function. - But that
>> is not a problem. It is purpose of that syntax, to get rid of template
>> boilerplate, no?
>>
>
> The purpose of terse syntax is to minimize template boilerplate in the
> most common and useful of cases. It is not intended to be a full-fledged
> *replacement* for declaring template functions. There will always be
> cases where you need to use full template syntax.
>
> The question is why should your case be the one that gets favoritism?
>
>
>> I used different declaration to show that i don't need InputIterator to
>> force same type for begin and end, if i need same types i define them to be
>> the same. Just like i do right now, by the way, by writing
>>
>> template <typename I, typename O>
>> O copy(I begin, I end, O out)
>>
>> I don't need obscure rules to define begin and end to be of the same
>> type. I can use template-introduction for that, which is perfectly
>> suitable. And by allowing constrained parameters with same constraints be
>> of different types, it's will be also easier to write functions where you
>> just doesn't care about actual types. And if it's not enough, you always
>> have usual template syntax, for both cases. Cake for you, and cake for you.
>> Everyone is happy.
>>
>
> Nobody has contested that full template syntax can do either one. Nobody
> has suggested that having terse syntax use one way means that the other way
> becomes impossible.
>
> The question is who gets to use the simple syntax. Simply declaring that
> the other side can still use full template syntax is basically saying, "why
> don't you just let us win? After all, if you do, you lose."
>
> Do a lot of people find this kind of argument convincing?
>
> --
>
> ---
> 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-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0117631165c9d0052565b8bc
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">I
would say that your `merge` function here is underconstrained. Why?=20
Because even if those different `Container` instances could deduce=20
different types, those three different types need to have something in=20
common. Namely, that the value type from `src_a` and `src_b` are=20
convertible to the value type for `output`.<br></blockquote><div><br></div>=
<div>But,
nothing was said about what is a Container, here. Maybe it's enough.=
=20
Maybe Container, it is something that can hold some type T, which can=20
hold any other type. And maybe that `merge` function is not an analogue=20
of `merge` in STL. And of course, it's not an example of perfectly=20
constrained, function. One, most probably, would need to add additional=20
requires-clause.<br><br><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><=
div>So if you actually applied all of the constraints that your function ne=
eds, you <i>couldn't</i> use terse syntax.<br></div></blockquote><block=
quote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,2=
04);padding-left:1ex" class=3D"gmail_quote"><br></blockquote><blockquote st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex" class=3D"gmail_quote">And I think that leads to an interestin=
g question. How often do you have a function which:<br><br>1) Takes two arg=
uments that can be of different types.<br><br>2) Those two arguments are co=
nstrained by the same concept.<br><br>3) There are no additional constraint=
s on those types that would prevent you from using terse syntax.<br><br></b=
lockquote></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>I=
9;d
bet that 90% of the time that #1 and #2 are true, there's probably som=
e
additional constraint that your function requires of those two types.<br><=
/div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>=
=C2=A0 <br></div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote"><div>Take your suggestion for `compare`. The first range and second ra=
nge need not be the same types. <i>But</i>,
they do need to have comparable value types. And a properly constrained
template function will apply that constraint, so that users who pass=20
the wrong things will get reasonable errors. And you can't apply such a=
=20
constraint with terse syntax.<br></div></blockquote><div>=C2=A0</div><div>T=
hat's why i am unhappy with current situation, i can apply additional c=
onstraints.<br><br><span style=3D"font-family:monospace,monospace">InputIte=
rator_Sentinel {I, S} bool compare(I begin1, S end1, InputIterator begin2)<=
br>=C2=A0 requires EquallyComparable<decltype(*begin1), decltype(*begin2=
)><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && /* any addit=
ional constraints */<br></span></div><div><br>and if you need and actual ty=
pe of begin2, and you don't want to use decltype, you can use usual tem=
plate syntax.<br><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">Why =
make the language more confusing to users? Why make people <i>have</i> to l=
earn esoteric rules?<br></blockquote></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);=
padding-left:1ex"><span class=3D""></span></blockquote><div><br></div><div>=
That
is why i am here! Why? Rule that is made to make me, a user, less=20
confused, made me confused even before it came into effect! <br></div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><i>Someb=
ody</i>
will be inconvenienced no matter what you do. Why is your side the one=20
that deserves to have the special syntax? Indeed, you seem to argue=20
exactly why they shouldn't: because they're the ones who are willin=
g to=20
learn and use arcane rules. And therefore, they will be less=20
inconvenienced by such arcane rules than if you do it the other way=20
around.</div></blockquote><div><br></div><div>That is not an arcane rule. A=
gain, what concept does (should do)? It checks, that object of type T <i>be=
haves as you need</i>, not that everything that behaves the same way have t=
he same type.<br><br>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks&q=
uot;?<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span =
class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.=
8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"lt=
r"><div>And
how is that even possible that someone will try to use a function like=20
above, without actually knowing what is a `Container'?</div></div></blo=
ckquote></span><div><br>The same way that people use std::vector without kn=
owing that the type it takes actually has minimum requirements.</div></bloc=
kquote><div><br></div><div>People now what std::vector is. How it behaves, =
and how to use it. To call a function F which takes object of type T, you <=
b>must</b>, know what you can pass to that function, and what you get as a =
result.<br></div><div><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"=
>The purpose of terse syntax is to minimize template boilerplate in the mos=
t common and useful of cases.<br></blockquote></div><div><br></div><div>One=
of the most common and useful of cases:<br></div><div><br><div style=3D"ma=
rgin-left:40px"><span style=3D"font-family:monospace,monospace">auto copy(I=
nputIterator begin, InputIterator end, OutputIterator out) -> OutputIter=
ator<br></span></div><div style=3D"margin-left:40px"><span style=3D"font-fa=
mily:monospace,monospace">=C2=A0 requires /* ... */<br></span></div></div><=
div><br></div><div>Is
this how it's written right now in GCC, Clang, MSVC? No (because it is=
=20
not time to rewrite it, but anyways), in GCC it is like that:<br><br><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"><=
span style=3D"color:rgb(0,0,0)">template<typename _II, typename _OI>
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> inline _OI</span></span></pre><div style=3D"margin-left:40px"><sp=
an style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0=
)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> copy(_II __first, _II __last, _OI __result)</span></span></pre><d=
iv style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospac=
e"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> {</span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> // concept requirements</span></span></pre><div style=3D"margin=
-left:40px"><span style=3D"font-family:monospace,monospace"><span style=3D"=
color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_InputIteratorConcept<_II>)</=
span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_OutputIteratorConcept<_OI,</spa=
n></span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> typename iterator_traits<_II>::value_type>)</span></spa=
n></pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospac=
e,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_requires_valid_range(__first, __last);</span></span><=
/pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,m=
onospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"><br></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> return (std::__copy_move_a2<__is_move_iterator<_II>::_=
_value></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> (std::__miter_base(__first), std::__miter_base(__last),</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __result));</span></span></pre><div style=3D"margin-left:40px=
"><span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(=
0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> }</span></span></pre><br></div><div>When GCC 6.0 will be released=
, will this function be made to use terse syntax? Or __glibcxx_* macro will=
be redefined?<br></div><div><br></div><div>What about Eric Niebler's a=
nd Casey Carter's STL2 version?<br><br><div style=3D"margin-left:40px">=
<span style=3D"font-family:monospace,monospace">template <InputIterator =
I, Sentinel<I> S, WeaklyIncrementable O><br>=C2=A0 requires<br>=C2=
=A0=C2=A0=C2=A0 models::IndirectlyCopyable<I, O><br>=C2=A0 tagged_pai=
r<tag::in(I), tag::out(O)><br>=C2=A0 copy(I first, S last, O result)<=
br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 for (; first !=3D last; ++first, ++result=
) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *result =3D *first;<br>=C2=A0=C2=A0=
=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 return {__stl2::move(first), __stl2::move(re=
sult)};<br>=C2=A0 }</span><br></div></div><div><br></div><div>It uses conce=
pts already, but, where is a terse syntax here? Is someone going to use it=
? Where is <i>the most common and useful of case</i>s applies?<br></div><di=
v><br></div><div>STL1 is not the only now, and most probably, it will not u=
se terse syntax. And rule, that i am arguing about, is for terse syntax, an=
d if it is not going to be used, for whom that rule is?<br><br><blockquote =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex" class=3D"gmail_quote"><..> to minimize template boile=
rplate <..>. It is not intended to be a full-fledged <i>replacement</=
i> for declaring template functions.<br></blockquote><br></div><div>I'm=
not suggesting to replace it. I'm saying that it could be minimized to=
the ground.<br></div><div><br><blockquote style=3D"margin:0px 0px 0px 0.8e=
x;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_q=
uote">There will always be cases where you need to use full template syntax=
..</blockquote><div><br></div><div>Not arguing with that. <br></div></div><d=
iv>=C2=A0</div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1p=
x solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">Nobody has=
contested that full template syntax can do either one. Nobody has suggeste=
d that having terse syntax use one way means that the other way becomes imp=
ossible.<br></blockquote><div><br></div><div>Suppose you writing a library =
with a lot of template functions. Some of them take arguments of the same, =
type. Some of them not. Suppose you want to constrain all you functions pro=
perly, so you use terse syntax for parameters with same type and usual temp=
late syntax for parameters that share same concept but not required to have=
same type. <br><br>Will you be writing it like that<br><div style=3D"margi=
n-left:40px"><span style=3D"font-family:monospace,monospace"><br>template &=
lt;R T2></span><br></div><div style=3D"margin-left:40px"><span style=3D"=
font-family:monospace,monospace"></span></div><div style=3D"margin-left:40p=
x"><span style=3D"font-family:monospace,monospace">auto maybe_same(R p1, T2=
p2)<br><br></span></div><div style=3D"margin-left:40px"><span style=3D"fon=
t-family:monospace,monospace">auto same(R p1, R p2)<br></span></div><br></d=
iv><div>or for the sake of consistency, like that:<br><br><div style=3D"mar=
gin-left:40px"><span style=3D"font-family:monospace,monospace">template <=
;R T1, R T2><br></span></div><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace">auto maybe_same(T1 p1, T2 p2)</span><b=
r><br></div><div style=3D"margin-left:40px"><span style=3D"font-family:mono=
space,monospace">template <R T><br></span></div><div style=3D"margin-=
left:40px"><span style=3D"font-family:monospace,monospace">auto same(T p1, =
T p2)</span><br></div></div><div><span style=3D"font-family:monospace,monos=
pace"></span></div><div><br></div><div>?<br></div><div><br></div><div>Witho=
ut same-type rule it could be written like that:<br><br><div style=3D"margi=
n-left:40px"><span style=3D"font-family:monospace,monospace">auto maybe_sam=
e(R p1, R p2)<br><br></span></div><span style=3D"font-family:monospace,mono=
space"></span><span style=3D"font-family:monospace,monospace"></span><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">R=
{T} auto same(T p1, T p2)</span></div></div><div><br></div><div>Aaand cons=
istent version looks kinda, better than others.. maybe just more familliar.=
But first version, i don't like it at all.<br></div></div><div class=
=3D"gmail_extra"><br><div class=3D"gmail_quote">2015-11-25 12:07 GMT+05:00 =
Nicol Bolas <span dir=3D"ltr"><<a href=3D"mailto:jmckesson@gmail.com" ta=
rget=3D"_blank">jmckesson@gmail.com</a>></span>:<br><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex"><span class=3D"">On Tuesday, November 24, 2015 at 9:53:59 PM UTC=
-5, Andrei L wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid r=
gb(204,204,204);padding-left:1ex" class=3D"gmail_quote">But what I said abo=
ve still applies: since you used a different declaration,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, bu=
t the only possible. And let's not forget about RangesTS, and STL2, whe=
re that "common case" is not so common.<br><br>I'm saying tha=
t type checking has nothing to do with defining parameters
of a function. It's just none of its business. User defines parameters=
.. User defines their types. User decides, if they are of the same type or n=
ot.<br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace">merge(</span><span style=3D"font-family:monospace,mon=
ospace">Container src_a, </span><span style=3D"font-family:monospace,monosp=
ace">Container src_b, Container output)</span></div><div><br></div><div>Do =
i want `src_a', `src_b' and `output' be of the same type? No.</=
div></div></blockquote></span><div><br>I would say that your `merge` functi=
on here is underconstrained. Why? Because even if those different `Containe=
r` instances could deduce different types, those three different types need=
to have something in common. Namely, that the value type from `src_a` and =
`src_b` are convertible to the value type for `output`.<br><br>So if you ac=
tually applied all of the constraints that your function needs, you <i>coul=
dn't</i> use terse syntax. So this is not an example of the problem.<br=
><br>And I think that leads to an interesting question. How often do you ha=
ve a function which:<br><br>1) Takes two arguments that can be of different=
types.<br><br>2) Those two arguments are constrained by the same concept.<=
br><br>3) There are no additional constraints on those types that would pre=
vent you from using terse syntax.<br><br>Take your suggestion for `compare`=
.. The first range and second range need not be the same types. <i>But</i>, =
they do need to have comparable value types. And a properly constrained tem=
plate function will apply that constraint, so that users who pass the wrong=
things will get reasonable errors. And you can't apply such a constrai=
nt with terse syntax.<br><br>I'd bet that 90% of the time that #1 and #=
2 are true, there's probably some additional constraint that your funct=
ion requires of those two types.<br><br><i></i></div><span class=3D""><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>- But, because `Co=
ntainer' placed where types are placed, someone might think that it'=
;s a type. That is confusing for that someone, lets make types the same. - =
Okay, but what is about ones who is not confused, who actually learned the =
language? Why make them pay and suffer? Is ones who don't learned prior=
itized over ones who learned?<br></div></div></blockquote></span><div><br>W=
hy make the language more confusing to users? Why make people <i>have</i> t=
o learn esoteric rules?<br><br><i>Somebody</i> will be inconvenienced no ma=
tter what you do. Why is your side the one that deserves to have the specia=
l syntax? Indeed, you seem to argue exactly why they shouldn't: because=
they're the ones who are willing to learn and use arcane rules. And th=
erefore, they will be less inconvenienced by such arcane rules than if you =
do it the other way around.<br><br></div><span class=3D""><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>And how is that even possible =
that someone will try to use a function like above, without actually knowin=
g what is a `Container'?</div></div></blockquote></span><div><br>The sa=
me way that people use std::vector without knowing that the type it takes a=
ctually has minimum requirements.<br>=C2=A0</div><span class=3D""><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>If you have a docs, yo=
u'll read that `merge' is a template function that accepts three ob=
jects, types of which meet a requirements of the `Container' concept. A=
nd if you doesn't have a docs you will go to source code and see for yo=
urself that `Container' is not a type.<br><br>I say, there is no source=
of confusion. Right now, confusion is not in the heads of a users.<br></di=
v><div><br>Oh, and that terse syntax hides that it's a template functio=
n. - But that is not a problem. It is purpose of that syntax, to get rid of=
template boilerplate, no?</div></div></blockquote></span><div><br>The purp=
ose of terse syntax is to minimize template boilerplate in the most common =
and useful of cases. It is not intended to be a full-fledged <i>replacement=
</i> for declaring template functions. There will always be cases where you=
need to use full template syntax.<br><br>The question is why should your c=
ase be the one that gets favoritism?<br>=C2=A0</div><span class=3D""><block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><div></div><di=
v>I used different declaration to show that i don't need InputIterator =
to force same type for begin and end, if i need same types i define them to=
be the same. Just like i do right now, by the way, by writing<br><div styl=
e=3D"margin-left:40px"><br></div><div style=3D"margin-left:40px"><font face=
=3D"monospace,monospace">template <typename I, typename O><br></font>=
</div><div style=3D"margin-left:40px"><font face=3D"monospace,monospace">O =
copy(I begin, I end, O out)<br><br></font></div>I don't need obscure ru=
les to define begin and end to be of the same type. I can use template-intr=
oduction for that, which is perfectly suitable. And by allowing constrained=
parameters with same constraints be of different types, it's will be a=
lso easier to write functions where you just doesn't care about actual =
types. And if it's not enough, you always have usual template syntax, f=
or both cases. Cake for you, and cake for you. Everyone is happy.<br></div>=
</div></div></div></blockquote></span><div><br>Nobody has contested that fu=
ll template syntax can do either one. Nobody has suggested that having ters=
e syntax use one way means that the other way becomes impossible.<br><br>Th=
e question is who gets to use the simple syntax. Simply declaring that the =
other side can still use full template syntax is basically saying, "wh=
y don't you just let us win? After all, if you do, you lose."</div=
><br>Do a lot of people find this kind of argument convincing?<div class=3D=
"HOEnZb"><div class=3D"h5"><br>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0117631165c9d0052565b8bc--
.
Author: Andrei L <aendaerel@gmail.com>
Date: Thu, 26 Nov 2015 05:09:29 +0500
Raw View
--001a113b1a487adaad052566631d
Content-Type: text/plain; charset=UTF-8
When you writing a function and you make use of type constraints, and you
decided to use terse syntax, you think, "How that object (argument) should
behave?" First thing you think about - is behavior. And when you choose
right behavior, you think, "What about its type? Do i need these be of the
same type?", not, "Do i need them to be different?". And you think that
way, because you didn't specified their types, because you choose to use
terse syntax, and same-type rule is basically saying, "Oh, i see you want
them to be of the same type! I'll make it". But no you don't, you don't
want, you don't care about type.
Isn't that is how we do it in life? If we care, we take actions, we make
statements, that we care, and if we don't, we do nothing. We don't take
actions to show that we don't care, because if we do something, that
usually means that we care. That is what bothers me.
2015-11-26 4:21 GMT+05:00 Andrei L <aendaerel@gmail.com>:
> I would say that your `merge` function here is underconstrained. Why?
>> Because even if those different `Container` instances could deduce
>> different types, those three different types need to have something in
>> common. Namely, that the value type from `src_a` and `src_b` are
>> convertible to the value type for `output`.
>>
>
> But, nothing was said about what is a Container, here. Maybe it's enough.
> Maybe Container, it is something that can hold some type T, which can hold
> any other type. And maybe that `merge` function is not an analogue of
> `merge` in STL. And of course, it's not an example of perfectly
> constrained, function. One, most probably, would need to add additional
> requires-clause.
>
> So if you actually applied all of the constraints that your function
>> needs, you *couldn't* use terse syntax.
>>
>
>> And I think that leads to an interesting question. How often do you have
>> a function which:
>>
>> 1) Takes two arguments that can be of different types.
>>
>> 2) Those two arguments are constrained by the same concept.
>>
>> 3) There are no additional constraints on those types that would prevent
>> you from using terse syntax.
>>
>> I'd bet that 90% of the time that #1 and #2 are true, there's probably
>> some additional constraint that your function requires of those two types.
>>
>
>>
> Take your suggestion for `compare`. The first range and second range need
>> not be the same types. *But*, they do need to have comparable value
>> types. And a properly constrained template function will apply that
>> constraint, so that users who pass the wrong things will get reasonable
>> errors. And you can't apply such a constraint with terse syntax.
>>
>
> That's why i am unhappy with current situation, i can apply additional
> constraints.
>
> InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIterator
> begin2)
> requires EquallyComparable<decltype(*begin1), decltype(*begin2)>
> && /* any additional constraints */
>
> and if you need and actual type of begin2, and you don't want to use
> decltype, you can use usual template syntax.
>
> Why make the language more confusing to users? Why make people *have* to
>> learn esoteric rules?
>>
>
> That is why i am here! Why? Rule that is made to make me, a user, less
> confused, made me confused even before it came into effect!
>
>
>> *Somebody* will be inconvenienced no matter what you do. Why is your
>> side the one that deserves to have the special syntax? Indeed, you seem to
>> argue exactly why they shouldn't: because they're the ones who are willing
>> to learn and use arcane rules. And therefore, they will be less
>> inconvenienced by such arcane rules than if you do it the other way around.
>>
>
> That is not an arcane rule. Again, what concept does (should do)? It
> checks, that object of type T *behaves as you need*, not that everything
> that behaves the same way have the same type.
>
> Ducks, i brought you some amount of ducks. They look like a ducks, they
> quack like a ducks, and you treat them like a ducks. But then, i take duck
> consumes off, and you see that this is a cat, this is a dog, and this is a
> horse! And quacking sounds was made with little speakers! What you will do,
> put costumes back on, and say, "Nope, they're all ducks"?
>
> And how is that even possible that someone will try to use a function like
>>> above, without actually knowing what is a `Container'?
>>>
>>
>> The same way that people use std::vector without knowing that the type it
>> takes actually has minimum requirements.
>>
>
> People now what std::vector is. How it behaves, and how to use it. To call
> a function F which takes object of type T, you *must*, know what you can
> pass to that function, and what you get as a result.
>
> The purpose of terse syntax is to minimize template boilerplate in the
>> most common and useful of cases.
>>
>
> One of the most common and useful of cases:
>
> auto copy(InputIterator begin, InputIterator end, OutputIterator out) ->
> OutputIterator
> requires /* ... */
>
> Is this how it's written right now in GCC, Clang, MSVC? No (because it is
> not time to rewrite it, but anyways), in GCC it is like that:
>
> template<typename _II, typename _OI>
>
> inline _OI
>
> copy(_II __first, _II __last, _OI __result)
>
> {
>
> // concept requirements
>
> __glibcxx_function_requires(_InputIteratorConcept<_II>)
>
> __glibcxx_function_requires(_OutputIteratorConcept<_OI,
>
> typename iterator_traits<_II>::value_type>)
>
> __glibcxx_requires_valid_range(__first, __last);
>
>
> return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
>
> (std::__miter_base(__first), std::__miter_base(__last),
>
> __result));
>
> }
>
>
> When GCC 6.0 will be released, will this function be made to use terse
> syntax? Or __glibcxx_* macro will be redefined?
>
> What about Eric Niebler's and Casey Carter's STL2 version?
>
> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
> requires
> models::IndirectlyCopyable<I, O>
> tagged_pair<tag::in(I), tag::out(O)>
> copy(I first, S last, O result)
> {
> for (; first != last; ++first, ++result) {
> *result = *first;
> }
> return {__stl2::move(first), __stl2::move(result)};
> }
>
> It uses concepts already, but, where is a terse syntax here? Is someone
> going to use it? Where is *the most common and useful of case*s applies?
>
> STL1 is not the only now, and most probably, it will not use terse syntax.
> And rule, that i am arguing about, is for terse syntax, and if it is not
> going to be used, for whom that rule is?
>
> <..> to minimize template boilerplate <..>. It is not intended to be a
>> full-fledged *replacement* for declaring template functions.
>>
>
> I'm not suggesting to replace it. I'm saying that it could be minimized to
> the ground.
>
> There will always be cases where you need to use full template syntax.
>
>
> Not arguing with that.
>
>
>> Nobody has contested that full template syntax can do either one. Nobody
>> has suggested that having terse syntax use one way means that the other way
>> becomes impossible.
>>
>
> Suppose you writing a library with a lot of template functions. Some of
> them take arguments of the same, type. Some of them not. Suppose you want
> to constrain all you functions properly, so you use terse syntax for
> parameters with same type and usual template syntax for parameters that
> share same concept but not required to have same type.
>
> Will you be writing it like that
>
> template <R T2>
> auto maybe_same(R p1, T2 p2)
>
> auto same(R p1, R p2)
>
> or for the sake of consistency, like that:
>
> template <R T1, R T2>
> auto maybe_same(T1 p1, T2 p2)
>
> template <R T>
> auto same(T p1, T p2)
>
> ?
>
> Without same-type rule it could be written like that:
>
> auto maybe_same(R p1, R p2)
>
> R {T} auto same(T p1, T p2)
>
> Aaand consistent version looks kinda, better than others.. maybe just more
> familliar. But first version, i don't like it at all.
>
> 2015-11-25 12:07 GMT+05:00 Nicol Bolas <jmckesson@gmail.com>:
>
>> On Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:
>>>
>>> But what I said above still applies: since you used a different
>>>> declaration,
>>>> it does not support the argument that two InputIterator uses in the same
>>>> declaration should be different.
>>>
>>>
>>> I'm not making an argument that two iterators should be different. Also,
>>> i am not talking about STL's "common case" which is not common, but the
>>> only possible. And let's not forget about RangesTS, and STL2, where that
>>> "common case" is not so common.
>>>
>>> I'm saying that type checking has nothing to do with defining parameters
>>> of a function. It's just none of its business. User defines parameters.
>>> User defines their types. User decides, if they are of the same type or not.
>>>
>>> merge(Container src_a, Container src_b, Container output)
>>>
>>> Do i want `src_a', `src_b' and `output' be of the same type? No.
>>>
>>
>> I would say that your `merge` function here is underconstrained. Why?
>> Because even if those different `Container` instances could deduce
>> different types, those three different types need to have something in
>> common. Namely, that the value type from `src_a` and `src_b` are
>> convertible to the value type for `output`.
>>
>> So if you actually applied all of the constraints that your function
>> needs, you *couldn't* use terse syntax. So this is not an example of the
>> problem.
>>
>> And I think that leads to an interesting question. How often do you have
>> a function which:
>>
>> 1) Takes two arguments that can be of different types.
>>
>> 2) Those two arguments are constrained by the same concept.
>>
>> 3) There are no additional constraints on those types that would prevent
>> you from using terse syntax.
>>
>> Take your suggestion for `compare`. The first range and second range need
>> not be the same types. *But*, they do need to have comparable value
>> types. And a properly constrained template function will apply that
>> constraint, so that users who pass the wrong things will get reasonable
>> errors. And you can't apply such a constraint with terse syntax.
>>
>> I'd bet that 90% of the time that #1 and #2 are true, there's probably
>> some additional constraint that your function requires of those two types.
>>
>> - But, because `Container' placed where types are placed, someone might
>>> think that it's a type. That is confusing for that someone, lets make types
>>> the same. - Okay, but what is about ones who is not confused, who actually
>>> learned the language? Why make them pay and suffer? Is ones who don't
>>> learned prioritized over ones who learned?
>>>
>>
>> Why make the language more confusing to users? Why make people *have* to
>> learn esoteric rules?
>>
>> *Somebody* will be inconvenienced no matter what you do. Why is your
>> side the one that deserves to have the special syntax? Indeed, you seem to
>> argue exactly why they shouldn't: because they're the ones who are willing
>> to learn and use arcane rules. And therefore, they will be less
>> inconvenienced by such arcane rules than if you do it the other way around.
>>
>> And how is that even possible that someone will try to use a function
>>> like above, without actually knowing what is a `Container'?
>>>
>>
>> The same way that people use std::vector without knowing that the type it
>> takes actually has minimum requirements.
>>
>>
>>> If you have a docs, you'll read that `merge' is a template function that
>>> accepts three objects, types of which meet a requirements of the
>>> `Container' concept. And if you doesn't have a docs you will go to source
>>> code and see for yourself that `Container' is not a type.
>>>
>>> I say, there is no source of confusion. Right now, confusion is not in
>>> the heads of a users.
>>>
>>> Oh, and that terse syntax hides that it's a template function. - But
>>> that is not a problem. It is purpose of that syntax, to get rid of template
>>> boilerplate, no?
>>>
>>
>> The purpose of terse syntax is to minimize template boilerplate in the
>> most common and useful of cases. It is not intended to be a full-fledged
>> *replacement* for declaring template functions. There will always be
>> cases where you need to use full template syntax.
>>
>> The question is why should your case be the one that gets favoritism?
>>
>>
>>> I used different declaration to show that i don't need InputIterator to
>>> force same type for begin and end, if i need same types i define them to be
>>> the same. Just like i do right now, by the way, by writing
>>>
>>> template <typename I, typename O>
>>> O copy(I begin, I end, O out)
>>>
>>> I don't need obscure rules to define begin and end to be of the same
>>> type. I can use template-introduction for that, which is perfectly
>>> suitable. And by allowing constrained parameters with same constraints be
>>> of different types, it's will be also easier to write functions where you
>>> just doesn't care about actual types. And if it's not enough, you always
>>> have usual template syntax, for both cases. Cake for you, and cake for you.
>>> Everyone is happy.
>>>
>>
>> Nobody has contested that full template syntax can do either one. Nobody
>> has suggested that having terse syntax use one way means that the other way
>> becomes impossible.
>>
>> The question is who gets to use the simple syntax. Simply declaring that
>> the other side can still use full template syntax is basically saying, "why
>> don't you just let us win? After all, if you do, you lose."
>>
>> Do a lot of people find this kind of argument convincing?
>>
>> --
>>
>> ---
>> 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-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a113b1a487adaad052566631d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>When you writing a function and you make use of type =
constraints, and you decided to use terse syntax, you think, "How that=
object (argument) should behave?" First thing you think about - is be=
havior. And when you choose right behavior, you think, "What about its=
type? Do i need these be of the same type?", not, "Do i need the=
m to be different?". And you think that way, because you didn't sp=
ecified their types, because you choose to use terse syntax, and same-type =
rule is basically saying, "Oh, i see you want them to be of the same t=
ype! I'll make it". But no you don't, you don't want, you =
don't care about type.<br><br></div>Isn't that is how we do it in l=
ife? If we care, we take actions, we make statements, that we care, and if =
we don't, we do nothing. We don't take actions to show that we don&=
#39;t care, because if we do something, that usually means that we care. Th=
at is what bothers me.<br></div><div class=3D"gmail_extra"><br><div class=
=3D"gmail_quote">2015-11-26 4:21 GMT+05:00 Andrei L <span dir=3D"ltr"><<=
a href=3D"mailto:aendaerel@gmail.com" target=3D"_blank">aendaerel@gmail.com=
</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span c=
lass=3D""><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">I
would say that your `merge` function here is underconstrained. Why?=20
Because even if those different `Container` instances could deduce=20
different types, those three different types need to have something in=20
common. Namely, that the value type from `src_a` and `src_b` are=20
convertible to the value type for `output`.<br></blockquote><div><br></div>=
</span><div>But,
nothing was said about what is a Container, here. Maybe it's enough.=
=20
Maybe Container, it is something that can hold some type T, which can=20
hold any other type. And maybe that `merge` function is not an analogue=20
of `merge` in STL. And of course, it's not an example of perfectly=20
constrained, function. One, most probably, would need to add additional=20
requires-clause.<span class=3D""><br><br><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex"><div>So if you actually applied all of the constraints that=
your function needs, you <i>couldn't</i> use terse syntax.<br></div></=
blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><br></blockquo=
te></span><span class=3D""><blockquote style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote=
">And I think that leads to an interesting question. How often do you have =
a function which:<br><br>1) Takes two arguments that can be of different ty=
pes.<br><br>2) Those two arguments are constrained by the same concept.<br>=
<br>3) There are no additional constraints on those types that would preven=
t you from using terse syntax.<br><br></blockquote></span></div><span class=
=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div>I'd
bet that 90% of the time that #1 and #2 are true, there's probably som=
e
additional constraint that your function requires of those two types.<br><=
/div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>=
=C2=A0 <br></div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote"><div>Take your suggestion for `compare`. The first range and second ra=
nge need not be the same types. <i>But</i>,
they do need to have comparable value types. And a properly constrained
template function will apply that constraint, so that users who pass=20
the wrong things will get reasonable errors. And you can't apply such a=
=20
constraint with terse syntax.<br></div></blockquote><div>=C2=A0</div></span=
><div>That's why i am unhappy with current situation, i can apply addit=
ional constraints.<br><br><span style=3D"font-family:monospace,monospace"><=
span class=3D"">InputIterator_Sentinel {I, S} bool compare(I begin1, S end1=
, InputIterator begin2)<br></span>=C2=A0 requires EquallyComparable<decl=
type(*begin1), decltype(*begin2)><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 && /* any additional constraints */<br></span></div><div>=
<br>and if you need and actual type of begin2, and you don't want to us=
e decltype, you can use usual template syntax.<span class=3D""><br><br><blo=
ckquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204=
,204);padding-left:1ex" class=3D"gmail_quote">Why make the language more co=
nfusing to users? Why make people <i>have</i> to learn esoteric rules?<br><=
/blockquote></span></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
<span></span></blockquote><div><br></div><div>That
is why i am here! Why? Rule that is made to make me, a user, less=20
confused, made me confused even before it came into effect! <br></div><span=
class=3D""><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1=
ex"><div><i>Somebody</i>
will be inconvenienced no matter what you do. Why is your side the one=20
that deserves to have the special syntax? Indeed, you seem to argue=20
exactly why they shouldn't: because they're the ones who are willin=
g to=20
learn and use arcane rules. And therefore, they will be less=20
inconvenienced by such arcane rules than if you do it the other way=20
around.</div></blockquote><div><br></div></span><div>That is not an arcane =
rule. Again, what concept does (should do)? It checks, that object of type =
T <i>behaves as you need</i>, not that everything that behaves the same way=
have the same type.<br><br>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks&q=
uot;?<br><br></div><span class=3D""><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div>And
how is that even possible that someone will try to use a function like=20
above, without actually knowing what is a `Container'?</div></div></blo=
ckquote></span><div><br>The same way that people use std::vector without kn=
owing that the type it takes actually has minimum requirements.</div></bloc=
kquote><div><br></div></span><div>People now what std::vector is. How it be=
haves, and how to use it. To call a function F which takes object of type T=
, you <b>must</b>, know what you can pass to that function, and what you ge=
t as a result.<br></div><span class=3D""><div><br><blockquote style=3D"marg=
in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x" class=3D"gmail_quote">The purpose of terse syntax is to minimize templat=
e boilerplate in the most common and useful of cases.<br></blockquote></div=
><div><br></div></span><div>One of the most common and useful of cases:<br>=
</div><div><br><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace">auto copy(InputIterator begin, InputIterator end, Outpu=
tIterator out) -> OutputIterator<br></span></div><div style=3D"margin-le=
ft:40px"><span style=3D"font-family:monospace,monospace">=C2=A0 requires /*=
... */<br></span></div></div><div><br></div><div>Is
this how it's written right now in GCC, Clang, MSVC? No (because it is=
=20
not time to rewrite it, but anyways), in GCC it is like that:<br><br><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"><=
span style=3D"color:rgb(0,0,0)">template<typename _II, typename _OI>
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> inline _OI</span></span></pre><div style=3D"margin-left:40px"><sp=
an style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0=
)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> copy(_II __first, _II __last, _OI __result)</span></span></pre><d=
iv style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospac=
e"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> {</span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> // concept requirements</span></span></pre><div style=3D"margin=
-left:40px"><span style=3D"font-family:monospace,monospace"><span style=3D"=
color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_InputIteratorConcept<_II>)</=
span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_OutputIteratorConcept<_OI,</spa=
n></span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> typename iterator_traits<_II>::value_type>)</span></spa=
n></pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospac=
e,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_requires_valid_range(__first, __last);</span></span><=
/pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,m=
onospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"><br></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> return (std::__copy_move_a2<__is_move_iterator<_II>::_=
_value></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> (std::__miter_base(__first), std::__miter_base(__last),</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __result));</span></span></pre><div style=3D"margin-left:40px=
"><span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(=
0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> }</span></span></pre><br></div><div>When GCC 6.0 will be released=
, will this function be made to use terse syntax? Or __glibcxx_* macro will=
be redefined?<br></div><div><br></div><div>What about Eric Niebler's a=
nd Casey Carter's STL2 version?<br><br><div style=3D"margin-left:40px">=
<span style=3D"font-family:monospace,monospace">template <InputIterator =
I, Sentinel<I> S, WeaklyIncrementable O><br>=C2=A0 requires<br>=C2=
=A0=C2=A0=C2=A0 models::IndirectlyCopyable<I, O><br>=C2=A0 tagged_pai=
r<tag::in(I), tag::out(O)><br>=C2=A0 copy(I first, S last, O result)<=
br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 for (; first !=3D last; ++first, ++result=
) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *result =3D *first;<br>=C2=A0=C2=A0=
=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 return {__stl2::move(first), __stl2::move(re=
sult)};<br>=C2=A0 }</span><br></div></div><div><br></div><div>It uses conce=
pts already, but, where is a terse syntax here? Is someone going to use it=
? Where is <i>the most common and useful of case</i>s applies?<br></div><di=
v><br></div><div>STL1 is not the only now, and most probably, it will not u=
se terse syntax. And rule, that i am arguing about, is for terse syntax, an=
d if it is not going to be used, for whom that rule is?<br><br><blockquote =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex" class=3D"gmail_quote"><..> to minimize template boile=
rplate <..>. It is not intended to be a full-fledged <i>replacement</=
i> for declaring template functions.<br></blockquote><br></div><div>I'm=
not suggesting to replace it. I'm saying that it could be minimized to=
the ground.<br></div><div><span class=3D""><br><blockquote style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
class=3D"gmail_quote">There will always be cases where you need to use ful=
l template syntax.</blockquote><div><br></div></span><div>Not arguing with =
that. <br></div></div><span class=3D""><div>=C2=A0</div><blockquote style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex" class=3D"gmail_quote">Nobody has contested that full template sy=
ntax can do either one. Nobody has suggested that having terse syntax use o=
ne way means that the other way becomes impossible.<br></blockquote><div><b=
r></div></span><div>Suppose you writing a library with a lot of template fu=
nctions. Some of them take arguments of the same, type. Some of them not. S=
uppose you want to constrain all you functions properly, so you use terse s=
yntax for parameters with same type and usual template syntax for parameter=
s that share same concept but not required to have same type. <br><br>Will =
you be writing it like that<br><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><br>template <R T2></span><br></=
div><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,mo=
nospace"></span></div><div style=3D"margin-left:40px"><span style=3D"font-f=
amily:monospace,monospace">auto maybe_same(R p1, T2 p2)<br><br></span></div=
><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,monos=
pace">auto same(R p1, R p2)<br></span></div><br></div><div>or for the sake =
of consistency, like that:<span class=3D""><br><br><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">template <R T1, =
R T2><br></span></div></span><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace">auto maybe_same(T1 p1, T2 p2)</span><b=
r><br></div><div style=3D"margin-left:40px"><span style=3D"font-family:mono=
space,monospace">template <R T><br></span></div><div style=3D"margin-=
left:40px"><span style=3D"font-family:monospace,monospace">auto same(T p1, =
T p2)</span><br></div></div><div><span style=3D"font-family:monospace,monos=
pace"></span></div><div><br></div><div>?<br></div><div><br></div><div>Witho=
ut same-type rule it could be written like that:<br><br><div style=3D"margi=
n-left:40px"><span style=3D"font-family:monospace,monospace">auto maybe_sam=
e(R p1, R p2)<br><br></span></div><span style=3D"font-family:monospace,mono=
space"></span><span style=3D"font-family:monospace,monospace"></span><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">R=
{T} auto same(T p1, T p2)</span></div></div><div><br></div><div>Aaand cons=
istent version looks kinda, better than others.. maybe just more familliar.=
But first version, i don't like it at all.<br></div></div><div class=
=3D"HOEnZb"><div class=3D"h5"><div class=3D"gmail_extra"><br><div class=3D"=
gmail_quote">2015-11-25 12:07 GMT+05:00 Nicol Bolas <span dir=3D"ltr"><<=
a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com=
</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
.8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On Tuesday, Novemb=
er 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:<blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div><blockquote style=3D"margin:0px 0px 0px =
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gma=
il_quote">But what I said above still applies: since you used a different d=
eclaration,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, bu=
t the only possible. And let's not forget about RangesTS, and STL2, whe=
re that "common case" is not so common.<br><br>I'm saying tha=
t type checking has nothing to do with defining parameters
of a function. It's just none of its business. User defines parameters=
.. User defines their types. User decides, if they are of the same type or n=
ot.<br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace">merge(</span><span style=3D"font-family:monospace,mon=
ospace">Container src_a, </span><span style=3D"font-family:monospace,monosp=
ace">Container src_b, Container output)</span></div><div><br></div><div>Do =
i want `src_a', `src_b' and `output' be of the same type? No.</=
div></div></blockquote></span><div><br>I would say that your `merge` functi=
on here is underconstrained. Why? Because even if those different `Containe=
r` instances could deduce different types, those three different types need=
to have something in common. Namely, that the value type from `src_a` and =
`src_b` are convertible to the value type for `output`.<br><br>So if you ac=
tually applied all of the constraints that your function needs, you <i>coul=
dn't</i> use terse syntax. So this is not an example of the problem.<br=
><br>And I think that leads to an interesting question. How often do you ha=
ve a function which:<br><br>1) Takes two arguments that can be of different=
types.<br><br>2) Those two arguments are constrained by the same concept.<=
br><br>3) There are no additional constraints on those types that would pre=
vent you from using terse syntax.<br><br>Take your suggestion for `compare`=
.. The first range and second range need not be the same types. <i>But</i>, =
they do need to have comparable value types. And a properly constrained tem=
plate function will apply that constraint, so that users who pass the wrong=
things will get reasonable errors. And you can't apply such a constrai=
nt with terse syntax.<br><br>I'd bet that 90% of the time that #1 and #=
2 are true, there's probably some additional constraint that your funct=
ion requires of those two types.<br><br><i></i></div><span><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>- But, because `Container'=
; placed where types are placed, someone might think that it's a type. =
That is confusing for that someone, lets make types the same. - Okay, but w=
hat is about ones who is not confused, who actually learned the language? W=
hy make them pay and suffer? Is ones who don't learned prioritized over=
ones who learned?<br></div></div></blockquote></span><div><br>Why make the=
language more confusing to users? Why make people <i>have</i> to learn eso=
teric rules?<br><br><i>Somebody</i> will be inconvenienced no matter what y=
ou do. Why is your side the one that deserves to have the special syntax? I=
ndeed, you seem to argue exactly why they shouldn't: because they'r=
e the ones who are willing to learn and use arcane rules. And therefore, th=
ey will be less inconvenienced by such arcane rules than if you do it the o=
ther way around.<br><br></div><span><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div>And how is that even possible that someone will try =
to use a function like above, without actually knowing what is a `Container=
'?</div></div></blockquote></span><div><br>The same way that people use=
std::vector without knowing that the type it takes actually has minimum re=
quirements.<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>If you have a docs, you'll read that `merge' is=
a template function that accepts three objects, types of which meet a requ=
irements of the `Container' concept. And if you doesn't have a docs=
you will go to source code and see for yourself that `Container' is no=
t a type.<br><br>I say, there is no source of confusion. Right now, confusi=
on is not in the heads of a users.<br></div><div><br>Oh, and that terse syn=
tax hides that it's a template function. - But that is not a problem. I=
t is purpose of that syntax, to get rid of template boilerplate, no?</div><=
/div></blockquote></span><div><br>The purpose of terse syntax is to minimiz=
e template boilerplate in the most common and useful of cases. It is not in=
tended to be a full-fledged <i>replacement</i> for declaring template funct=
ions. There will always be cases where you need to use full template syntax=
..<br><br>The question is why should your case be the one that gets favoriti=
sm?<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div><div></div><div>I used different declaration to show tha=
t i don't need InputIterator to force same type for begin and end, if i=
need same types i define them to be the same. Just like i do right now, by=
the way, by writing<br><div style=3D"margin-left:40px"><br></div><div styl=
e=3D"margin-left:40px"><font face=3D"monospace,monospace">template <type=
name I, typename O><br></font></div><div style=3D"margin-left:40px"><fon=
t face=3D"monospace,monospace">O copy(I begin, I end, O out)<br><br></font>=
</div>I don't need obscure rules to define begin and end to be of the s=
ame type. I can use template-introduction for that, which is perfectly suit=
able. And by allowing constrained parameters with same constraints be of di=
fferent types, it's will be also easier to write functions where you ju=
st doesn't care about actual types. And if it's not enough, you alw=
ays have usual template syntax, for both cases. Cake for you, and cake for =
you. Everyone is happy.<br></div></div></div></div></blockquote></span><div=
><br>Nobody has contested that full template syntax can do either one. Nobo=
dy has suggested that having terse syntax use one way means that the other =
way becomes impossible.<br><br>The question is who gets to use the simple s=
yntax. Simply declaring that the other side can still use full template syn=
tax is basically saying, "why don't you just let us win? After all=
, if you do, you lose."</div><br>Do a lot of people find this kind of =
argument convincing?<div><div><br>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a113b1a487adaad052566631d--
.
Author: Andrei L <aendaerel@gmail.com>
Date: Thu, 26 Nov 2015 05:36:35 +0500
Raw View
--089e0149c3206fab6b052566c442
Content-Type: text/plain; charset=UTF-8
Also, since type constraints now could be applied everywhere, i can declare
a variable with it.
Container c;
Non-confused user will think that Container is a type. And what he will get
if he will try to initialize it?
Container c {1, 2, 3};
Compiler error saying something about `variable of type auto should be
initialized with single value`? Or
Container c = {1, 2, 3};
he will end up with std::initializer_list<int>?
Confusion about type constraints is everywhere, and same-type rule is not
helping.
2015-11-26 5:09 GMT+05:00 Andrei L <aendaerel@gmail.com>:
> When you writing a function and you make use of type constraints, and you
> decided to use terse syntax, you think, "How that object (argument) should
> behave?" First thing you think about - is behavior. And when you choose
> right behavior, you think, "What about its type? Do i need these be of the
> same type?", not, "Do i need them to be different?". And you think that
> way, because you didn't specified their types, because you choose to use
> terse syntax, and same-type rule is basically saying, "Oh, i see you want
> them to be of the same type! I'll make it". But no you don't, you don't
> want, you don't care about type.
>
> Isn't that is how we do it in life? If we care, we take actions, we make
> statements, that we care, and if we don't, we do nothing. We don't take
> actions to show that we don't care, because if we do something, that
> usually means that we care. That is what bothers me.
>
> 2015-11-26 4:21 GMT+05:00 Andrei L <aendaerel@gmail.com>:
>
>> I would say that your `merge` function here is underconstrained. Why?
>>> Because even if those different `Container` instances could deduce
>>> different types, those three different types need to have something in
>>> common. Namely, that the value type from `src_a` and `src_b` are
>>> convertible to the value type for `output`.
>>>
>>
>> But, nothing was said about what is a Container, here. Maybe it's enough.
>> Maybe Container, it is something that can hold some type T, which can hold
>> any other type. And maybe that `merge` function is not an analogue of
>> `merge` in STL. And of course, it's not an example of perfectly
>> constrained, function. One, most probably, would need to add additional
>> requires-clause.
>>
>> So if you actually applied all of the constraints that your function
>>> needs, you *couldn't* use terse syntax.
>>>
>>
>>> And I think that leads to an interesting question. How often do you have
>>> a function which:
>>>
>>> 1) Takes two arguments that can be of different types.
>>>
>>> 2) Those two arguments are constrained by the same concept.
>>>
>>> 3) There are no additional constraints on those types that would prevent
>>> you from using terse syntax.
>>>
>>> I'd bet that 90% of the time that #1 and #2 are true, there's probably
>>> some additional constraint that your function requires of those two types.
>>>
>>
>>>
>> Take your suggestion for `compare`. The first range and second range need
>>> not be the same types. *But*, they do need to have comparable value
>>> types. And a properly constrained template function will apply that
>>> constraint, so that users who pass the wrong things will get reasonable
>>> errors. And you can't apply such a constraint with terse syntax.
>>>
>>
>> That's why i am unhappy with current situation, i can apply additional
>> constraints.
>>
>> InputIterator_Sentinel {I, S} bool compare(I begin1, S end1,
>> InputIterator begin2)
>> requires EquallyComparable<decltype(*begin1), decltype(*begin2)>
>> && /* any additional constraints */
>>
>> and if you need and actual type of begin2, and you don't want to use
>> decltype, you can use usual template syntax.
>>
>> Why make the language more confusing to users? Why make people *have* to
>>> learn esoteric rules?
>>>
>>
>> That is why i am here! Why? Rule that is made to make me, a user, less
>> confused, made me confused even before it came into effect!
>>
>>
>>> *Somebody* will be inconvenienced no matter what you do. Why is your
>>> side the one that deserves to have the special syntax? Indeed, you seem to
>>> argue exactly why they shouldn't: because they're the ones who are willing
>>> to learn and use arcane rules. And therefore, they will be less
>>> inconvenienced by such arcane rules than if you do it the other way around.
>>>
>>
>> That is not an arcane rule. Again, what concept does (should do)? It
>> checks, that object of type T *behaves as you need*, not that everything
>> that behaves the same way have the same type.
>>
>> Ducks, i brought you some amount of ducks. They look like a ducks, they
>> quack like a ducks, and you treat them like a ducks. But then, i take duck
>> consumes off, and you see that this is a cat, this is a dog, and this is a
>> horse! And quacking sounds was made with little speakers! What you will do,
>> put costumes back on, and say, "Nope, they're all ducks"?
>>
>> And how is that even possible that someone will try to use a function
>>>> like above, without actually knowing what is a `Container'?
>>>>
>>>
>>> The same way that people use std::vector without knowing that the type
>>> it takes actually has minimum requirements.
>>>
>>
>> People now what std::vector is. How it behaves, and how to use it. To
>> call a function F which takes object of type T, you *must*, know what
>> you can pass to that function, and what you get as a result.
>>
>> The purpose of terse syntax is to minimize template boilerplate in the
>>> most common and useful of cases.
>>>
>>
>> One of the most common and useful of cases:
>>
>> auto copy(InputIterator begin, InputIterator end, OutputIterator out) ->
>> OutputIterator
>> requires /* ... */
>>
>> Is this how it's written right now in GCC, Clang, MSVC? No (because it is
>> not time to rewrite it, but anyways), in GCC it is like that:
>>
>> template<typename _II, typename _OI>
>>
>> inline _OI
>>
>> copy(_II __first, _II __last, _OI __result)
>>
>> {
>>
>> // concept requirements
>>
>> __glibcxx_function_requires(_InputIteratorConcept<_II>)
>>
>> __glibcxx_function_requires(_OutputIteratorConcept<_OI,
>>
>> typename iterator_traits<_II>::value_type>)
>>
>> __glibcxx_requires_valid_range(__first, __last);
>>
>>
>> return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
>>
>> (std::__miter_base(__first), std::__miter_base(__last),
>>
>> __result));
>>
>> }
>>
>>
>> When GCC 6.0 will be released, will this function be made to use terse
>> syntax? Or __glibcxx_* macro will be redefined?
>>
>> What about Eric Niebler's and Casey Carter's STL2 version?
>>
>> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
>> requires
>> models::IndirectlyCopyable<I, O>
>> tagged_pair<tag::in(I), tag::out(O)>
>> copy(I first, S last, O result)
>> {
>> for (; first != last; ++first, ++result) {
>> *result = *first;
>> }
>> return {__stl2::move(first), __stl2::move(result)};
>> }
>>
>> It uses concepts already, but, where is a terse syntax here? Is someone
>> going to use it? Where is *the most common and useful of case*s applies?
>>
>> STL1 is not the only now, and most probably, it will not use terse
>> syntax. And rule, that i am arguing about, is for terse syntax, and if it
>> is not going to be used, for whom that rule is?
>>
>> <..> to minimize template boilerplate <..>. It is not intended to be a
>>> full-fledged *replacement* for declaring template functions.
>>>
>>
>> I'm not suggesting to replace it. I'm saying that it could be minimized
>> to the ground.
>>
>> There will always be cases where you need to use full template syntax.
>>
>>
>> Not arguing with that.
>>
>>
>>> Nobody has contested that full template syntax can do either one. Nobody
>>> has suggested that having terse syntax use one way means that the other way
>>> becomes impossible.
>>>
>>
>> Suppose you writing a library with a lot of template functions. Some of
>> them take arguments of the same, type. Some of them not. Suppose you want
>> to constrain all you functions properly, so you use terse syntax for
>> parameters with same type and usual template syntax for parameters that
>> share same concept but not required to have same type.
>>
>> Will you be writing it like that
>>
>> template <R T2>
>> auto maybe_same(R p1, T2 p2)
>>
>> auto same(R p1, R p2)
>>
>> or for the sake of consistency, like that:
>>
>> template <R T1, R T2>
>> auto maybe_same(T1 p1, T2 p2)
>>
>> template <R T>
>> auto same(T p1, T p2)
>>
>> ?
>>
>> Without same-type rule it could be written like that:
>>
>> auto maybe_same(R p1, R p2)
>>
>> R {T} auto same(T p1, T p2)
>>
>> Aaand consistent version looks kinda, better than others.. maybe just
>> more familliar. But first version, i don't like it at all.
>>
>> 2015-11-25 12:07 GMT+05:00 Nicol Bolas <jmckesson@gmail.com>:
>>
>>> On Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:
>>>>
>>>> But what I said above still applies: since you used a different
>>>>> declaration,
>>>>> it does not support the argument that two InputIterator uses in the
>>>>> same
>>>>> declaration should be different.
>>>>
>>>>
>>>> I'm not making an argument that two iterators should be different.
>>>> Also, i am not talking about STL's "common case" which is not common, but
>>>> the only possible. And let's not forget about RangesTS, and STL2, where
>>>> that "common case" is not so common.
>>>>
>>>> I'm saying that type checking has nothing to do with defining
>>>> parameters of a function. It's just none of its business. User defines
>>>> parameters. User defines their types. User decides, if they are of the same
>>>> type or not.
>>>>
>>>> merge(Container src_a, Container src_b, Container output)
>>>>
>>>> Do i want `src_a', `src_b' and `output' be of the same type? No.
>>>>
>>>
>>> I would say that your `merge` function here is underconstrained. Why?
>>> Because even if those different `Container` instances could deduce
>>> different types, those three different types need to have something in
>>> common. Namely, that the value type from `src_a` and `src_b` are
>>> convertible to the value type for `output`.
>>>
>>> So if you actually applied all of the constraints that your function
>>> needs, you *couldn't* use terse syntax. So this is not an example of
>>> the problem.
>>>
>>> And I think that leads to an interesting question. How often do you have
>>> a function which:
>>>
>>> 1) Takes two arguments that can be of different types.
>>>
>>> 2) Those two arguments are constrained by the same concept.
>>>
>>> 3) There are no additional constraints on those types that would prevent
>>> you from using terse syntax.
>>>
>>> Take your suggestion for `compare`. The first range and second range
>>> need not be the same types. *But*, they do need to have comparable
>>> value types. And a properly constrained template function will apply that
>>> constraint, so that users who pass the wrong things will get reasonable
>>> errors. And you can't apply such a constraint with terse syntax.
>>>
>>> I'd bet that 90% of the time that #1 and #2 are true, there's probably
>>> some additional constraint that your function requires of those two types.
>>>
>>> - But, because `Container' placed where types are placed, someone might
>>>> think that it's a type. That is confusing for that someone, lets make types
>>>> the same. - Okay, but what is about ones who is not confused, who actually
>>>> learned the language? Why make them pay and suffer? Is ones who don't
>>>> learned prioritized over ones who learned?
>>>>
>>>
>>> Why make the language more confusing to users? Why make people *have*
>>> to learn esoteric rules?
>>>
>>> *Somebody* will be inconvenienced no matter what you do. Why is your
>>> side the one that deserves to have the special syntax? Indeed, you seem to
>>> argue exactly why they shouldn't: because they're the ones who are willing
>>> to learn and use arcane rules. And therefore, they will be less
>>> inconvenienced by such arcane rules than if you do it the other way around.
>>>
>>> And how is that even possible that someone will try to use a function
>>>> like above, without actually knowing what is a `Container'?
>>>>
>>>
>>> The same way that people use std::vector without knowing that the type
>>> it takes actually has minimum requirements.
>>>
>>>
>>>> If you have a docs, you'll read that `merge' is a template function
>>>> that accepts three objects, types of which meet a requirements of the
>>>> `Container' concept. And if you doesn't have a docs you will go to source
>>>> code and see for yourself that `Container' is not a type.
>>>>
>>>> I say, there is no source of confusion. Right now, confusion is not in
>>>> the heads of a users.
>>>>
>>>> Oh, and that terse syntax hides that it's a template function. - But
>>>> that is not a problem. It is purpose of that syntax, to get rid of template
>>>> boilerplate, no?
>>>>
>>>
>>> The purpose of terse syntax is to minimize template boilerplate in the
>>> most common and useful of cases. It is not intended to be a full-fledged
>>> *replacement* for declaring template functions. There will always be
>>> cases where you need to use full template syntax.
>>>
>>> The question is why should your case be the one that gets favoritism?
>>>
>>>
>>>> I used different declaration to show that i don't need InputIterator to
>>>> force same type for begin and end, if i need same types i define them to be
>>>> the same. Just like i do right now, by the way, by writing
>>>>
>>>> template <typename I, typename O>
>>>> O copy(I begin, I end, O out)
>>>>
>>>> I don't need obscure rules to define begin and end to be of the same
>>>> type. I can use template-introduction for that, which is perfectly
>>>> suitable. And by allowing constrained parameters with same constraints be
>>>> of different types, it's will be also easier to write functions where you
>>>> just doesn't care about actual types. And if it's not enough, you always
>>>> have usual template syntax, for both cases. Cake for you, and cake for you.
>>>> Everyone is happy.
>>>>
>>>
>>> Nobody has contested that full template syntax can do either one. Nobody
>>> has suggested that having terse syntax use one way means that the other way
>>> becomes impossible.
>>>
>>> The question is who gets to use the simple syntax. Simply declaring that
>>> the other side can still use full template syntax is basically saying, "why
>>> don't you just let us win? After all, if you do, you lose."
>>>
>>> Do a lot of people find this kind of argument convincing?
>>>
>>> --
>>>
>>> ---
>>> 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-proposals+unsubscribe@isocpp.org.
>>> To post to this group, send email to std-proposals@isocpp.org.
>>> Visit this group at
>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>>
>>
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0149c3206fab6b052566c442
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Also, since type constraints now could be applied eve=
rywhere, i can declare a variable with it.<br><br><div style=3D"margin-left=
:40px">Container c;<br><br></div>Non-confused user will think that Containe=
r is a type. And what he will get if he will try to initialize it?<br><br>=
<div style=3D"margin-left:40px">Container c {1, 2, 3};<br><br></div>Compile=
r error saying something about `variable of type auto should be initialized=
with single value`? Or<br><br><div style=3D"margin-left:40px">Container c =
=3D {1, 2, 3};<br><br></div>he will end up with std::initializer_list<in=
t>?<br><br></div>Confusion about type constraints is everywhere, and sam=
e-type rule is not helping.<br></div><div class=3D"gmail_extra"><br><div cl=
ass=3D"gmail_quote">2015-11-26 5:09 GMT+05:00 Andrei L <span dir=3D"ltr">&l=
t;<a href=3D"mailto:aendaerel@gmail.com" target=3D"_blank">aendaerel@gmail.=
com</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
>When you writing a function and you make use of type constraints, and you =
decided to use terse syntax, you think, "How that object (argument) sh=
ould behave?" First thing you think about - is behavior. And when you =
choose right behavior, you think, "What about its type? Do i need thes=
e be of the same type?", not, "Do i need them to be different?&qu=
ot;. And you think that way, because you didn't specified their types, =
because you choose to use terse syntax, and same-type rule is basically say=
ing, "Oh, i see you want them to be of the same type! I'll make it=
". But no you don't, you don't want, you don't care about =
type.<br><br></div>Isn't that is how we do it in life? If we care, we t=
ake actions, we make statements, that we care, and if we don't, we do n=
othing. We don't take actions to show that we don't care, because i=
f we do something, that usually means that we care. That is what bothers me=
..<br></div><div class=3D"HOEnZb"><div class=3D"h5"><div class=3D"gmail_extr=
a"><br><div class=3D"gmail_quote">2015-11-26 4:21 GMT+05:00 Andrei L <span =
dir=3D"ltr"><<a href=3D"mailto:aendaerel@gmail.com" target=3D"_blank">ae=
ndaerel@gmail.com</a>></span>:<br><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><span><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1=
px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">I
would say that your `merge` function here is underconstrained. Why?=20
Because even if those different `Container` instances could deduce=20
different types, those three different types need to have something in=20
common. Namely, that the value type from `src_a` and `src_b` are=20
convertible to the value type for `output`.<br></blockquote><div><br></div>=
</span><div>But,
nothing was said about what is a Container, here. Maybe it's enough.=
=20
Maybe Container, it is something that can hold some type T, which can=20
hold any other type. And maybe that `merge` function is not an analogue=20
of `merge` in STL. And of course, it's not an example of perfectly=20
constrained, function. One, most probably, would need to add additional=20
requires-clause.<span><br><br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex"><div>So if you actually applied all of the constraints that your funct=
ion needs, you <i>couldn't</i> use terse syntax.<br></div></blockquote>=
<blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex" class=3D"gmail_quote"><br></blockquote></span><=
span><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex" class=3D"gmail_quote">And I think that lea=
ds to an interesting question. How often do you have a function which:<br><=
br>1) Takes two arguments that can be of different types.<br><br>2) Those t=
wo arguments are constrained by the same concept.<br><br>3) There are no ad=
ditional constraints on those types that would prevent you from using terse=
syntax.<br><br></blockquote></span></div><span><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex"><div>I'd
bet that 90% of the time that #1 and #2 are true, there's probably som=
e
additional constraint that your function requires of those two types.<br><=
/div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>=
=C2=A0 <br></div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote"><div>Take your suggestion for `compare`. The first range and second ra=
nge need not be the same types. <i>But</i>,
they do need to have comparable value types. And a properly constrained
template function will apply that constraint, so that users who pass=20
the wrong things will get reasonable errors. And you can't apply such a=
=20
constraint with terse syntax.<br></div></blockquote><div>=C2=A0</div></span=
><div>That's why i am unhappy with current situation, i can apply addit=
ional constraints.<br><br><span style=3D"font-family:monospace,monospace"><=
span>InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIter=
ator begin2)<br></span>=C2=A0 requires EquallyComparable<decltype(*begin=
1), decltype(*begin2)><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &am=
p;& /* any additional constraints */<br></span></div><div><br>and if yo=
u need and actual type of begin2, and you don't want to use decltype, y=
ou can use usual template syntax.<span><br><br><blockquote style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" =
class=3D"gmail_quote">Why make the language more confusing to users? Why ma=
ke people <i>have</i> to learn esoteric rules?<br></blockquote></span></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border=
-left:1px solid rgb(204,204,204);padding-left:1ex"><span></span></blockquot=
e><div><br></div><div>That
is why i am here! Why? Rule that is made to make me, a user, less=20
confused, made me confused even before it came into effect! <br></div><span=
><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><i=
>Somebody</i>
will be inconvenienced no matter what you do. Why is your side the one=20
that deserves to have the special syntax? Indeed, you seem to argue=20
exactly why they shouldn't: because they're the ones who are willin=
g to=20
learn and use arcane rules. And therefore, they will be less=20
inconvenienced by such arcane rules than if you do it the other way=20
around.</div></blockquote><div><br></div></span><div>That is not an arcane =
rule. Again, what concept does (should do)? It checks, that object of type =
T <i>behaves as you need</i>, not that everything that behaves the same way=
have the same type.<br><br>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks&q=
uot;?<br><br></div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
<span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>And
how is that even possible that someone will try to use a function like=20
above, without actually knowing what is a `Container'?</div></div></blo=
ckquote></span><div><br>The same way that people use std::vector without kn=
owing that the type it takes actually has minimum requirements.</div></bloc=
kquote><div><br></div></span><div>People now what std::vector is. How it be=
haves, and how to use it. To call a function F which takes object of type T=
, you <b>must</b>, know what you can pass to that function, and what you ge=
t as a result.<br></div><span><div><br><blockquote style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D=
"gmail_quote">The purpose of terse syntax is to minimize template boilerpla=
te in the most common and useful of cases.<br></blockquote></div><div><br><=
/div></span><div>One of the most common and useful of cases:<br></div><div>=
<br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,mo=
nospace">auto copy(InputIterator begin, InputIterator end, OutputIterator o=
ut) -> OutputIterator<br></span></div><div style=3D"margin-left:40px"><s=
pan style=3D"font-family:monospace,monospace">=C2=A0 requires /* ... */<br>=
</span></div></div><div><br></div><div>Is
this how it's written right now in GCC, Clang, MSVC? No (because it is=
=20
not time to rewrite it, but anyways), in GCC it is like that:<br><br><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"><=
span style=3D"color:rgb(0,0,0)">template<typename _II, typename _OI>
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> inline _OI</span></span></pre><div style=3D"margin-left:40px"><sp=
an style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0=
)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> copy(_II __first, _II __last, _OI __result)</span></span></pre><d=
iv style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospac=
e"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> {</span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> // concept requirements</span></span></pre><div style=3D"margin=
-left:40px"><span style=3D"font-family:monospace,monospace"><span style=3D"=
color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_InputIteratorConcept<_II>)</=
span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_OutputIteratorConcept<_OI,</spa=
n></span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> typename iterator_traits<_II>::value_type>)</span></spa=
n></pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospac=
e,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_requires_valid_range(__first, __last);</span></span><=
/pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,m=
onospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"><br></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> return (std::__copy_move_a2<__is_move_iterator<_II>::_=
_value></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> (std::__miter_base(__first), std::__miter_base(__last),</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __result));</span></span></pre><div style=3D"margin-left:40px=
"><span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(=
0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> }</span></span></pre><br></div><div>When GCC 6.0 will be released=
, will this function be made to use terse syntax? Or __glibcxx_* macro will=
be redefined?<br></div><div><br></div><div>What about Eric Niebler's a=
nd Casey Carter's STL2 version?<br><br><div style=3D"margin-left:40px">=
<span style=3D"font-family:monospace,monospace">template <InputIterator =
I, Sentinel<I> S, WeaklyIncrementable O><br>=C2=A0 requires<br>=C2=
=A0=C2=A0=C2=A0 models::IndirectlyCopyable<I, O><br>=C2=A0 tagged_pai=
r<tag::in(I), tag::out(O)><br>=C2=A0 copy(I first, S last, O result)<=
br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 for (; first !=3D last; ++first, ++result=
) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *result =3D *first;<br>=C2=A0=C2=A0=
=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 return {__stl2::move(first), __stl2::move(re=
sult)};<br>=C2=A0 }</span><br></div></div><div><br></div><div>It uses conce=
pts already, but, where is a terse syntax here? Is someone going to use it=
? Where is <i>the most common and useful of case</i>s applies?<br></div><di=
v><br></div><div>STL1 is not the only now, and most probably, it will not u=
se terse syntax. And rule, that i am arguing about, is for terse syntax, an=
d if it is not going to be used, for whom that rule is?<br><br><blockquote =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex" class=3D"gmail_quote"><..> to minimize template boile=
rplate <..>. It is not intended to be a full-fledged <i>replacement</=
i> for declaring template functions.<br></blockquote><br></div><div>I'm=
not suggesting to replace it. I'm saying that it could be minimized to=
the ground.<br></div><div><span><br><blockquote style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"g=
mail_quote">There will always be cases where you need to use full template =
syntax.</blockquote><div><br></div></span><div>Not arguing with that. <br><=
/div></div><span><div>=C2=A0</div><blockquote style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmai=
l_quote">Nobody has contested that full template syntax can do either one. =
Nobody has suggested that having terse syntax use one way means that the ot=
her way becomes impossible.<br></blockquote><div><br></div></span><div>Supp=
ose you writing a library with a lot of template functions. Some of them ta=
ke arguments of the same, type. Some of them not. Suppose you want to const=
rain all you functions properly, so you use terse syntax for parameters wit=
h same type and usual template syntax for parameters that share same concep=
t but not required to have same type. <br><br>Will you be writing it like t=
hat<br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace=
,monospace"><br>template <R T2></span><br></div><div style=3D"margin-=
left:40px"><span style=3D"font-family:monospace,monospace"></span></div><di=
v style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace=
">auto maybe_same(R p1, T2 p2)<br><br></span></div><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">auto same(R p1, R p=
2)<br></span></div><br></div><div>or for the sake of consistency, like that=
:<span><br><br><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace">template <R T1, R T2><br></span></div></span><div=
style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"=
>auto maybe_same(T1 p1, T2 p2)</span><br><br></div><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">template <R T>=
;<br></span></div><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace">auto same(T p1, T p2)</span><br></div></div><div><sp=
an style=3D"font-family:monospace,monospace"></span></div><div><br></div><d=
iv>?<br></div><div><br></div><div>Without same-type rule it could be writte=
n like that:<br><br><div style=3D"margin-left:40px"><span style=3D"font-fam=
ily:monospace,monospace">auto maybe_same(R p1, R p2)<br><br></span></div><s=
pan style=3D"font-family:monospace,monospace"></span><span style=3D"font-fa=
mily:monospace,monospace"></span><div style=3D"margin-left:40px"><span styl=
e=3D"font-family:monospace,monospace">R {T} auto same(T p1, T p2)</span></d=
iv></div><div><br></div><div>Aaand consistent version looks kinda, better t=
han others.. maybe just more familliar. But first version, i don't like=
it at all.<br></div></div><div><div><div class=3D"gmail_extra"><br><div cl=
ass=3D"gmail_quote">2015-11-25 12:07 GMT+05:00 Nicol Bolas <span dir=3D"ltr=
"><<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gm=
ail.com</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On Tuesday,=
November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div><blockquote style=3D"margin:0px 0=
px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=
=3D"gmail_quote">But what I said above still applies: since you used a diff=
erent declaration,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, bu=
t the only possible. And let's not forget about RangesTS, and STL2, whe=
re that "common case" is not so common.<br><br>I'm saying tha=
t type checking has nothing to do with defining parameters
of a function. It's just none of its business. User defines parameters=
.. User defines their types. User decides, if they are of the same type or n=
ot.<br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace">merge(</span><span style=3D"font-family:monospace,mon=
ospace">Container src_a, </span><span style=3D"font-family:monospace,monosp=
ace">Container src_b, Container output)</span></div><div><br></div><div>Do =
i want `src_a', `src_b' and `output' be of the same type? No.</=
div></div></blockquote></span><div><br>I would say that your `merge` functi=
on here is underconstrained. Why? Because even if those different `Containe=
r` instances could deduce different types, those three different types need=
to have something in common. Namely, that the value type from `src_a` and =
`src_b` are convertible to the value type for `output`.<br><br>So if you ac=
tually applied all of the constraints that your function needs, you <i>coul=
dn't</i> use terse syntax. So this is not an example of the problem.<br=
><br>And I think that leads to an interesting question. How often do you ha=
ve a function which:<br><br>1) Takes two arguments that can be of different=
types.<br><br>2) Those two arguments are constrained by the same concept.<=
br><br>3) There are no additional constraints on those types that would pre=
vent you from using terse syntax.<br><br>Take your suggestion for `compare`=
.. The first range and second range need not be the same types. <i>But</i>, =
they do need to have comparable value types. And a properly constrained tem=
plate function will apply that constraint, so that users who pass the wrong=
things will get reasonable errors. And you can't apply such a constrai=
nt with terse syntax.<br><br>I'd bet that 90% of the time that #1 and #=
2 are true, there's probably some additional constraint that your funct=
ion requires of those two types.<br><br><i></i></div><span><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>- But, because `Container'=
; placed where types are placed, someone might think that it's a type. =
That is confusing for that someone, lets make types the same. - Okay, but w=
hat is about ones who is not confused, who actually learned the language? W=
hy make them pay and suffer? Is ones who don't learned prioritized over=
ones who learned?<br></div></div></blockquote></span><div><br>Why make the=
language more confusing to users? Why make people <i>have</i> to learn eso=
teric rules?<br><br><i>Somebody</i> will be inconvenienced no matter what y=
ou do. Why is your side the one that deserves to have the special syntax? I=
ndeed, you seem to argue exactly why they shouldn't: because they'r=
e the ones who are willing to learn and use arcane rules. And therefore, th=
ey will be less inconvenienced by such arcane rules than if you do it the o=
ther way around.<br><br></div><span><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div>And how is that even possible that someone will try =
to use a function like above, without actually knowing what is a `Container=
'?</div></div></blockquote></span><div><br>The same way that people use=
std::vector without knowing that the type it takes actually has minimum re=
quirements.<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>If you have a docs, you'll read that `merge' is=
a template function that accepts three objects, types of which meet a requ=
irements of the `Container' concept. And if you doesn't have a docs=
you will go to source code and see for yourself that `Container' is no=
t a type.<br><br>I say, there is no source of confusion. Right now, confusi=
on is not in the heads of a users.<br></div><div><br>Oh, and that terse syn=
tax hides that it's a template function. - But that is not a problem. I=
t is purpose of that syntax, to get rid of template boilerplate, no?</div><=
/div></blockquote></span><div><br>The purpose of terse syntax is to minimiz=
e template boilerplate in the most common and useful of cases. It is not in=
tended to be a full-fledged <i>replacement</i> for declaring template funct=
ions. There will always be cases where you need to use full template syntax=
..<br><br>The question is why should your case be the one that gets favoriti=
sm?<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div><div></div><div>I used different declaration to show tha=
t i don't need InputIterator to force same type for begin and end, if i=
need same types i define them to be the same. Just like i do right now, by=
the way, by writing<br><div style=3D"margin-left:40px"><br></div><div styl=
e=3D"margin-left:40px"><font face=3D"monospace,monospace">template <type=
name I, typename O><br></font></div><div style=3D"margin-left:40px"><fon=
t face=3D"monospace,monospace">O copy(I begin, I end, O out)<br><br></font>=
</div>I don't need obscure rules to define begin and end to be of the s=
ame type. I can use template-introduction for that, which is perfectly suit=
able. And by allowing constrained parameters with same constraints be of di=
fferent types, it's will be also easier to write functions where you ju=
st doesn't care about actual types. And if it's not enough, you alw=
ays have usual template syntax, for both cases. Cake for you, and cake for =
you. Everyone is happy.<br></div></div></div></div></blockquote></span><div=
><br>Nobody has contested that full template syntax can do either one. Nobo=
dy has suggested that having terse syntax use one way means that the other =
way becomes impossible.<br><br>The question is who gets to use the simple s=
yntax. Simply declaring that the other side can still use full template syn=
tax is basically saying, "why don't you just let us win? After all=
, if you do, you lose."</div><br>Do a lot of people find this kind of =
argument convincing?<div><div><br>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0149c3206fab6b052566c442--
.
Author: tsvetan.dimitrov76@gmail.com
Date: Wed, 25 Nov 2015 17:30:26 -0800 (PST)
Raw View
------=_Part_7102_495639388.1448501426120
Content-Type: multipart/alternative;
boundary="----=_Part_7103_291376815.1448501426122"
------=_Part_7103_291376815.1448501426122
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, November 26, 2015 at 2:36:38 AM UTC+2, Andrei L wrote:
>
> Also, since type constraints now could be applied everywhere, i can=20
> declare a variable with it.
>
> Container c;
>
> Non-confused user will think that Container is a type. And what he will=
=20
> get if he will try to initialize it?
>
> Container c {1, 2, 3};
>
> Compiler error saying something about `variable of type auto should be=20
> initialized with single value`? Or
>
> Container c =3D {1, 2, 3};
>
> he will end up with std::initializer_list<int>?
>
> Confusion about type constraints is everywhere, and same-type rule is not=
=20
> helping.
>
> 2015-11-26 5:09 GMT+05:00 Andrei L <aend...@gmail.com <javascript:>>:
>
>> When you writing a function and you make use of type constraints, and yo=
u=20
>> decided to use terse syntax, you think, "How that object (argument) shou=
ld=20
>> behave?" First thing you think about - is behavior. And when you choose=
=20
>> right behavior, you think, "What about its type? Do i need these be of t=
he=20
>> same type?", not, "Do i need them to be different?". And you think that=
=20
>> way, because you didn't specified their types, because you choose to use=
=20
>> terse syntax, and same-type rule is basically saying, "Oh, i see you wan=
t=20
>> them to be of the same type! I'll make it". But no you don't, you don't=
=20
>> want, you don't care about type.
>>
>> Isn't that is how we do it in life? If we care, we take actions, we make=
=20
>> statements, that we care, and if we don't, we do nothing. We don't take=
=20
>> actions to show that we don't care, because if we do something, that=20
>> usually means that we care. That is what bothers me.
>>
>> 2015-11-26 4:21 GMT+05:00 Andrei L <aend...@gmail.com <javascript:>>:
>>
>>> I would say that your `merge` function here is underconstrained. Why?=
=20
>>>> Because even if those different `Container` instances could deduce=20
>>>> different types, those three different types need to have something in=
=20
>>>> common. Namely, that the value type from `src_a` and `src_b` are=20
>>>> convertible to the value type for `output`.
>>>>
>>>
>>> But, nothing was said about what is a Container, here. Maybe it's=20
>>> enough. Maybe Container, it is something that can hold some type T, whi=
ch=20
>>> can hold any other type. And maybe that `merge` function is not an anal=
ogue=20
>>> of `merge` in STL. And of course, it's not an example of perfectly=20
>>> constrained, function. One, most probably, would need to add additional=
=20
>>> requires-clause.
>>>
>>> So if you actually applied all of the constraints that your function=20
>>>> needs, you *couldn't* use terse syntax.
>>>>
>>>
>>>> And I think that leads to an interesting question. How often do you=20
>>>> have a function which:
>>>>
>>>> 1) Takes two arguments that can be of different types.
>>>>
>>>> 2) Those two arguments are constrained by the same concept.
>>>>
>>>> 3) There are no additional constraints on those types that would=20
>>>> prevent you from using terse syntax.
>>>>
>>>> I'd bet that 90% of the time that #1 and #2 are true, there's probably=
=20
>>>> some additional constraint that your function requires of those two ty=
pes.
>>>>
>>> =20
>>>>
>>> Take your suggestion for `compare`. The first range and second range=20
>>>> need not be the same types. *But*, they do need to have comparable=20
>>>> value types. And a properly constrained template function will apply t=
hat=20
>>>> constraint, so that users who pass the wrong things will get reasonabl=
e=20
>>>> errors. And you can't apply such a constraint with terse syntax.
>>>>
>>> =20
>>> That's why i am unhappy with current situation, i can apply additional=
=20
>>> constraints.
>>>
>>> InputIterator_Sentinel {I, S} bool compare(I begin1, S end1,=20
>>> InputIterator begin2)
>>> requires EquallyComparable<decltype(*begin1), decltype(*begin2)>
>>> && /* any additional constraints */
>>>
>>> and if you need and actual type of begin2, and you don't want to use=20
>>> decltype, you can use usual template syntax.
>>>
>>> Why make the language more confusing to users? Why make people *have*=
=20
>>>> to learn esoteric rules?
>>>>
>>>
>>> That is why i am here! Why? Rule that is made to make me, a user, less=
=20
>>> confused, made me confused even before it came into effect!=20
>>> =20
>>>
>>>> *Somebody* will be inconvenienced no matter what you do. Why is your=
=20
>>>> side the one that deserves to have the special syntax? Indeed, you see=
m to=20
>>>> argue exactly why they shouldn't: because they're the ones who are wil=
ling=20
>>>> to learn and use arcane rules. And therefore, they will be less=20
>>>> inconvenienced by such arcane rules than if you do it the other way ar=
ound.
>>>>
>>>
>>> That is not an arcane rule. Again, what concept does (should do)? It=20
>>> checks, that object of type T *behaves as you need*, not that=20
>>> everything that behaves the same way have the same type.
>>>
>>> Ducks, i brought you some amount of ducks. They look like a ducks, they=
=20
>>> quack like a ducks, and you treat them like a ducks. But then, i take d=
uck=20
>>> consumes off, and you see that this is a cat, this is a dog, and this i=
s a=20
>>> horse! And quacking sounds was made with little speakers! What you will=
do,=20
>>> put costumes back on, and say, "Nope, they're all ducks"?
>>>
>>> And how is that even possible that someone will try to use a function=
=20
>>>>> like above, without actually knowing what is a `Container'?
>>>>>
>>>>
>>>> The same way that people use std::vector without knowing that the type=
=20
>>>> it takes actually has minimum requirements.
>>>>
>>>
>>> People now what std::vector is. How it behaves, and how to use it. To=
=20
>>> call a function F which takes object of type T, you *must*, know what=
=20
>>> you can pass to that function, and what you get as a result.
>>>
>>> The purpose of terse syntax is to minimize template boilerplate in the=
=20
>>>> most common and useful of cases.
>>>>
>>>
>>> One of the most common and useful of cases:
>>>
>>> auto copy(InputIterator begin, InputIterator end, OutputIterator out) -=
>=20
>>> OutputIterator
>>> requires /* ... */
>>>
>>> Is this how it's written right now in GCC, Clang, MSVC? No (because it=
=20
>>> is not time to rewrite it, but anyways), in GCC it is like that:
>>>
>>> template<typename _II, typename _OI>=20
>>>
>>> inline _OI
>>>
>>> copy(_II __first, _II __last, _OI __result)
>>>
>>> {
>>>
>>> // concept requirements
>>>
>>> __glibcxx_function_requires(_InputIteratorConcept<_II>)
>>>
>>> __glibcxx_function_requires(_OutputIteratorConcept<_OI,
>>>
>>> typename iterator_traits<_II>::value_type>)
>>>
>>> __glibcxx_requires_valid_range(__first, __last);
>>>
>>>
>>> return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
>>>
>>> (std::__miter_base(__first), std::__miter_base(__last),
>>>
>>> __result));
>>>
>>> }
>>>
>>>
>>> When GCC 6.0 will be released, will this function be made to use terse=
=20
>>> syntax? Or __glibcxx_* macro will be redefined?
>>>
>>> What about Eric Niebler's and Casey Carter's STL2 version?
>>>
>>> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
>>> requires
>>> models::IndirectlyCopyable<I, O>
>>> tagged_pair<tag::in(I), tag::out(O)>
>>> copy(I first, S last, O result)
>>> {
>>> for (; first !=3D last; ++first, ++result) {
>>> *result =3D *first;
>>> }
>>> return {__stl2::move(first), __stl2::move(result)};
>>> }
>>>
>>> It uses concepts already, but, where is a terse syntax here? Is someone=
=20
>>> going to use it? Where is *the most common and useful of case*s applies=
?
>>>
>>> STL1 is not the only now, and most probably, it will not use terse=20
>>> syntax. And rule, that i am arguing about, is for terse syntax, and if =
it=20
>>> is not going to be used, for whom that rule is?
>>>
>>> <..> to minimize template boilerplate <..>. It is not intended to be a=
=20
>>>> full-fledged *replacement* for declaring template functions.
>>>>
>>>
>>> I'm not suggesting to replace it. I'm saying that it could be minimized=
=20
>>> to the ground.
>>>
>>> There will always be cases where you need to use full template syntax.
>>>
>>>
>>> Not arguing with that.=20
>>> =20
>>>
>>>> Nobody has contested that full template syntax can do either one.=20
>>>> Nobody has suggested that having terse syntax use one way means that t=
he=20
>>>> other way becomes impossible.
>>>>
>>>
>>> Suppose you writing a library with a lot of template functions. Some of=
=20
>>> them take arguments of the same, type. Some of them not. Suppose you wa=
nt=20
>>> to constrain all you functions properly, so you use terse syntax for=20
>>> parameters with same type and usual template syntax for parameters that=
=20
>>> share same concept but not required to have same type.=20
>>>
>>> Will you be writing it like that
>>>
>>> template <R T2>
>>> auto maybe_same(R p1, T2 p2)
>>>
>>> auto same(R p1, R p2)
>>>
>>> or for the sake of consistency, like that:
>>>
>>> template <R T1, R T2>
>>> auto maybe_same(T1 p1, T2 p2)
>>>
>>> template <R T>
>>> auto same(T p1, T p2)
>>>
>>> ?
>>>
>>> Without same-type rule it could be written like that:
>>>
>>> auto maybe_same(R p1, R p2)
>>>
>>> R {T} auto same(T p1, T p2)
>>>
>>> Aaand consistent version looks kinda, better than others.. maybe just=
=20
>>> more familliar. But first version, i don't like it at all.
>>>
>>> 2015-11-25 12:07 GMT+05:00 Nicol Bolas <jmck...@gmail.com <javascript:>=
>
>>> :
>>>
>>>> On Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:
>>>>>
>>>>> But what I said above still applies: since you used a different=20
>>>>>> declaration,
>>>>>> it does not support the argument that two InputIterator uses in the=
=20
>>>>>> same
>>>>>> declaration should be different.
>>>>>
>>>>>
>>>>> I'm not making an argument that two iterators should be different.=20
>>>>> Also, i am not talking about STL's "common case" which is not common,=
but=20
>>>>> the only possible. And let's not forget about RangesTS, and STL2, whe=
re=20
>>>>> that "common case" is not so common.
>>>>>
>>>>> I'm saying that type checking has nothing to do with defining=20
>>>>> parameters of a function. It's just none of its business. User define=
s=20
>>>>> parameters. User defines their types. User decides, if they are of th=
e same=20
>>>>> type or not.
>>>>>
>>>>> merge(Container src_a, Container src_b, Container output)
>>>>>
>>>>> Do i want `src_a', `src_b' and `output' be of the same type? No.
>>>>>
>>>>
>>>> I would say that your `merge` function here is underconstrained. Why?=
=20
>>>> Because even if those different `Container` instances could deduce=20
>>>> different types, those three different types need to have something in=
=20
>>>> common. Namely, that the value type from `src_a` and `src_b` are=20
>>>> convertible to the value type for `output`.
>>>>
>>>> So if you actually applied all of the constraints that your function=
=20
>>>> needs, you *couldn't* use terse syntax. So this is not an example of=
=20
>>>> the problem.
>>>>
>>>> And I think that leads to an interesting question. How often do you=20
>>>> have a function which:
>>>>
>>>> 1) Takes two arguments that can be of different types.
>>>>
>>>> 2) Those two arguments are constrained by the same concept.
>>>>
>>>> 3) There are no additional constraints on those types that would=20
>>>> prevent you from using terse syntax.
>>>>
>>>> Take your suggestion for `compare`. The first range and second range=
=20
>>>> need not be the same types. *But*, they do need to have comparable=20
>>>> value types. And a properly constrained template function will apply t=
hat=20
>>>> constraint, so that users who pass the wrong things will get reasonabl=
e=20
>>>> errors. And you can't apply such a constraint with terse syntax.
>>>>
>>>> I'd bet that 90% of the time that #1 and #2 are true, there's probably=
=20
>>>> some additional constraint that your function requires of those two ty=
pes.
>>>>
>>>> - But, because `Container' placed where types are placed, someone migh=
t=20
>>>>> think that it's a type. That is confusing for that someone, lets make=
types=20
>>>>> the same. - Okay, but what is about ones who is not confused, who act=
ually=20
>>>>> learned the language? Why make them pay and suffer? Is ones who don't=
=20
>>>>> learned prioritized over ones who learned?
>>>>>
>>>>
>>>> Why make the language more confusing to users? Why make people *have*=
=20
>>>> to learn esoteric rules?
>>>>
>>>> *Somebody* will be inconvenienced no matter what you do. Why is your=
=20
>>>> side the one that deserves to have the special syntax? Indeed, you see=
m to=20
>>>> argue exactly why they shouldn't: because they're the ones who are wil=
ling=20
>>>> to learn and use arcane rules. And therefore, they will be less=20
>>>> inconvenienced by such arcane rules than if you do it the other way ar=
ound.
>>>>
>>>> And how is that even possible that someone will try to use a function=
=20
>>>>> like above, without actually knowing what is a `Container'?
>>>>>
>>>>
>>>> The same way that people use std::vector without knowing that the type=
=20
>>>> it takes actually has minimum requirements.
>>>> =20
>>>>
>>>>> If you have a docs, you'll read that `merge' is a template function=
=20
>>>>> that accepts three objects, types of which meet a requirements of the=
=20
>>>>> `Container' concept. And if you doesn't have a docs you will go to so=
urce=20
>>>>> code and see for yourself that `Container' is not a type.
>>>>>
>>>>> I say, there is no source of confusion. Right now, confusion is not i=
n=20
>>>>> the heads of a users.
>>>>>
>>>>> Oh, and that terse syntax hides that it's a template function. - But=
=20
>>>>> that is not a problem. It is purpose of that syntax, to get rid of te=
mplate=20
>>>>> boilerplate, no?
>>>>>
>>>>
>>>> The purpose of terse syntax is to minimize template boilerplate in the=
=20
>>>> most common and useful of cases. It is not intended to be a full-fledg=
ed=20
>>>> *replacement* for declaring template functions. There will always be=
=20
>>>> cases where you need to use full template syntax.
>>>>
>>>> The question is why should your case be the one that gets favoritism?
>>>> =20
>>>>
>>>>> I used different declaration to show that i don't need InputIterator=
=20
>>>>> to force same type for begin and end, if i need same types i define t=
hem to=20
>>>>> be the same. Just like i do right now, by the way, by writing
>>>>>
>>>>> template <typename I, typename O>
>>>>> O copy(I begin, I end, O out)
>>>>>
>>>>> I don't need obscure rules to define begin and end to be of the same=
=20
>>>>> type. I can use template-introduction for that, which is perfectly=20
>>>>> suitable. And by allowing constrained parameters with same constraint=
s be=20
>>>>> of different types, it's will be also easier to write functions where=
you=20
>>>>> just doesn't care about actual types. And if it's not enough, you alw=
ays=20
>>>>> have usual template syntax, for both cases. Cake for you, and cake fo=
r you.=20
>>>>> Everyone is happy.
>>>>>
>>>>
>>>> Nobody has contested that full template syntax can do either one.=20
>>>> Nobody has suggested that having terse syntax use one way means that t=
he=20
>>>> other way becomes impossible.
>>>>
>>>> The question is who gets to use the simple syntax. Simply declaring=20
>>>> that the other side can still use full template syntax is basically sa=
ying,=20
>>>> "why don't you just let us win? After all, if you do, you lose."
>>>>
>>>> Do a lot of people find this kind of argument convincing?
>>>>
>>>> --=20
>>>>
>>>> ---=20
>>>> You received this message because you are subscribed to the Google=20
>>>> Groups "ISO C++ Standard - Future Proposals" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send=
=20
>>>> an email to std-proposal...@isocpp.org <javascript:>.
>>>> To post to this group, send email to std-pr...@isocpp.org <javascript:=
>
>>>> .
>>>> Visit this group at=20
>>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>>
>>>
>>>
> Not sure if it's relevant but seems that in the latest draft generic=20
lambdas non-constrained parameters are treated in exactly the opposite way=
=20
- see for example 5.1.2.5:
auto glambda =3D [](auto a, auto&& b) { return a < b; };
bool b =3D glambda(3, 3.14); // OK
auto vglambda =3D [](auto printer){
return [=3D](auto&& ... ts) { // OK: ts is a function parameter pa=
ck
printer(std::forward(ts)...);=20
return [=3D]() { printer(ts ...);=20
};=20
}; }; auto p =3D vglambda( [](auto v1, auto v2, auto v3) { std::cout << v1=
=20
<< v2 << v3; } ); auto q =3D p(1, =E2=80=99a=E2=80=99, 3.14); // OK: output=
s 1a3.14 q(); //=20
OK: outputs 1a3.14=20
Seems somewhat inconsistent to treat unconstrained types one way and=20
constrained exactly the opposite
--=20
---=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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_7103_291376815.1448501426122
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Thursday, November 26, 2015 at 2:36:38 AM UTC+2, Andrei L wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Also, si=
nce type constraints now could be applied everywhere, i can declare a varia=
ble with it.<br><br><div style=3D"margin-left:40px">Container c;<br><br></d=
iv>Non-confused user will think that Container is a type. And what he will =
get if he will try to initialize it?<br><br><div style=3D"margin-left:40px=
">Container c {1, 2, 3};<br><br></div>Compiler error saying something about=
`variable of type auto should be initialized with single value`? Or<br><br=
><div style=3D"margin-left:40px">Container c =3D {1, 2, 3};<br><br></div>he=
will end up with std::initializer_list<int>?<br><br></div>Confusion =
about type constraints is everywhere, and same-type rule is not helping.<br=
></div><div><br><div class=3D"gmail_quote">2015-11-26 5:09 GMT+05:00 Andrei=
L <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfu=
scated-mailto=3D"cPtb6XbrBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D=
'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">aend...@gmail.com</a>></span>:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div>When you writing a function and you mak=
e use of type constraints, and you decided to use terse syntax, you think, =
"How that object (argument) should behave?" First thing you think=
about - is behavior. And when you choose right behavior, you think, "=
What about its type? Do i need these be of the same type?", not, "=
;Do i need them to be different?". And you think that way, because you=
didn't specified their types, because you choose to use terse syntax, =
and same-type rule is basically saying, "Oh, i see you want them to be=
of the same type! I'll make it". But no you don't, you don=
9;t want, you don't care about type.<br><br></div>Isn't that is how=
we do it in life? If we care, we take actions, we make statements, that we=
care, and if we don't, we do nothing. We don't take actions to sho=
w that we don't care, because if we do something, that usually means th=
at we care. That is what bothers me.<br></div><div><div><div><br><div class=
=3D"gmail_quote">2015-11-26 4:21 GMT+05:00 Andrei L <span dir=3D"ltr"><<=
a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"cPtb6XbrB=
gAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';retu=
rn true;" onclick=3D"this.href=3D'javascript:';return true;">aend..=
..@gmail.com</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><span><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">I
would say that your `merge` function here is underconstrained. Why?=20
Because even if those different `Container` instances could deduce=20
different types, those three different types need to have something in=20
common. Namely, that the value type from `src_a` and `src_b` are=20
convertible to the value type for `output`.<br></blockquote><div><br></div>=
</span><div>But,
nothing was said about what is a Container, here. Maybe it's enough.=
=20
Maybe Container, it is something that can hold some type T, which can=20
hold any other type. And maybe that `merge` function is not an analogue=20
of `merge` in STL. And of course, it's not an example of perfectly=20
constrained, function. One, most probably, would need to add additional=20
requires-clause.<span><br><br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex"><div>So if you actually applied all of the constraints that your funct=
ion needs, you <i>couldn't</i> use terse syntax.<br></div></blockquote>=
<blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex" class=3D"gmail_quote"><br></blockquote></span><=
span><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex" class=3D"gmail_quote">And I think that lea=
ds to an interesting question. How often do you have a function which:<br><=
br>1) Takes two arguments that can be of different types.<br><br>2) Those t=
wo arguments are constrained by the same concept.<br><br>3) There are no ad=
ditional constraints on those types that would prevent you from using terse=
syntax.<br><br></blockquote></span></div><span><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex"><div>I'd
bet that 90% of the time that #1 and #2 are true, there's probably som=
e
additional constraint that your function requires of those two types.<br><=
/div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>=
=C2=A0 <br></div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote"><div>Take your suggestion for `compare`. The first range and second ra=
nge need not be the same types. <i>But</i>,
they do need to have comparable value types. And a properly constrained
template function will apply that constraint, so that users who pass=20
the wrong things will get reasonable errors. And you can't apply such a=
=20
constraint with terse syntax.<br></div></blockquote><div>=C2=A0</div></span=
><div>That's why i am unhappy with current situation, i can apply addit=
ional constraints.<br><br><span style=3D"font-family:monospace,monospace"><=
span>InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIter=
ator begin2)<br></span>=C2=A0 requires EquallyComparable<decltype(*<wbr>=
begin1), decltype(*begin2)><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 && /* any additional constraints */<br></span></div><div><br>an=
d if you need and actual type of begin2, and you don't want to use decl=
type, you can use usual template syntax.<span><br><br><blockquote style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex" class=3D"gmail_quote">Why make the language more confusing to users?=
Why make people <i>have</i> to learn esoteric rules?<br></blockquote></spa=
n></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span></span></bl=
ockquote><div><br></div><div>That
is why i am here! Why? Rule that is made to make me, a user, less=20
confused, made me confused even before it came into effect! <br></div><span=
><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><i=
>Somebody</i>
will be inconvenienced no matter what you do. Why is your side the one=20
that deserves to have the special syntax? Indeed, you seem to argue=20
exactly why they shouldn't: because they're the ones who are willin=
g to=20
learn and use arcane rules. And therefore, they will be less=20
inconvenienced by such arcane rules than if you do it the other way=20
around.</div></blockquote><div><br></div></span><div>That is not an arcane =
rule. Again, what concept does (should do)? It checks, that object of type =
T <i>behaves as you need</i>, not that everything that behaves the same way=
have the same type.<br><br>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks&q=
uot;?<br><br></div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
<span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>And
how is that even possible that someone will try to use a function like=20
above, without actually knowing what is a `Container'?</div></div></blo=
ckquote></span><div><br>The same way that people use std::vector without kn=
owing that the type it takes actually has minimum requirements.</div></bloc=
kquote><div><br></div></span><div>People now what std::vector is. How it be=
haves, and how to use it. To call a function F which takes object of type T=
, you <b>must</b>, know what you can pass to that function, and what you ge=
t as a result.<br></div><span><div><br><blockquote style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D=
"gmail_quote">The purpose of terse syntax is to minimize template boilerpla=
te in the most common and useful of cases.<br></blockquote></div><div><br><=
/div></span><div>One of the most common and useful of cases:<br></div><div>=
<br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,mo=
nospace">auto copy(InputIterator begin, InputIterator end, OutputIterator o=
ut) -> OutputIterator<br></span></div><div style=3D"margin-left:40px"><s=
pan style=3D"font-family:monospace,monospace">=C2=A0 requires /* ... */<br>=
</span></div></div><div><br></div><div>Is
this how it's written right now in GCC, Clang, MSVC? No (because it is=
=20
not time to rewrite it, but anyways), in GCC it is like that:<br><br><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"><=
span style=3D"color:rgb(0,0,0)">template<typename _II, typename _OI>
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> inline _OI</span></span></pre><div style=3D"margin-left:40px"><sp=
an style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0=
)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> copy(_II __first, _II __last, _OI __result)</span></span></pre><d=
iv style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospac=
e"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> {</span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> // concept requirements</span></span></pre><div style=3D"margin=
-left:40px"><span style=3D"font-family:monospace,monospace"><span style=3D"=
color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_<wbr>InputIteratorConcept<_II&g=
t;)</span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-=
family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_<wbr>OutputIteratorConcept<_OI,=
</span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-fam=
ily:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> typename iterator_traits<_II>::value_<wbr>type>)</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_requires_valid_<wbr>range(__first, __last);</span></s=
pan></pre><div style=3D"margin-left:40px"><span style=3D"font-family:monosp=
ace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"><br></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> return (std::__copy_move_a2<__is_<wbr>move_iterator<_II&g=
t;::__value></span></span></pre><div style=3D"margin-left:40px"><span st=
yle=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> (std::__miter_base(__first), std::__miter_base(__last),</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __result));</span></span></pre><div style=3D"margin-left:40px=
"><span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(=
0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> }</span></span></pre><br></div><div>When GCC 6.0 will be released=
, will this function be made to use terse syntax? Or __glibcxx_* macro will=
be redefined?<br></div><div><br></div><div>What about Eric Niebler's a=
nd Casey Carter's STL2 version?<br><br><div style=3D"margin-left:40px">=
<span style=3D"font-family:monospace,monospace">template <InputIterator =
I, Sentinel<I> S, WeaklyIncrementable O><br>=C2=A0 requires<br>=C2=
=A0=C2=A0=C2=A0 models::IndirectlyCopyable<I, O><br>=C2=A0 tagged_pai=
r<tag::in(I), tag::out(O)><br>=C2=A0 copy(I first, S last, O result)<=
br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 for (; first !=3D last; ++first, ++result=
) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *result =3D *first;<br>=C2=A0=C2=A0=
=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 return {__stl2::move(first), __stl2::move(re=
sult)};<br>=C2=A0 }</span><br></div></div><div><br></div><div>It uses conce=
pts already, but, where is a terse syntax here? Is someone going to use it=
? Where is <i>the most common and useful of case</i>s applies?<br></div><di=
v><br></div><div>STL1 is not the only now, and most probably, it will not u=
se terse syntax. And rule, that i am arguing about, is for terse syntax, an=
d if it is not going to be used, for whom that rule is?<br><br><blockquote =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex" class=3D"gmail_quote"><..> to minimize template boile=
rplate <..>. It is not intended to be a full-fledged <i>replacement</=
i> for declaring template functions.<br></blockquote><br></div><div>I'm=
not suggesting to replace it. I'm saying that it could be minimized to=
the ground.<br></div><div><span><br><blockquote style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"g=
mail_quote">There will always be cases where you need to use full template =
syntax.</blockquote><div><br></div></span><div>Not arguing with that. <br><=
/div></div><span><div>=C2=A0</div><blockquote style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmai=
l_quote">Nobody has contested that full template syntax can do either one. =
Nobody has suggested that having terse syntax use one way means that the ot=
her way becomes impossible.<br></blockquote><div><br></div></span><div>Supp=
ose you writing a library with a lot of template functions. Some of them ta=
ke arguments of the same, type. Some of them not. Suppose you want to const=
rain all you functions properly, so you use terse syntax for parameters wit=
h same type and usual template syntax for parameters that share same concep=
t but not required to have same type. <br><br>Will you be writing it like t=
hat<br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace=
,monospace"><br>template <R T2></span><br></div><div style=3D"margin-=
left:40px"><span style=3D"font-family:monospace,monospace"></span></div><di=
v style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace=
">auto maybe_same(R p1, T2 p2)<br><br></span></div><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">auto same(R p1, R p=
2)<br></span></div><br></div><div>or for the sake of consistency, like that=
:<span><br><br><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace">template <R T1, R T2><br></span></div></span><div=
style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"=
>auto maybe_same(T1 p1, T2 p2)</span><br><br></div><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">template <R T>=
;<br></span></div><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace">auto same(T p1, T p2)</span><br></div></div><div><sp=
an style=3D"font-family:monospace,monospace"></span></div><div><br></div><d=
iv>?<br></div><div><br></div><div>Without same-type rule it could be writte=
n like that:<br><br><div style=3D"margin-left:40px"><span style=3D"font-fam=
ily:monospace,monospace">auto maybe_same(R p1, R p2)<br><br></span></div><s=
pan style=3D"font-family:monospace,monospace"></span><span style=3D"font-fa=
mily:monospace,monospace"></span><div style=3D"margin-left:40px"><span styl=
e=3D"font-family:monospace,monospace">R {T} auto same(T p1, T p2)</span></d=
iv></div><div><br></div><div>Aaand consistent version looks kinda, better t=
han others.. maybe just more familliar. But first version, i don't like=
it at all.<br></div></div><div><div><div><br><div class=3D"gmail_quote">20=
15-11-25 12:07 GMT+05:00 Nicol Bolas <span dir=3D"ltr"><<a href=3D"javas=
cript:" target=3D"_blank" gdf-obfuscated-mailto=3D"cPtb6XbrBgAJ" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D'javascript:';return true;" oncli=
ck=3D"this.href=3D'javascript:';return true;">jmck...@gmail.com</a>=
></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><span>On Tuesday, November 2=
4, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div><blockquote style=3D"margin:0px 0px 0px 0.8e=
x;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_q=
uote">But what I said above still applies: since you used a different decla=
ration,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, bu=
t the only possible. And let's not forget about RangesTS, and STL2, whe=
re that "common case" is not so common.<br><br>I'm saying tha=
t type checking has nothing to do with defining parameters
of a function. It's just none of its business. User defines parameters=
.. User defines their types. User decides, if they are of the same type or n=
ot.<br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace">merge(</span><span style=3D"font-family:monospace,mon=
ospace">Container src_a, </span><span style=3D"font-family:monospace,monosp=
ace">Container src_b, Container output)</span></div><div><br></div><div>Do =
i want `src_a', `src_b' and `output' be of the same type? No.</=
div></div></blockquote></span><div><br>I would say that your `merge` functi=
on here is underconstrained. Why? Because even if those different `Containe=
r` instances could deduce different types, those three different types need=
to have something in common. Namely, that the value type from `src_a` and =
`src_b` are convertible to the value type for `output`.<br><br>So if you ac=
tually applied all of the constraints that your function needs, you <i>coul=
dn't</i> use terse syntax. So this is not an example of the problem.<br=
><br>And I think that leads to an interesting question. How often do you ha=
ve a function which:<br><br>1) Takes two arguments that can be of different=
types.<br><br>2) Those two arguments are constrained by the same concept.<=
br><br>3) There are no additional constraints on those types that would pre=
vent you from using terse syntax.<br><br>Take your suggestion for `compare`=
.. The first range and second range need not be the same types. <i>But</i>, =
they do need to have comparable value types. And a properly constrained tem=
plate function will apply that constraint, so that users who pass the wrong=
things will get reasonable errors. And you can't apply such a constrai=
nt with terse syntax.<br><br>I'd bet that 90% of the time that #1 and #=
2 are true, there's probably some additional constraint that your funct=
ion requires of those two types.<br><br><i></i></div><span><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>- But, because `Container'=
; placed where types are placed, someone might think that it's a type. =
That is confusing for that someone, lets make types the same. - Okay, but w=
hat is about ones who is not confused, who actually learned the language? W=
hy make them pay and suffer? Is ones who don't learned prioritized over=
ones who learned?<br></div></div></blockquote></span><div><br>Why make the=
language more confusing to users? Why make people <i>have</i> to learn eso=
teric rules?<br><br><i>Somebody</i> will be inconvenienced no matter what y=
ou do. Why is your side the one that deserves to have the special syntax? I=
ndeed, you seem to argue exactly why they shouldn't: because they'r=
e the ones who are willing to learn and use arcane rules. And therefore, th=
ey will be less inconvenienced by such arcane rules than if you do it the o=
ther way around.<br><br></div><span><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div>And how is that even possible that someone will try =
to use a function like above, without actually knowing what is a `Container=
'?</div></div></blockquote></span><div><br>The same way that people use=
std::vector without knowing that the type it takes actually has minimum re=
quirements.<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>If you have a docs, you'll read that `merge' is=
a template function that accepts three objects, types of which meet a requ=
irements of the `Container' concept. And if you doesn't have a docs=
you will go to source code and see for yourself that `Container' is no=
t a type.<br><br>I say, there is no source of confusion. Right now, confusi=
on is not in the heads of a users.<br></div><div><br>Oh, and that terse syn=
tax hides that it's a template function. - But that is not a problem. I=
t is purpose of that syntax, to get rid of template boilerplate, no?</div><=
/div></blockquote></span><div><br>The purpose of terse syntax is to minimiz=
e template boilerplate in the most common and useful of cases. It is not in=
tended to be a full-fledged <i>replacement</i> for declaring template funct=
ions. There will always be cases where you need to use full template syntax=
..<br><br>The question is why should your case be the one that gets favoriti=
sm?<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div><div></div><div>I used different declaration to show tha=
t i don't need InputIterator to force same type for begin and end, if i=
need same types i define them to be the same. Just like i do right now, by=
the way, by writing<br><div style=3D"margin-left:40px"><br></div><div styl=
e=3D"margin-left:40px"><font face=3D"monospace,monospace">template <type=
name I, typename O><br></font></div><div style=3D"margin-left:40px"><fon=
t face=3D"monospace,monospace">O copy(I begin, I end, O out)<br><br></font>=
</div>I don't need obscure rules to define begin and end to be of the s=
ame type. I can use template-introduction for that, which is perfectly suit=
able. And by allowing constrained parameters with same constraints be of di=
fferent types, it's will be also easier to write functions where you ju=
st doesn't care about actual types. And if it's not enough, you alw=
ays have usual template syntax, for both cases. Cake for you, and cake for =
you. Everyone is happy.<br></div></div></div></div></blockquote></span><div=
><br>Nobody has contested that full template syntax can do either one. Nobo=
dy has suggested that having terse syntax use one way means that the other =
way becomes impossible.<br><br>The question is who gets to use the simple s=
yntax. Simply declaring that the other side can still use full template syn=
tax is basically saying, "why don't you just let us win? After all=
, if you do, you lose."</div><br>Do a lot of people find this kind of =
argument convincing?<div><div><br>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
cPtb6XbrBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"cPtb6XbrBgAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
;javascript:';return true;">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';ret=
urn true;" onclick=3D"this.href=3D'http://groups.google.com/a/isocpp.or=
g/group/std-proposals/';return true;">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div></div></div></div></blockquote></div><br></d=
iv></blockquote><div>Not sure if it's relevant but seems that in the la=
test draft generic lambdas non-constrained parameters are treated in exactl=
y the opposite way - see for example 5.1.2.5:<br><br>auto glambda =3D [](au=
to a, auto&& b) { return a < b; };<br>=C2=A0bool b =3D glambda(3=
, 3.14); // OK<br>=C2=A0auto vglambda =3D [](auto printer){</div><div>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return [=3D](auto&& ... ts) { // OK:=
ts is a function parameter pack<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0printer(std::forward<decltype(ts)>(ts)...);
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return [=3D]() {
printer(ts ...);
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 };
<br>=C2=A0};
};
auto p =3D vglambda( [](auto v1, auto v2, auto v3)
{ std::cout << v1 << v2 << v3; } );
auto q =3D p(1, =E2=80=99a=E2=80=99, 3.14); // OK: outputs 1a3.14
q(); // OK: outputs 1a3.14=C2=A0<br></decltype(ts)>Seems somewhat inconsist=
ent to treat unconstrained types one way and constrained exactly the opposi=
te</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_7103_291376815.1448501426122--
------=_Part_7102_495639388.1448501426120--
.
Author: Andrei L <aendaerel@gmail.com>
Date: Thu, 26 Nov 2015 06:46:06 +0500
Raw View
--001a113b1a48050236052567bdd8
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
>
> Seems somewhat inconsistent to treat unconstrained types one way and
> constrained exactly the opposite
Yes, exactly. And given that `Constraint a` is same thing as
`Constraint<auto> a`, so type of `a` is still `auto`, inconsistency
intensifies.
2015-11-26 6:30 GMT+05:00 <tsvetan.dimitrov76@gmail.com>:
>
>
> On Thursday, November 26, 2015 at 2:36:38 AM UTC+2, Andrei L wrote:
>>
>> Also, since type constraints now could be applied everywhere, i can
>> declare a variable with it.
>>
>> Container c;
>>
>> Non-confused user will think that Container is a type. And what he will
>> get if he will try to initialize it?
>>
>> Container c {1, 2, 3};
>>
>> Compiler error saying something about `variable of type auto should be
>> initialized with single value`? Or
>>
>> Container c =3D {1, 2, 3};
>>
>> he will end up with std::initializer_list<int>?
>>
>> Confusion about type constraints is everywhere, and same-type rule is no=
t
>> helping.
>>
>> 2015-11-26 5:09 GMT+05:00 Andrei L <aend...@gmail.com>:
>>
>>> When you writing a function and you make use of type constraints, and
>>> you decided to use terse syntax, you think, "How that object (argument)
>>> should behave?" First thing you think about - is behavior. And when you
>>> choose right behavior, you think, "What about its type? Do i need these=
be
>>> of the same type?", not, "Do i need them to be different?". And you thi=
nk
>>> that way, because you didn't specified their types, because you choose =
to
>>> use terse syntax, and same-type rule is basically saying, "Oh, i see yo=
u
>>> want them to be of the same type! I'll make it". But no you don't, you
>>> don't want, you don't care about type.
>>>
>>> Isn't that is how we do it in life? If we care, we take actions, we mak=
e
>>> statements, that we care, and if we don't, we do nothing. We don't take
>>> actions to show that we don't care, because if we do something, that
>>> usually means that we care. That is what bothers me.
>>>
>>> 2015-11-26 4:21 GMT+05:00 Andrei L <aend...@gmail.com>:
>>>
>>>> I would say that your `merge` function here is underconstrained. Why?
>>>>> Because even if those different `Container` instances could deduce
>>>>> different types, those three different types need to have something i=
n
>>>>> common. Namely, that the value type from `src_a` and `src_b` are
>>>>> convertible to the value type for `output`.
>>>>>
>>>>
>>>> But, nothing was said about what is a Container, here. Maybe it's
>>>> enough. Maybe Container, it is something that can hold some type T, wh=
ich
>>>> can hold any other type. And maybe that `merge` function is not an ana=
logue
>>>> of `merge` in STL. And of course, it's not an example of perfectly
>>>> constrained, function. One, most probably, would need to add additiona=
l
>>>> requires-clause.
>>>>
>>>> So if you actually applied all of the constraints that your function
>>>>> needs, you *couldn't* use terse syntax.
>>>>>
>>>>
>>>>> And I think that leads to an interesting question. How often do you
>>>>> have a function which:
>>>>>
>>>>> 1) Takes two arguments that can be of different types.
>>>>>
>>>>> 2) Those two arguments are constrained by the same concept.
>>>>>
>>>>> 3) There are no additional constraints on those types that would
>>>>> prevent you from using terse syntax.
>>>>>
>>>>> I'd bet that 90% of the time that #1 and #2 are true, there's probabl=
y
>>>>> some additional constraint that your function requires of those two t=
ypes.
>>>>>
>>>>
>>>>>
>>>> Take your suggestion for `compare`. The first range and second range
>>>>> need not be the same types. *But*, they do need to have comparable
>>>>> value types. And a properly constrained template function will apply =
that
>>>>> constraint, so that users who pass the wrong things will get reasonab=
le
>>>>> errors. And you can't apply such a constraint with terse syntax.
>>>>>
>>>>
>>>> That's why i am unhappy with current situation, i can apply additional
>>>> constraints.
>>>>
>>>> InputIterator_Sentinel {I, S} bool compare(I begin1, S end1,
>>>> InputIterator begin2)
>>>> requires EquallyComparable<decltype(*begin1), decltype(*begin2)>
>>>> && /* any additional constraints */
>>>>
>>>> and if you need and actual type of begin2, and you don't want to use
>>>> decltype, you can use usual template syntax.
>>>>
>>>> Why make the language more confusing to users? Why make people *have*
>>>>> to learn esoteric rules?
>>>>>
>>>>
>>>> That is why i am here! Why? Rule that is made to make me, a user, less
>>>> confused, made me confused even before it came into effect!
>>>>
>>>>
>>>>> *Somebody* will be inconvenienced no matter what you do. Why is your
>>>>> side the one that deserves to have the special syntax? Indeed, you se=
em to
>>>>> argue exactly why they shouldn't: because they're the ones who are wi=
lling
>>>>> to learn and use arcane rules. And therefore, they will be less
>>>>> inconvenienced by such arcane rules than if you do it the other way a=
round.
>>>>>
>>>>
>>>> That is not an arcane rule. Again, what concept does (should do)? It
>>>> checks, that object of type T *behaves as you need*, not that
>>>> everything that behaves the same way have the same type.
>>>>
>>>> Ducks, i brought you some amount of ducks. They look like a ducks, the=
y
>>>> quack like a ducks, and you treat them like a ducks. But then, i take =
duck
>>>> consumes off, and you see that this is a cat, this is a dog, and this =
is a
>>>> horse! And quacking sounds was made with little speakers! What you wil=
l do,
>>>> put costumes back on, and say, "Nope, they're all ducks"?
>>>>
>>>> And how is that even possible that someone will try to use a function
>>>>>> like above, without actually knowing what is a `Container'?
>>>>>>
>>>>>
>>>>> The same way that people use std::vector without knowing that the typ=
e
>>>>> it takes actually has minimum requirements.
>>>>>
>>>>
>>>> People now what std::vector is. How it behaves, and how to use it. To
>>>> call a function F which takes object of type T, you *must*, know what
>>>> you can pass to that function, and what you get as a result.
>>>>
>>>> The purpose of terse syntax is to minimize template boilerplate in the
>>>>> most common and useful of cases.
>>>>>
>>>>
>>>> One of the most common and useful of cases:
>>>>
>>>> auto copy(InputIterator begin, InputIterator end, OutputIterator out)
>>>> -> OutputIterator
>>>> requires /* ... */
>>>>
>>>> Is this how it's written right now in GCC, Clang, MSVC? No (because it
>>>> is not time to rewrite it, but anyways), in GCC it is like that:
>>>>
>>>> template<typename _II, typename _OI>
>>>>
>>>> inline _OI
>>>>
>>>> copy(_II __first, _II __last, _OI __result)
>>>>
>>>> {
>>>>
>>>> // concept requirements
>>>>
>>>> __glibcxx_function_requires(_InputIteratorConcept<_II>)
>>>>
>>>> __glibcxx_function_requires(_OutputIteratorConcept<_OI,
>>>>
>>>> typename iterator_traits<_II>::value_type>)
>>>>
>>>> __glibcxx_requires_valid_range(__first, __last);
>>>>
>>>>
>>>> return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
>>>>
>>>> (std::__miter_base(__first), std::__miter_base(__last),
>>>>
>>>> __result));
>>>>
>>>> }
>>>>
>>>>
>>>> When GCC 6.0 will be released, will this function be made to use terse
>>>> syntax? Or __glibcxx_* macro will be redefined?
>>>>
>>>> What about Eric Niebler's and Casey Carter's STL2 version?
>>>>
>>>> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
>>>> requires
>>>> models::IndirectlyCopyable<I, O>
>>>> tagged_pair<tag::in(I), tag::out(O)>
>>>> copy(I first, S last, O result)
>>>> {
>>>> for (; first !=3D last; ++first, ++result) {
>>>> *result =3D *first;
>>>> }
>>>> return {__stl2::move(first), __stl2::move(result)};
>>>> }
>>>>
>>>> It uses concepts already, but, where is a terse syntax here? Is someon=
e
>>>> going to use it? Where is *the most common and useful of case*s
>>>> applies?
>>>>
>>>> STL1 is not the only now, and most probably, it will not use terse
>>>> syntax. And rule, that i am arguing about, is for terse syntax, and if=
it
>>>> is not going to be used, for whom that rule is?
>>>>
>>>> <..> to minimize template boilerplate <..>. It is not intended to be a
>>>>> full-fledged *replacement* for declaring template functions.
>>>>>
>>>>
>>>> I'm not suggesting to replace it. I'm saying that it could be minimize=
d
>>>> to the ground.
>>>>
>>>> There will always be cases where you need to use full template syntax.
>>>>
>>>>
>>>> Not arguing with that.
>>>>
>>>>
>>>>> Nobody has contested that full template syntax can do either one.
>>>>> Nobody has suggested that having terse syntax use one way means that =
the
>>>>> other way becomes impossible.
>>>>>
>>>>
>>>> Suppose you writing a library with a lot of template functions. Some o=
f
>>>> them take arguments of the same, type. Some of them not. Suppose you w=
ant
>>>> to constrain all you functions properly, so you use terse syntax for
>>>> parameters with same type and usual template syntax for parameters tha=
t
>>>> share same concept but not required to have same type.
>>>>
>>>> Will you be writing it like that
>>>>
>>>> template <R T2>
>>>> auto maybe_same(R p1, T2 p2)
>>>>
>>>> auto same(R p1, R p2)
>>>>
>>>> or for the sake of consistency, like that:
>>>>
>>>> template <R T1, R T2>
>>>> auto maybe_same(T1 p1, T2 p2)
>>>>
>>>> template <R T>
>>>> auto same(T p1, T p2)
>>>>
>>>> ?
>>>>
>>>> Without same-type rule it could be written like that:
>>>>
>>>> auto maybe_same(R p1, R p2)
>>>>
>>>> R {T} auto same(T p1, T p2)
>>>>
>>>> Aaand consistent version looks kinda, better than others.. maybe just
>>>> more familliar. But first version, i don't like it at all.
>>>>
>>>> 2015-11-25 12:07 GMT+05:00 Nicol Bolas <jmck...@gmail.com>:
>>>>
>>>>> On Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:
>>>>>>
>>>>>> But what I said above still applies: since you used a different
>>>>>>> declaration,
>>>>>>> it does not support the argument that two InputIterator uses in the
>>>>>>> same
>>>>>>> declaration should be different.
>>>>>>
>>>>>>
>>>>>> I'm not making an argument that two iterators should be different.
>>>>>> Also, i am not talking about STL's "common case" which is not common=
, but
>>>>>> the only possible. And let's not forget about RangesTS, and STL2, wh=
ere
>>>>>> that "common case" is not so common.
>>>>>>
>>>>>> I'm saying that type checking has nothing to do with defining
>>>>>> parameters of a function. It's just none of its business. User defin=
es
>>>>>> parameters. User defines their types. User decides, if they are of t=
he same
>>>>>> type or not.
>>>>>>
>>>>>> merge(Container src_a, Container src_b, Container output)
>>>>>>
>>>>>> Do i want `src_a', `src_b' and `output' be of the same type? No.
>>>>>>
>>>>>
>>>>> I would say that your `merge` function here is underconstrained. Why?
>>>>> Because even if those different `Container` instances could deduce
>>>>> different types, those three different types need to have something i=
n
>>>>> common. Namely, that the value type from `src_a` and `src_b` are
>>>>> convertible to the value type for `output`.
>>>>>
>>>>> So if you actually applied all of the constraints that your function
>>>>> needs, you *couldn't* use terse syntax. So this is not an example of
>>>>> the problem.
>>>>>
>>>>> And I think that leads to an interesting question. How often do you
>>>>> have a function which:
>>>>>
>>>>> 1) Takes two arguments that can be of different types.
>>>>>
>>>>> 2) Those two arguments are constrained by the same concept.
>>>>>
>>>>> 3) There are no additional constraints on those types that would
>>>>> prevent you from using terse syntax.
>>>>>
>>>>> Take your suggestion for `compare`. The first range and second range
>>>>> need not be the same types. *But*, they do need to have comparable
>>>>> value types. And a properly constrained template function will apply =
that
>>>>> constraint, so that users who pass the wrong things will get reasonab=
le
>>>>> errors. And you can't apply such a constraint with terse syntax.
>>>>>
>>>>> I'd bet that 90% of the time that #1 and #2 are true, there's probabl=
y
>>>>> some additional constraint that your function requires of those two t=
ypes.
>>>>>
>>>>> - But, because `Container' placed where types are placed, someone
>>>>>> might think that it's a type. That is confusing for that someone, le=
ts make
>>>>>> types the same. - Okay, but what is about ones who is not confused, =
who
>>>>>> actually learned the language? Why make them pay and suffer? Is ones=
who
>>>>>> don't learned prioritized over ones who learned?
>>>>>>
>>>>>
>>>>> Why make the language more confusing to users? Why make people *have*
>>>>> to learn esoteric rules?
>>>>>
>>>>> *Somebody* will be inconvenienced no matter what you do. Why is your
>>>>> side the one that deserves to have the special syntax? Indeed, you se=
em to
>>>>> argue exactly why they shouldn't: because they're the ones who are wi=
lling
>>>>> to learn and use arcane rules. And therefore, they will be less
>>>>> inconvenienced by such arcane rules than if you do it the other way a=
round.
>>>>>
>>>>> And how is that even possible that someone will try to use a function
>>>>>> like above, without actually knowing what is a `Container'?
>>>>>>
>>>>>
>>>>> The same way that people use std::vector without knowing that the typ=
e
>>>>> it takes actually has minimum requirements.
>>>>>
>>>>>
>>>>>> If you have a docs, you'll read that `merge' is a template function
>>>>>> that accepts three objects, types of which meet a requirements of th=
e
>>>>>> `Container' concept. And if you doesn't have a docs you will go to s=
ource
>>>>>> code and see for yourself that `Container' is not a type.
>>>>>>
>>>>>> I say, there is no source of confusion. Right now, confusion is not
>>>>>> in the heads of a users.
>>>>>>
>>>>>> Oh, and that terse syntax hides that it's a template function. - But
>>>>>> that is not a problem. It is purpose of that syntax, to get rid of t=
emplate
>>>>>> boilerplate, no?
>>>>>>
>>>>>
>>>>> The purpose of terse syntax is to minimize template boilerplate in th=
e
>>>>> most common and useful of cases. It is not intended to be a full-fled=
ged
>>>>> *replacement* for declaring template functions. There will always be
>>>>> cases where you need to use full template syntax.
>>>>>
>>>>> The question is why should your case be the one that gets favoritism?
>>>>>
>>>>>
>>>>>> I used different declaration to show that i don't need InputIterator
>>>>>> to force same type for begin and end, if i need same types i define =
them to
>>>>>> be the same. Just like i do right now, by the way, by writing
>>>>>>
>>>>>> template <typename I, typename O>
>>>>>> O copy(I begin, I end, O out)
>>>>>>
>>>>>> I don't need obscure rules to define begin and end to be of the same
>>>>>> type. I can use template-introduction for that, which is perfectly
>>>>>> suitable. And by allowing constrained parameters with same constrain=
ts be
>>>>>> of different types, it's will be also easier to write functions wher=
e you
>>>>>> just doesn't care about actual types. And if it's not enough, you al=
ways
>>>>>> have usual template syntax, for both cases. Cake for you, and cake f=
or you.
>>>>>> Everyone is happy.
>>>>>>
>>>>>
>>>>> Nobody has contested that full template syntax can do either one.
>>>>> Nobody has suggested that having terse syntax use one way means that =
the
>>>>> other way becomes impossible.
>>>>>
>>>>> The question is who gets to use the simple syntax. Simply declaring
>>>>> that the other side can still use full template syntax is basically s=
aying,
>>>>> "why don't you just let us win? After all, if you do, you lose."
>>>>>
>>>>> Do a lot of people find this kind of argument convincing?
>>>>>
>>>>> --
>>>>>
>>>>> ---
>>>>> 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, sen=
d
>>>>> an email to std-proposal...@isocpp.org.
>>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>>> Visit this group at
>>>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>>>
>>>>
>>>>
>> Not sure if it's relevant but seems that in the latest draft generic
> lambdas non-constrained parameters are treated in exactly the opposite wa=
y
> - see for example 5.1.2.5:
>
> auto glambda =3D [](auto a, auto&& b) { return a < b; };
> bool b =3D glambda(3, 3.14); // OK
> auto vglambda =3D [](auto printer){
> return [=3D](auto&& ... ts) { // OK: ts is a function parameter =
pack
> printer(std::forward(ts)...);
> return [=3D]() { printer(ts ...);
> };
> }; }; auto p =3D vglambda( [](auto v1, auto v2, auto v3) { std::cout << =
v1
> << v2 << v3; } ); auto q =3D p(1, =E2=80=99a=E2=80=99, 3.14); // OK: outp=
uts 1a3.14 q(); //
> OK: outputs 1a3.14
> Seems somewhat inconsistent to treat unconstrained types one way and
> constrained exactly the opposite
>
> --
>
> ---
> 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-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a113b1a48050236052567bdd8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">Seems so=
mewhat inconsistent to treat unconstrained types one way and constrained ex=
actly the opposite</blockquote><div><br>Yes, exactly. And given that `Const=
raint a` is same thing as `Constraint<auto> a`, so type of `a` is sti=
ll `auto`, inconsistency intensifies.<br></div></div><div class=3D"gmail_ex=
tra"><br><div class=3D"gmail_quote">2015-11-26 6:30 GMT+05:00 <span dir=3D=
"ltr"><<a href=3D"mailto:tsvetan.dimitrov76@gmail.com" target=3D"_blank"=
>tsvetan.dimitrov76@gmail.com</a>></span>:<br><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex"><span class=3D""><br><br>On Thursday, November 26, 2015 at 2:36:38 AM =
UTC+2, Andrei L wrote:</span><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><span =
class=3D""><div dir=3D"ltr"><div>Also, since type constraints now could be =
applied everywhere, i can declare a variable with it.<br><br><div style=3D"=
margin-left:40px">Container c;<br><br></div>Non-confused user will think th=
at Container is a type. And what he will get if he will try to initialize =
it?<br><br><div style=3D"margin-left:40px">Container c {1, 2, 3};<br><br></=
div>Compiler error saying something about `variable of type auto should be =
initialized with single value`? Or<br><br><div style=3D"margin-left:40px">C=
ontainer c =3D {1, 2, 3};<br><br></div>he will end up with std::initializer=
_list<int>?<br><br></div>Confusion about type constraints is everywhe=
re, and same-type rule is not helping.<br></div></span><div><br><div class=
=3D"gmail_quote"><span class=3D"">2015-11-26 5:09 GMT+05:00 Andrei L <span =
dir=3D"ltr"><<a rel=3D"nofollow">aend...@gmail.com</a>></span>:<br></=
span><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><span class=3D""><div dir=3D"ltr"><div>=
When you writing a function and you make use of type constraints, and you d=
ecided to use terse syntax, you think, "How that object (argument) sho=
uld behave?" First thing you think about - is behavior. And when you c=
hoose right behavior, you think, "What about its type? Do i need these=
be of the same type?", not, "Do i need them to be different?&quo=
t;. And you think that way, because you didn't specified their types, b=
ecause you choose to use terse syntax, and same-type rule is basically sayi=
ng, "Oh, i see you want them to be of the same type! I'll make it&=
quot;. But no you don't, you don't want, you don't care about t=
ype.<br><br></div>Isn't that is how we do it in life? If we care, we ta=
ke actions, we make statements, that we care, and if we don't, we do no=
thing. We don't take actions to show that we don't care, because if=
we do something, that usually means that we care. That is what bothers me.=
<br></div></span><div><div><div><br><div class=3D"gmail_quote"><div><div cl=
ass=3D"h5">2015-11-26 4:21 GMT+05:00 Andrei L <span dir=3D"ltr"><<a rel=
=3D"nofollow">aend...@gmail.com</a>></span>:<br></div></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div><div class=3D"h5"><div dir=3D"ltr"><span><blockquot=
e style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);=
padding-left:1ex" class=3D"gmail_quote">I
would say that your `merge` function here is underconstrained. Why?=20
Because even if those different `Container` instances could deduce=20
different types, those three different types need to have something in=20
common. Namely, that the value type from `src_a` and `src_b` are=20
convertible to the value type for `output`.<br></blockquote><div><br></div>=
</span><div>But,
nothing was said about what is a Container, here. Maybe it's enough.=
=20
Maybe Container, it is something that can hold some type T, which can=20
hold any other type. And maybe that `merge` function is not an analogue=20
of `merge` in STL. And of course, it's not an example of perfectly=20
constrained, function. One, most probably, would need to add additional=20
requires-clause.<span><br><br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex"><div>So if you actually applied all of the constraints that your funct=
ion needs, you <i>couldn't</i> use terse syntax.<br></div></blockquote>=
<blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex" class=3D"gmail_quote"><br></blockquote></span><=
span><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex" class=3D"gmail_quote">And I think that lea=
ds to an interesting question. How often do you have a function which:<br><=
br>1) Takes two arguments that can be of different types.<br><br>2) Those t=
wo arguments are constrained by the same concept.<br><br>3) There are no ad=
ditional constraints on those types that would prevent you from using terse=
syntax.<br><br></blockquote></span></div><span><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex"><div>I'd
bet that 90% of the time that #1 and #2 are true, there's probably som=
e
additional constraint that your function requires of those two types.<br><=
/div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>=
=C2=A0 <br></div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote"><div>Take your suggestion for `compare`. The first range and second ra=
nge need not be the same types. <i>But</i>,
they do need to have comparable value types. And a properly constrained
template function will apply that constraint, so that users who pass=20
the wrong things will get reasonable errors. And you can't apply such a=
=20
constraint with terse syntax.<br></div></blockquote><div>=C2=A0</div></span=
><div>That's why i am unhappy with current situation, i can apply addit=
ional constraints.<br><br><span style=3D"font-family:monospace,monospace"><=
span>InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIter=
ator begin2)<br></span>=C2=A0 requires EquallyComparable<decltype(*begin=
1), decltype(*begin2)><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &am=
p;& /* any additional constraints */<br></span></div><div><br>and if yo=
u need and actual type of begin2, and you don't want to use decltype, y=
ou can use usual template syntax.<span><br><br><blockquote style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" =
class=3D"gmail_quote">Why make the language more confusing to users? Why ma=
ke people <i>have</i> to learn esoteric rules?<br></blockquote></span></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border=
-left:1px solid rgb(204,204,204);padding-left:1ex"><span></span></blockquot=
e><div><br></div><div>That
is why i am here! Why? Rule that is made to make me, a user, less=20
confused, made me confused even before it came into effect! <br></div><span=
><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><i=
>Somebody</i>
will be inconvenienced no matter what you do. Why is your side the one=20
that deserves to have the special syntax? Indeed, you seem to argue=20
exactly why they shouldn't: because they're the ones who are willin=
g to=20
learn and use arcane rules. And therefore, they will be less=20
inconvenienced by such arcane rules than if you do it the other way=20
around.</div></blockquote><div><br></div></span><div>That is not an arcane =
rule. Again, what concept does (should do)? It checks, that object of type =
T <i>behaves as you need</i>, not that everything that behaves the same way=
have the same type.<br><br>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks&q=
uot;?<br><br></div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
<span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>And
how is that even possible that someone will try to use a function like=20
above, without actually knowing what is a `Container'?</div></div></blo=
ckquote></span><div><br>The same way that people use std::vector without kn=
owing that the type it takes actually has minimum requirements.</div></bloc=
kquote><div><br></div></span><div>People now what std::vector is. How it be=
haves, and how to use it. To call a function F which takes object of type T=
, you <b>must</b>, know what you can pass to that function, and what you ge=
t as a result.<br></div><span><div><br><blockquote style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D=
"gmail_quote">The purpose of terse syntax is to minimize template boilerpla=
te in the most common and useful of cases.<br></blockquote></div><div><br><=
/div></span><div>One of the most common and useful of cases:<br></div><div>=
<br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,mo=
nospace">auto copy(InputIterator begin, InputIterator end, OutputIterator o=
ut) -> OutputIterator<br></span></div><div style=3D"margin-left:40px"><s=
pan style=3D"font-family:monospace,monospace">=C2=A0 requires /* ... */<br>=
</span></div></div><div><br></div><div>Is
this how it's written right now in GCC, Clang, MSVC? No (because it is=
=20
not time to rewrite it, but anyways), in GCC it is like that:<br><br><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"><=
span style=3D"color:rgb(0,0,0)">template<typename _II, typename _OI>
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> inline _OI</span></span></pre><div style=3D"margin-left:40px"><sp=
an style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0=
)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> copy(_II __first, _II __last, _OI __result)</span></span></pre><d=
iv style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospac=
e"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> {</span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> // concept requirements</span></span></pre><div style=3D"margin=
-left:40px"><span style=3D"font-family:monospace,monospace"><span style=3D"=
color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_InputIteratorConcept<_II>)</=
span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_OutputIteratorConcept<_OI,</spa=
n></span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> typename iterator_traits<_II>::value_type>)</span></spa=
n></pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospac=
e,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_requires_valid_range(__first, __last);</span></span><=
/pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,m=
onospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"><br></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> return (std::__copy_move_a2<__is_move_iterator<_II>::_=
_value></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> (std::__miter_base(__first), std::__miter_base(__last),</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __result));</span></span></pre><div style=3D"margin-left:40px=
"><span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(=
0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> }</span></span></pre><br></div><div>When GCC 6.0 will be released=
, will this function be made to use terse syntax? Or __glibcxx_* macro will=
be redefined?<br></div><div><br></div><div>What about Eric Niebler's a=
nd Casey Carter's STL2 version?<br><br><div style=3D"margin-left:40px">=
<span style=3D"font-family:monospace,monospace">template <InputIterator =
I, Sentinel<I> S, WeaklyIncrementable O><br>=C2=A0 requires<br>=C2=
=A0=C2=A0=C2=A0 models::IndirectlyCopyable<I, O><br>=C2=A0 tagged_pai=
r<tag::in(I), tag::out(O)><br>=C2=A0 copy(I first, S last, O result)<=
br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 for (; first !=3D last; ++first, ++result=
) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *result =3D *first;<br>=C2=A0=C2=A0=
=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 return {__stl2::move(first), __stl2::move(re=
sult)};<br>=C2=A0 }</span><br></div></div><div><br></div><div>It uses conce=
pts already, but, where is a terse syntax here? Is someone going to use it=
? Where is <i>the most common and useful of case</i>s applies?<br></div><di=
v><br></div><div>STL1 is not the only now, and most probably, it will not u=
se terse syntax. And rule, that i am arguing about, is for terse syntax, an=
d if it is not going to be used, for whom that rule is?<br><br><blockquote =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex" class=3D"gmail_quote"><..> to minimize template boile=
rplate <..>. It is not intended to be a full-fledged <i>replacement</=
i> for declaring template functions.<br></blockquote><br></div><div>I'm=
not suggesting to replace it. I'm saying that it could be minimized to=
the ground.<br></div><div><span><br><blockquote style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"g=
mail_quote">There will always be cases where you need to use full template =
syntax.</blockquote><div><br></div></span><div>Not arguing with that. <br><=
/div></div><span><div>=C2=A0</div><blockquote style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmai=
l_quote">Nobody has contested that full template syntax can do either one. =
Nobody has suggested that having terse syntax use one way means that the ot=
her way becomes impossible.<br></blockquote><div><br></div></span><div>Supp=
ose you writing a library with a lot of template functions. Some of them ta=
ke arguments of the same, type. Some of them not. Suppose you want to const=
rain all you functions properly, so you use terse syntax for parameters wit=
h same type and usual template syntax for parameters that share same concep=
t but not required to have same type. <br><br>Will you be writing it like t=
hat<br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace=
,monospace"><br>template <R T2></span><br></div><div style=3D"margin-=
left:40px"><span style=3D"font-family:monospace,monospace"></span></div><di=
v style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace=
">auto maybe_same(R p1, T2 p2)<br><br></span></div><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">auto same(R p1, R p=
2)<br></span></div><br></div><div>or for the sake of consistency, like that=
:<span><br><br><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace">template <R T1, R T2><br></span></div></span><div=
style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"=
>auto maybe_same(T1 p1, T2 p2)</span><br><br></div><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">template <R T>=
;<br></span></div><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace">auto same(T p1, T p2)</span><br></div></div><div><sp=
an style=3D"font-family:monospace,monospace"></span></div><div><br></div><d=
iv>?<br></div><div><br></div><div>Without same-type rule it could be writte=
n like that:<br><br><div style=3D"margin-left:40px"><span style=3D"font-fam=
ily:monospace,monospace">auto maybe_same(R p1, R p2)<br><br></span></div><s=
pan style=3D"font-family:monospace,monospace"></span><span style=3D"font-fa=
mily:monospace,monospace"></span><div style=3D"margin-left:40px"><span styl=
e=3D"font-family:monospace,monospace">R {T} auto same(T p1, T p2)</span></d=
iv></div><div><br></div><div>Aaand consistent version looks kinda, better t=
han others.. maybe just more familliar. But first version, i don't like=
it at all.<br></div></div></div></div><div><div><div><br><div class=3D"gma=
il_quote"><div><div class=3D"h5">2015-11-25 12:07 GMT+05:00 Nicol Bolas <sp=
an dir=3D"ltr"><<a rel=3D"nofollow">jmck...@gmail.com</a>></span>:<br=
></div></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div><div class=3D"h5"><span>On=
Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:<blockquote=
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px =
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><blockquote style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1=
ex" class=3D"gmail_quote">But what I said above still applies: since you us=
ed a different declaration,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, bu=
t the only possible. And let's not forget about RangesTS, and STL2, whe=
re that "common case" is not so common.<br><br>I'm saying tha=
t type checking has nothing to do with defining parameters
of a function. It's just none of its business. User defines parameters=
.. User defines their types. User decides, if they are of the same type or n=
ot.<br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace">merge(</span><span style=3D"font-family:monospace,mon=
ospace">Container src_a, </span><span style=3D"font-family:monospace,monosp=
ace">Container src_b, Container output)</span></div><div><br></div><div>Do =
i want `src_a', `src_b' and `output' be of the same type? No.</=
div></div></blockquote></span><div><br>I would say that your `merge` functi=
on here is underconstrained. Why? Because even if those different `Containe=
r` instances could deduce different types, those three different types need=
to have something in common. Namely, that the value type from `src_a` and =
`src_b` are convertible to the value type for `output`.<br><br>So if you ac=
tually applied all of the constraints that your function needs, you <i>coul=
dn't</i> use terse syntax. So this is not an example of the problem.<br=
><br>And I think that leads to an interesting question. How often do you ha=
ve a function which:<br><br>1) Takes two arguments that can be of different=
types.<br><br>2) Those two arguments are constrained by the same concept.<=
br><br>3) There are no additional constraints on those types that would pre=
vent you from using terse syntax.<br><br>Take your suggestion for `compare`=
.. The first range and second range need not be the same types. <i>But</i>, =
they do need to have comparable value types. And a properly constrained tem=
plate function will apply that constraint, so that users who pass the wrong=
things will get reasonable errors. And you can't apply such a constrai=
nt with terse syntax.<br><br>I'd bet that 90% of the time that #1 and #=
2 are true, there's probably some additional constraint that your funct=
ion requires of those two types.<br><br><i></i></div><span><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>- But, because `Container'=
; placed where types are placed, someone might think that it's a type. =
That is confusing for that someone, lets make types the same. - Okay, but w=
hat is about ones who is not confused, who actually learned the language? W=
hy make them pay and suffer? Is ones who don't learned prioritized over=
ones who learned?<br></div></div></blockquote></span><div><br>Why make the=
language more confusing to users? Why make people <i>have</i> to learn eso=
teric rules?<br><br><i>Somebody</i> will be inconvenienced no matter what y=
ou do. Why is your side the one that deserves to have the special syntax? I=
ndeed, you seem to argue exactly why they shouldn't: because they'r=
e the ones who are willing to learn and use arcane rules. And therefore, th=
ey will be less inconvenienced by such arcane rules than if you do it the o=
ther way around.<br><br></div><span><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div>And how is that even possible that someone will try =
to use a function like above, without actually knowing what is a `Container=
'?</div></div></blockquote></span><div><br>The same way that people use=
std::vector without knowing that the type it takes actually has minimum re=
quirements.<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>If you have a docs, you'll read that `merge' is=
a template function that accepts three objects, types of which meet a requ=
irements of the `Container' concept. And if you doesn't have a docs=
you will go to source code and see for yourself that `Container' is no=
t a type.<br><br>I say, there is no source of confusion. Right now, confusi=
on is not in the heads of a users.<br></div><div><br>Oh, and that terse syn=
tax hides that it's a template function. - But that is not a problem. I=
t is purpose of that syntax, to get rid of template boilerplate, no?</div><=
/div></blockquote></span><div><br>The purpose of terse syntax is to minimiz=
e template boilerplate in the most common and useful of cases. It is not in=
tended to be a full-fledged <i>replacement</i> for declaring template funct=
ions. There will always be cases where you need to use full template syntax=
..<br><br>The question is why should your case be the one that gets favoriti=
sm?<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div><div></div><div>I used different declaration to show tha=
t i don't need InputIterator to force same type for begin and end, if i=
need same types i define them to be the same. Just like i do right now, by=
the way, by writing<br><div style=3D"margin-left:40px"><br></div><div styl=
e=3D"margin-left:40px"><font face=3D"monospace,monospace">template <type=
name I, typename O><br></font></div><div style=3D"margin-left:40px"><fon=
t face=3D"monospace,monospace">O copy(I begin, I end, O out)<br><br></font>=
</div>I don't need obscure rules to define begin and end to be of the s=
ame type. I can use template-introduction for that, which is perfectly suit=
able. And by allowing constrained parameters with same constraints be of di=
fferent types, it's will be also easier to write functions where you ju=
st doesn't care about actual types. And if it's not enough, you alw=
ays have usual template syntax, for both cases. Cake for you, and cake for =
you. Everyone is happy.<br></div></div></div></div></blockquote></span><div=
><br>Nobody has contested that full template syntax can do either one. Nobo=
dy has suggested that having terse syntax use one way means that the other =
way becomes impossible.<br><br>The question is who gets to use the simple s=
yntax. Simply declaring that the other side can still use full template syn=
tax is basically saying, "why don't you just let us win? After all=
, if you do, you lose."</div><br>Do a lot of people find this kind of =
argument convincing?</div></div><div><div><div><div class=3D"h5"><br>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br></div></div>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<span class=3D""><br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" rel=3D"nofollow" target=3D"_blank">http://groups.google.com=
/a/isocpp.org/group/std-proposals/</a>.<br>
</span></div></div></blockquote></div><br></div>
</div></div></blockquote></div></div></div></div></blockquote></div><br></d=
iv></blockquote><div>Not sure if it's relevant but seems that in the la=
test draft generic lambdas non-constrained parameters are treated in exactl=
y the opposite way - see for example <a href=3D"http://5.1.2.5" target=3D"_=
blank">5.1.2.5</a>:<br><br>auto glambda =3D [](auto a, auto&& b) { =
return a < b; };<br>=C2=A0bool b =3D glambda(3, 3.14); // OK<br>=C2=A0au=
to vglambda =3D [](auto printer){</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0return [=3D](auto&& ... ts) { // OK: ts is a function parameter =
pack<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printer(std:=
:forward<u></u>(ts)...);
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return [=3D]() {
printer(ts ...);
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 };
<br>=C2=A0};
};
auto p =3D vglambda( [](auto v1, auto v2, auto v3)
{ std::cout << v1 << v2 << v3; } );
auto q =3D p(1, =E2=80=99a=E2=80=99, 3.14); // OK: outputs 1a3.14
q(); // OK: outputs 1a3.14=C2=A0<br><u></u>Seems somewhat inconsistent to t=
reat unconstrained types one way and constrained exactly the opposite</div>=
<div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a113b1a48050236052567bdd8--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 26 Nov 2015 09:50:45 -0800 (PST)
Raw View
------=_Part_754_575981765.1448560245544
Content-Type: multipart/alternative;
boundary="----=_Part_755_1904997490.1448560245545"
------=_Part_755_1904997490.1448560245545
Content-Type: text/plain; charset=UTF-8
On Wednesday, November 25, 2015 at 6:21:41 PM UTC-5, Andrei L wrote:
> So if you actually applied all of the constraints that your function
>> needs, you *couldn't* use terse syntax.
>>
>
>> And I think that leads to an interesting question. How often do you have
>> a function which:
>>
>> 1) Takes two arguments that can be of different types.
>>
>> 2) Those two arguments are constrained by the same concept.
>>
>> 3) There are no additional constraints on those types that would prevent
>> you from using terse syntax.
>>
>> I'd bet that 90% of the time that #1 and #2 are true, there's probably
>> some additional constraint that your function requires of those two types.
>>
>
>>
> Take your suggestion for `compare`. The first range and second range need
>> not be the same types. *But*, they do need to have comparable value
>> types. And a properly constrained template function will apply that
>> constraint, so that users who pass the wrong things will get reasonable
>> errors. And you can't apply such a constraint with terse syntax.
>>
>
> That's why i am unhappy with current situation, i can apply additional
> constraints.
>
> InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIterator
> begin2)
> requires EquallyComparable<decltype(*begin1), decltype(*begin2)>
> && /* any additional constraints */
>
> and if you need and actual type of begin2, and you don't want to use
> decltype, you can use usual template syntax.
>
Wait... Concepts TS allows that functionality right now. There's nothing
that says you can't have a requires clause in addition to terse syntax.
Also, I can't find anything that would prevent you from using template
introduction syntax with a constrained parameter.
I was wrong about not being able to mix the two/three. Though doing what
you did above makes the terse syntax not particularly "terse".
So with the exception of the last statement about `InputIterator` not
referring to the type of `begin2`... what exactly are you missing from the
current system?
And actually, you bring up a very important point. Namely, if we do things
your way, we have to throw around a lot of `decltype(variableName)` to get
the typename of a variable if you use terse syntax.
Or more to the point, if I do this:
void foo(Thingy t)
{
Thingy j = <expr>;
static_assert(is_same<decltype(t), decltype(j)>::value, "Why should this
ever be false?");
}
Given absolutely no knowledge of what `Thingy` is, why should any user ever
expect that assert to trigger? Or more to the point, if we define terse
template syntax the way you want, then users have to know why this may not
be true. That sounds very much like a trap, much like the most vexing
parse. Knowing why it doesn't work requires knowing *way too much* about
C++ minutiae.
Similarly, why should I be prevented from doing `Thingy{}` to construct a
value of the same type as `t`? Why should I have to do `using ThingyType =
decltype(t); ThingyType{}` just to create another value of that type?
> Why make the language more confusing to users? Why make people *have* to
>> learn esoteric rules?
>>
>
> That is why i am here! Why? Rule that is made to make me, a user, less
> confused, made me confused even before it came into effect!
>
Why is *your* confusion more important than someone else's confusion?
Somebody's going to be confused either way. It's either going to be the
people who are acutely aware that using a constraint makes the function a
template, or it's going to be the people who aren't aware of that.
As far as I'm concerned, the former group can handle it better than the
latter.
*Somebody* will be inconvenienced no matter what you do. Why is your side
>> the one that deserves to have the special syntax? Indeed, you seem to argue
>> exactly why they shouldn't: because they're the ones who are willing to
>> learn and use arcane rules. And therefore, they will be less inconvenienced
>> by such arcane rules than if you do it the other way around.
>>
>
> That is not an arcane rule.
>
It requires knowing:
1) That you're using a constraint rather than a typename, despite all
appearances to the contrary.
2) That the rules for using a constraint in a parameter list are different
from the rules of using a typename in a parameter list.
That makes it arcane. It requires knowing way more than most people need to.
> Again, what concept does (should do)? It checks, that object of type T *behaves
> as you need*, not that everything that behaves the same way have the same
> type.
>
> Ducks, i brought you some amount of ducks. They look like a ducks, they
> quack like a ducks, and you treat them like a ducks. But then, i take duck
> consumes off, and you see that this is a cat, this is a dog, and this is a
> horse! And quacking sounds was made with little speakers! What you will do,
> put costumes back on, and say, "Nope, they're all ducks"?
>
You're arguing my case for me.
If the point of putting a duck costume on a cat/dog/horse is that it behave
like a duck, then *make it behave like a duck*. While it's wearing the duck
costume, it should be as indistinguishable as possible from a duck. If I
have to know whether it's a cat or dog or whatever, then why make it look
like a duck at all?
If the point of terse template syntax is to make a constrained template
function act like a non-template function, then it should make it *act like
a non-template function*. Constraints used in place of typenames should
therefore *act like typenames*. That is essentially how the Concepts TS
makes it work.
I don't much care for terse template syntax, but given the goals of it,
this is very much the right choice.
When GCC 6.0 will be released, will this function be made to use terse
> syntax? Or __glibcxx_* macro will be redefined?
>
It may switch to it, and it may not. That's entirely up to GCC's
implementation of the standard library.
The question is ultimately not whether it would. But where it *could*. And
for this function, it certainly could.
What about Eric Niebler's and Casey Carter's STL2 version?
>
> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
> requires
> models::IndirectlyCopyable<I, O>
> tagged_pair<tag::in(I), tag::out(O)>
> copy(I first, S last, O result)
> {
> for (; first != last; ++first, ++result) {
> *result = *first;
> }
> return {__stl2::move(first), __stl2::move(result)};
> }
>
> It uses concepts already, but, where is a terse syntax here?
>
auto copy(InputIterator first, Sentinel<InputIterator> last, OutputIterator
result) requires IndirectlyCopyable<InputIterator, OutputIterator>
I'm not sure about whether `Sentinel<InputIterator>` can work as a
constrained-type-name. But other than that though, what's the problem?
> Is someone going to use it? Where is *the most common and useful of case*s
> applies?
>
Prove that the current syntax is not "the most common and useful of cases".
> STL1 is not the only now, and most probably, it will not use terse syntax.
>
.... again, so what? Does it need to?
Right now, the algorithms and iterator libraries can't effectively use
concepts at all. This is due to the fact that it wasn't designed with such
constraints in mind, and imposing reasonable constraints now will likely
break a lot of people's code.
They could use some, such as the set of iterator requirements and such. But
it should be noted that most of the "set of iterator requirements and such"
can use terse syntax just fine.
Dealing with what `std::accumulate` should require of the value_type, for
example, is not something we want to conceptualize.
> Nobody has contested that full template syntax can do either one. Nobody
>> has suggested that having terse syntax use one way means that the other way
>> becomes impossible.
>>
>
> Suppose you writing a library with a lot of template functions. Some of
> them take arguments of the same, type. Some of them not. Suppose you want
> to constrain all you functions properly, so you use terse syntax for
> parameters with same type and usual template syntax for parameters that
> share same concept but not required to have same type.
>
> Will you be writing it like that
>
> template <R T2>
> auto maybe_same(R p1, T2 p2)
>
> auto same(R p1, R p2)
>
> or for the sake of consistency, like that:
>
> template <R T1, R T2>
> auto maybe_same(T1 p1, T2 p2)
>
> template <R T>
> auto same(T p1, T p2)
>
> ?
>
I wouldn't expect someone to write the latter "for the sake of
consistency". You write each function in the way that seems most natural
for that function declaration. If one function can make use of terse
syntax, I see no reason not to use it just because some other function
can't.
Just like you don't use auto return type deduction on every function just
for the sake of consistency. You use it where it makes the code clearer.
Without same-type rule it could be written like that:
>
> auto maybe_same(R p1, R p2)
>
> R {T} auto same(T p1, T p2)
>
> Aaand consistent version looks kinda, better than others.. maybe just more
> familliar. But first version, i don't like it at all.
>
I can't say that I agree that this is "consistent". I guess it depends on
what you mean by the term "terse templates".
The second function is still using a template declaration. It just doesn't
use the word `template`. The spec is very clear that `concept_name{...}` is
a form of template declaration called a "template-introduction
declaration", which introduces template parameter names.
I consider "terse templates" to refer specifically to using concept names
in place of typenames in function declarations. Especially since parameter
constraints are the only way to apply constraints to lambdas (indeed, I'm
kinda surprised that a lambda *cannot* use template-introduction
declarations or even a `requires` clause at all).
So I can't say that I agree that these are more consistent. Then again, I
don't agree that consistency on this point is a desirable feature...
Oh, one more thing. If you're going to copy pieces out of the text, don't
leave the entire post you're replying to at the bottom. Just delete it
before you post your response.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_755_1904997490.1448560245545
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, November 25, 2015 at 6:21:41 PM UTC-5, Andre=
i L wrote:<br><div></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
dir=3D"ltr"><div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>So =
if you actually applied all of the constraints that your function needs, yo=
u <i>couldn't</i> use terse syntax.<br></div></blockquote><blockquote s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pad=
ding-left:1ex" class=3D"gmail_quote"><br></blockquote><blockquote style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex" class=3D"gmail_quote">And I think that leads to an interesting quest=
ion. How often do you have a function which:<br><br>1) Takes two arguments =
that can be of different types.<br><br>2) Those two arguments are constrain=
ed by the same concept.<br><br>3) There are no additional constraints on th=
ose types that would prevent you from using terse syntax.<br><br></blockquo=
te></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>I'd
bet that 90% of the time that #1 and #2 are true, there's probably som=
e
additional constraint that your function requires of those two types.<br><=
/div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>=
=C2=A0 <br></div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote"><div>Take your suggestion for `compare`. The first range and second ra=
nge need not be the same types. <i>But</i>,
they do need to have comparable value types. And a properly constrained
template function will apply that constraint, so that users who pass=20
the wrong things will get reasonable errors. And you can't apply such a=
=20
constraint with terse syntax.<br></div></blockquote><div>=C2=A0</div><div>T=
hat's why i am unhappy with current situation, i can apply additional c=
onstraints.<br><br><span style=3D"font-family:monospace,monospace">InputIte=
rator_Sentinel {I, S} bool compare(I begin1, S end1, InputIterator begin2)<=
br>=C2=A0 requires EquallyComparable<decltype(*<wbr>begin1), decltype(*b=
egin2)><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 && /* any =
additional constraints */<br></span></div><div><br>and if you need and actu=
al type of begin2, and you don't want to use decltype, you can use usua=
l template syntax.<br></div></div></blockquote><div><br>Wait... Concepts TS=
allows that functionality right now. There's nothing that says you can=
't have a requires clause in addition to terse syntax. Also, I can'=
t find anything that would prevent you from using template introduction syn=
tax with a constrained parameter.<br><br>I was wrong about not being able t=
o mix the two/three. Though doing what you did above makes the terse syntax=
not particularly "terse".<br><br>So with the exception of the la=
st statement about `InputIterator` not referring to the type of `begin2`...=
what exactly are you missing from the current system?<br><br>And actually,=
you bring up a very important point. Namely, if we do things your way, we =
have to throw around a lot of `decltype(variableName)` to get the typename =
of a variable if you use terse syntax.<br><br>Or more to the point, if I do=
this:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250=
, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-=
width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> fo=
o</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Thingy</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> t</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">Thingy</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> j </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&l=
t;expr></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">static=
_assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">is_same</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">decltype</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">t</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">),</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">decltype</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">j</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)&g=
t;::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">value<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">"Why should this ever b=
e false?"</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></=
div></code></div><br>Given absolutely no knowledge of what `Thingy` is, why=
should any user ever expect that assert to trigger? Or more to the point, =
if we define terse template syntax the way you want, then users have to kno=
w why this may not be true. That sounds very much like a trap, much like th=
e most vexing parse. Knowing why it doesn't work requires knowing <i>wa=
y too much</i> about C++ minutiae.<br><br>Similarly, why should I be preven=
ted from doing `Thingy{}` to construct a value of the same type as `t`? Why=
should I have to do `using ThingyType =3D decltype(t); ThingyType{}` just =
to create another value of that type?<br>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div><blockquote style=3D"margin:0p=
x 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" cl=
ass=3D"gmail_quote">Why make the language more confusing to users? Why make=
people <i>have</i> to learn esoteric rules?<br></blockquote></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px=
solid rgb(204,204,204);padding-left:1ex"><span></span></blockquote><div><b=
r></div><div>That
is why i am here! Why? Rule that is made to make me, a user, less=20
confused, made me confused even before it came into effect!<br></div></div>=
</blockquote><div><br>Why is <i>your</i> confusion more important than some=
one else's confusion? Somebody's going to be confused either way. I=
t's either going to be the people who are acutely aware that using a co=
nstraint makes the function a template, or it's going to be the people =
who aren't aware of that.<br><br>As far as I'm concerned, the forme=
r group can handle it better than the latter.<br><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div></div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1p=
x solid rgb(204,204,204);padding-left:1ex"><div><i>Somebody</i>
will be inconvenienced no matter what you do. Why is your side the one=20
that deserves to have the special syntax? Indeed, you seem to argue=20
exactly why they shouldn't: because they're the ones who are willin=
g to=20
learn and use arcane rules. And therefore, they will be less=20
inconvenienced by such arcane rules than if you do it the other way=20
around.</div></blockquote><div><br></div><div>That is not an arcane rule.</=
div></div></blockquote><div><br>It requires knowing:<br><br>1) That you'=
;re using a constraint rather than a typename, despite all appearances to t=
he contrary.<br><br>2) That the rules for using a constraint in a parameter=
list are different from the rules of using a typename in a parameter list.=
<br><br>That makes it arcane. It requires knowing way more than most people=
need to.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
dir=3D"ltr"><div>Again, what concept does (should do)? It checks, that obje=
ct of type T <i>behaves as you need</i>, not that everything that behaves t=
he same way have the same type.<br><br>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks&q=
uot;?<br></div></div></blockquote><div><br>You're arguing my case for m=
e.<br><br>If the point of putting a duck costume on a cat/dog/horse is that=
it behave like a duck, then <i>make it behave like a duck</i>. While it=
9;s wearing the duck costume, it should be as indistinguishable as possible=
from a duck. If I have to know whether it's a cat or dog or whatever, =
then why make it look like a duck at all?<br><br>If the point of terse temp=
late syntax is to make a constrained template function act like a non-templ=
ate function, then it should make it <i>act like a non-template function</i=
>. Constraints used in place of typenames should therefore <i>act like type=
names</i>. That is essentially how the Concepts TS makes it work.<br><br>I =
don't much care for terse template syntax, but given the goals of it, t=
his is very much the right choice.<br><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div></div><div>When GCC 6.0 will be rel=
eased, will this function be made to use terse syntax? Or __glibcxx_* macro=
will be redefined?<br></div></div></blockquote><div><br>It may switch to i=
t, and it may not. That's entirely up to GCC's implementation of th=
e standard library.<br><br>The question is ultimately not whether it would.=
But where it <i>could</i>. And for this function, it certainly could.<br><=
br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
></div><div></div><div>What about Eric Niebler's and Casey Carter's=
STL2 version?<br><br><div style=3D"margin-left:40px"><span style=3D"font-f=
amily:monospace,monospace">template <InputIterator I, Sentinel<I> =
S, WeaklyIncrementable O><br>=C2=A0 requires<br>=C2=A0=C2=A0=C2=A0 model=
s::IndirectlyCopyable<I, O><br>=C2=A0 tagged_pair<tag::in(I), tag:=
:out(O)><br>=C2=A0 copy(I first, S last, O result)<br>=C2=A0 {<br>=C2=A0=
=C2=A0=C2=A0 for (; first !=3D last; ++first, ++result) {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 *result =3D *first;<br>=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=
=A0=C2=A0 return {__stl2::move(first), __stl2::move(result)};<br>=C2=A0 }</=
span><br></div></div><div><br></div><div>It uses concepts already, but, whe=
re is a terse syntax here?<br></div></div></blockquote><div><br><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> copy</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">InputIterator</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> first</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Sentinel</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><</span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">InputIterator</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">></span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">last<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">OutputIterator</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> result</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> requires </span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">IndirectlyCopyable</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">InputIterator</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">OutputIterator</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">></span></div></code></div><br>I'm not=
sure about whether `Sentinel<InputIterator>` can work as a constrain=
ed-type-name. But other than that though, what's the problem?<br>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div> =
Is someone going to use it? Where is <i>the most common and useful of case<=
/i>s applies?<br></div></div></blockquote><div><br>Prove that the current s=
yntax is not "the most common and useful of cases".<br>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div>=
<div></div><div>STL1 is not the only now, and most probably, it will not us=
e terse syntax.</div></div></blockquote><div><br>... again, so what? Does i=
t need to?<br><br>Right now, the algorithms and iterator libraries can'=
t effectively use concepts at all. This is due to the fact that it wasn'=
;t designed with such constraints in mind, and imposing reasonable constrai=
nts now will likely break a lot of people's code.<br><br>They could use=
some, such as the set of iterator requirements and such. But it should be =
noted that most of the "set of iterator requirements and such" ca=
n use terse syntax just fine.<br><br>Dealing with what `std::accumulate` sh=
ould require of the value_type, for example, is not something we want to co=
nceptualize.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div></div><blockquote style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"=
>Nobody has contested that full template syntax can do either one. Nobody h=
as suggested that having terse syntax use one way means that the other way =
becomes impossible.<br></blockquote><div><br></div><div>Suppose you writing=
a library with a lot of template functions. Some of them take arguments of=
the same, type. Some of them not. Suppose you want to constrain all you fu=
nctions properly, so you use terse syntax for parameters with same type and=
usual template syntax for parameters that share same concept but not requi=
red to have same type. <br><br>Will you be writing it like that<br><div sty=
le=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"><br=
>template <R T2></span><br></div><div style=3D"margin-left:40px"><spa=
n style=3D"font-family:monospace,monospace"></span></div><div style=3D"marg=
in-left:40px"><span style=3D"font-family:monospace,monospace">auto maybe_sa=
me(R p1, T2 p2)<br><br></span></div><div style=3D"margin-left:40px"><span s=
tyle=3D"font-family:monospace,monospace">auto same(R p1, R p2)<br></span></=
div><br></div><div>or for the sake of consistency, like that:<br><br><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">t=
emplate <R T1, R T2><br></span></div><div style=3D"margin-left:40px">=
<span style=3D"font-family:monospace,monospace">auto maybe_same(T1 p1, T2 p=
2)</span><br><br></div><div style=3D"margin-left:40px"><span style=3D"font-=
family:monospace,monospace">template <R T><br></span></div><div style=
=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">auto =
same(T p1, T p2)</span><br></div></div><div><span style=3D"font-family:mono=
space,monospace"></span></div><div><br></div><div>?<br></div></div></blockq=
uote><div><br>I wouldn't expect someone to write the latter "for t=
he sake of consistency". You write each function in the way that seems=
most natural for that function declaration. If one function can make use o=
f terse syntax, I see no reason not to use it just because some other funct=
ion can't.<br><br>Just like you don't use auto return type deductio=
n on every function just for the sake of consistency. You use it where it m=
akes the code clearer.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div></div><div></div><div>Without same-type rule it=
could be written like that:<br><br><div style=3D"margin-left:40px"><span s=
tyle=3D"font-family:monospace,monospace">auto maybe_same(R p1, R p2)<br><br=
></span></div><span style=3D"font-family:monospace,monospace"></span><span =
style=3D"font-family:monospace,monospace"></span><div style=3D"margin-left:=
40px"><span style=3D"font-family:monospace,monospace">R {T} auto same(T p1,=
T p2)</span></div></div><div><br></div><div>Aaand consistent version looks=
kinda, better than others.. maybe just more familliar. But first version, =
i don't like it at all.<br></div></div></blockquote><div><br>I can'=
t say that I agree that this is "consistent". I guess it depends =
on what you mean by the term "terse templates".<br><br>The second=
function is still using a template declaration. It just doesn't use th=
e word `template`. The spec is very clear that `concept_name{...}` is a for=
m of template declaration called a "template-introduction declaration&=
quot;, which introduces template parameter names.<br><br>I consider "t=
erse templates" to refer specifically to using concept names in place =
of typenames in function declarations. Especially since parameter constrain=
ts are the only way to apply constraints to lambdas (indeed, I'm kinda =
surprised that a lambda <i>cannot</i> use template-introduction declaration=
s or even a `requires` clause at all).<br><br>So I can't say that I agr=
ee that these are more consistent. Then again, I don't agree that consi=
stency on this point is a desirable feature...<br><br><br><br>Oh, one more =
thing. If you're going to copy pieces out of the text, don't leave =
the entire post you're replying to at the bottom. Just delete it before=
you post your response.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_755_1904997490.1448560245545--
------=_Part_754_575981765.1448560245544--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 26 Nov 2015 20:07:37 +0200
Raw View
On 26 November 2015 at 19:50, Nicol Bolas <jmckesson@gmail.com> wrote:
> Or more to the point, if I do this:
>
> void foo(Thingy t)
> {
> Thingy j = <expr>;
> static_assert(is_same<decltype(t), decltype(j)>::value, "Why should this
> ever be false?");
> }
> Given absolutely no knowledge of what `Thingy` is, why should any user ever
> expect that assert to trigger? Or more to the point, if we define terse
With the current semantics as implemented by gcc, that assert may very
well trigger, so I don't follow
what point you're making here. Multiple occurrences of Thingy in the parameter
list are required to be of the same type, but occurrences of Thingy in
the function
body are not required to be of that type.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 26 Nov 2015 14:33:29 -0500
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
255, 255); line-height: initial;"> =
<div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">I completely agree with this analogy and think it is important =
and pertinent. </div><div style=3D"width: 100%; font-size: initial; fo=
nt-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73,=
125); text-align: initial; background-color: rgb(255, 255, 255);">+1</div>=
=
<div style=3D"wid=
th: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif=
, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-colo=
r: rgb(255, 255, 255);"><br style=3D"display:initial"></div> =
=
=
<div style=3D"font-size: initial; font-family=
: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); te=
xt-align: initial; background-color: rgb(255, 255, 255);">Sent from&nb=
sp;my BlackBerry portable Babbage Device</div> =
=
=
<table width=3D"100%" style=3D"background-color:white;bo=
rder-spacing:0px;"> <tbody><tr><td colspan=3D"2" style=3D"font-size: initia=
l; text-align: initial; background-color: rgb(255, 255, 255);"> =
<div style=3D"border-style: solid none none; border-top-colo=
r: rgb(181, 196, 223); border-top-width: 1pt; padding: 3pt 0in 0in; font-fa=
mily: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-size: 10pt;"> <div><b>Fro=
m: </b>Andrew Tomazos</div><div><b>Sent: </b>Wednesday, November 25, 2015 3=
:14 PM</div><div><b>To: </b>std-proposals@isocpp.org</div><div><b>Reply To:=
</b>std-proposals@isocpp.org</div><div><b>Subject: </b>Re: [std-proposals]=
Re: Question about P0121R0 (Concepts TS)</div></div></td></tr></tbody></ta=
ble><div style=3D"border-style: solid none none; border-top-color: rgb(186,=
188, 209); border-top-width: 1pt; font-size: initial; text-align: initial;=
background-color: rgb(255, 255, 255);"></div><br><div id=3D"_originalConte=
nt" style=3D""><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote">On Wed, Nov 25, 2015 at 8:50 PM, Thiago Macieira <span dir=3D"lt=
r"><<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@maci=
eira.org</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span cl=
ass=3D"">On Wednesday 25 November 2015 19:47:33 Andrew Tomazos wrote:<br>
> concept Animal ...;<br>
> class Dog { ... };<br>
> static_assert(Dog conforms to Animal);<br>
> class Cat { ... };<br>
> static_assert(Cat conforms to Animal);<br>
><br>
> void f(Animal a, Animal b);<br>
><br>
> Dog dog;<br>
> Cat cat;<br>
><br>
> f(dog, cat);<br>
><br>
> I argue that both this example and the previous are similar in importa=
nt<br>
> ways.<br>
><br>
> The mechanics of derived-to-base conversions, base class subobjects,<b=
r>
> reference binding, etc, etc - are secondary to how the language should=
work<br>
> at a conceptual level. They are just a means to an end.<br>
<br>
</span>In this case, the function f would be a template. And that's where t=
hings<br>
become blurry, because if the arguments are templates, there's no automatic=
<br>
casting to a base class.</blockquote><div><br></div><div>Right, instead of =
derived-to-base conversion there is concept-conforming type deduction. =
; The former happens at run-time, the later happens at compile-time. =
Beyond that, at a high-level, I think they are supposed to be similar.</div=
><div><br></div></div></div></div>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br>
<br><!--end of _originalContent --></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 26 Nov 2015 14:40:54 -0500
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
255, 255); line-height: initial;"> =
<div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">Yes. </div><div style=3D"width: 100%; font-size: initial; =
font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 7=
3, 125); text-align: initial; background-color: rgb(255, 255, 255);"><br></=
div><div style=3D"width: 100%; font-size: initial; font-family: Calibri, 'S=
late Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: ini=
tial; background-color: rgb(255, 255, 255);">Once a developer has the 'esse=
nce' of Concepts,=E2=80=8E ie that 'Container' means 'the type, whatever it=
is, must model/satisfy Container', then </div><div style=3D"wid=
th: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif=
, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-colo=
r: rgb(255, 255, 255);"><br></div><div style=3D"width: 100%; font-size: ini=
tial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb=
(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">=
f(Container a, Container b)</div><div style=3D"width: 100%; font-size: init=
ial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(=
31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);"><=
br></div><div style=3D"width: 100%; font-size: initial; font-family: Calibr=
i, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align=
: initial; background-color: rgb(255, 255, 255);">should/can/DOES have obvi=
ous meaning. =E2=80=8E That a and b model Container. No more, no less. If w=
e want to say more, if we want to say 'same' we should need to state that.&=
nbsp;</div><div style=3D"width: 100%; font-size: initial; font-family: Cali=
bri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-ali=
gn: initial; background-color: rgb(255, 255, 255);"><br></div><div style=3D=
"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-s=
erif, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-=
color: rgb(255, 255, 255);">It isn't about terseness or =E2=80=8Efrequency =
of use. It is about what follows logically from the initial principles. Ter=
seness shouldn't override that. </div><div style=3D"width: 100%; font-=
size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; c=
olor: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255=
, 255);"><br></div><div style=3D"width: 100%; font-size: initial; font-fami=
ly: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); =
text-align: initial; background-color: rgb(255, 255, 255);">Tony</div><div =
style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro'=
, sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; bac=
kground-color: rgb(255, 255, 255);"><br></div> =
=
<div style=3D"width: 100%; font-size: initial;=
font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, =
73, 125); text-align: initial; background-color: rgb(255, 255, 255);"><br s=
tyle=3D"display:initial"></div> =
=
=
<div style=3D"font-size: initial; font-family: Calibri, 'Slate Pro', sans-=
serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; background=
-color: rgb(255, 255, 255);">Sent from my BlackBerry po=
rtable Babbage Device</div> =
=
<table wid=
th=3D"100%" style=3D"background-color:white;border-spacing:0px;"> <tbody><t=
r><td colspan=3D"2" style=3D"font-size: initial; text-align: initial; backg=
round-color: rgb(255, 255, 255);"> <div style=3D"=
border-style: solid none none; border-top-color: rgb(181, 196, 223); border=
-top-width: 1pt; padding: 3pt 0in 0in; font-family: Tahoma, 'BB Alpha Sans'=
, 'Slate Pro'; font-size: 10pt;"> <div><b>From: </b>Andrei L</div><div><b>=
Sent: </b>Wednesday, November 25, 2015 7:09 PM</div><div><b>To: </b>std-pro=
posals@isocpp.org</div><div><b>Reply To: </b>std-proposals@isocpp.org</div>=
<div><b>Subject: </b>Re: [std-proposals] Question about P0121R0 (Concepts T=
S)</div></div></td></tr></tbody></table><div style=3D"border-style: solid n=
one none; border-top-color: rgb(186, 188, 209); border-top-width: 1pt; font=
-size: initial; text-align: initial; background-color: rgb(255, 255, 255);"=
></div><br><div id=3D"_originalContent" style=3D""><div dir=3D"ltr"><div>Wh=
en you writing a function and you make use of type constraints, and you dec=
ided to use terse syntax, you think, "How that object (argument) should beh=
ave?" First thing you think about - is behavior. And when you choose right =
behavior, you think, "What about its type? Do i need these be of the same t=
ype?", not, "Do i need them to be different?". And you think that way, beca=
use you didn't specified their types, because you choose to use terse synta=
x, and same-type rule is basically saying, "Oh, i see you want them to be o=
f the same type! I'll make it". But no you don't, you don't want, you don't=
care about type.<br><br></div>Isn't that is how we do it in life? If we ca=
re, we take actions, we make statements, that we care, and if we don't, we =
do nothing. We don't take actions to show that we don't care, because if we=
do something, that usually means that we care. That is what bothers me.<br=
></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">2015-11-26=
4:21 GMT+05:00 Andrei L <span dir=3D"ltr"><<a href=3D"mailto:aendaerel@=
gmail.com" target=3D"_blank">aendaerel@gmail.com</a>></span>:<br><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D""><blockquote style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex" class=3D"gmail_quote">I
would say that your `merge` function here is underconstrained. Why?=20
Because even if those different `Container` instances could deduce=20
different types, those three different types need to have something in=20
common. Namely, that the value type from `src_a` and `src_b` are=20
convertible to the value type for `output`.<br></blockquote><div><br></div>=
</span><div>But,
nothing was said about what is a Container, here. Maybe it's enough.=20
Maybe Container, it is something that can hold some type T, which can=20
hold any other type. And maybe that `merge` function is not an analogue=20
of `merge` in STL. And of course, it's not an example of perfectly=20
constrained, function. One, most probably, would need to add additional=20
requires-clause.<span class=3D""><br><br><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex"><div>So if you actually applied all of the constraints that=
your function needs, you <i>couldn't</i> use terse syntax.<br></div></bloc=
kquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><br></blockquote><=
/span><span class=3D""><blockquote style=3D"margin:0px 0px 0px 0.8ex;border=
-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">An=
d I think that leads to an interesting question. How often do you have a fu=
nction which:<br><br>1) Takes two arguments that can be of different types.=
<br><br>2) Those two arguments are constrained by the same concept.<br><br>=
3) There are no additional constraints on those types that would prevent yo=
u from using terse syntax.<br><br></blockquote></span></div><span class=3D"=
"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left:1px solid rgb(204,204,204);padding-left:1ex"><div>I'd
bet that 90% of the time that #1 and #2 are true, there's probably some
additional constraint that your function requires of those two types.<br><=
/div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>&n=
bsp; <br></div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quot=
e"><div>Take your suggestion for `compare`. The first range and second rang=
e need not be the same types. <i>But</i>,
they do need to have comparable value types. And a properly constrained
template function will apply that constraint, so that users who pass=20
the wrong things will get reasonable errors. And you can't apply such a=20
constraint with terse syntax.<br></div></blockquote><div> </div></span=
><div>That's why i am unhappy with current situation, i can apply additiona=
l constraints.<br><br><span style=3D"font-family:monospace,monospace"><span=
class=3D"">InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, In=
putIterator begin2)<br></span> requires EquallyComparable<decltype=
(*begin1), decltype(*begin2)><br> &nb=
sp; && /* any additional constraints */<br></span></div><div><br>an=
d if you need and actual type of begin2, and you don't want to use decltype=
, you can use usual template syntax.<span class=3D""><br><br><blockquote st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex" class=3D"gmail_quote">Why make the language more confusing to=
users? Why make people <i>have</i> to learn esoteric rules?<br></blockquot=
e></span></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span></sp=
an></blockquote><div><br></div><div>That
is why i am here! Why? Rule that is made to make me, a user, less=20
confused, made me confused even before it came into effect! <br></div><span=
class=3D""><div> </div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1=
ex"><div><i>Somebody</i>
will be inconvenienced no matter what you do. Why is your side the one=20
that deserves to have the special syntax? Indeed, you seem to argue=20
exactly why they shouldn't: because they're the ones who are willing to=20
learn and use arcane rules. And therefore, they will be less=20
inconvenienced by such arcane rules than if you do it the other way=20
around.</div></blockquote><div><br></div></span><div>That is not an arcane =
rule. Again, what concept does (should do)? It checks, that object of type =
T <i>behaves as you need</i>, not that everything that behaves the same way=
have the same type.<br><br>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks"?<br><br><=
/div><span class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px=
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><sp=
an><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>=
And
how is that even possible that someone will try to use a function like=20
above, without actually knowing what is a `Container'?</div></div></blockqu=
ote></span><div><br>The same way that people use std::vector without knowin=
g that the type it takes actually has minimum requirements.</div></blockquo=
te><div><br></div></span><div>People now what std::vector is. How it behave=
s, and how to use it. To call a function F which takes object of type T, yo=
u <b>must</b>, know what you can pass to that function, and what you get as=
a result.<br></div><span class=3D""><div><br><blockquote style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" c=
lass=3D"gmail_quote">The purpose of terse syntax is to minimize template bo=
ilerplate in the most common and useful of cases.<br></blockquote></div><di=
v><br></div></span><div>One of the most common and useful of cases:<br></di=
v><div><br><div style=3D"margin-left:40px"><span style=3D"font-family:monos=
pace,monospace">auto copy(InputIterator begin, InputIterator end, OutputIte=
rator out) -> OutputIterator<br></span></div><div style=3D"margin-left:4=
0px"><span style=3D"font-family:monospace,monospace"> requires /* ...=
*/<br></span></div></div><div><br></div><div>Is
this how it's written right now in GCC, Clang, MSVC? No (because it is=20
not time to rewrite it, but anyways), in GCC it is like that:<br><br><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"><=
span style=3D"color:rgb(0,0,0)">template<typename _II, typename _OI>
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> inline _OI</span></span></pre><div style=3D"margin-left:40px"><sp=
an style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0=
)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> copy(_II __first, _II __last, _OI __result)</span></span></pre><d=
iv style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospac=
e"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> {</span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> // concept requirements</span></span></pre><div style=3D"margin=
-left:40px"><span style=3D"font-family:monospace,monospace"><span style=3D"=
color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_InputIteratorConcept<_II>)</=
span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_OutputIteratorConcept<_OI,</spa=
n></span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> typename iterator_traits<_II>::value_type>)</span></spa=
n></pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospac=
e,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_requires_valid_range(__first, __last);</span></span><=
/pre><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,m=
onospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"><br></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> return (std::__copy_move_a2<__is_move_iterator<_II>::_=
_value></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> (std::__miter_base(__first), std::__miter_base(__last),</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __result));</span></span></pre><div style=3D"margin-left:40px=
"><span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(=
0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> }</span></span></pre><br></div><div>When GCC 6.0 will be released=
, will this function be made to use terse syntax? Or __glibcxx_* macro will=
be redefined?<br></div><div><br></div><div>What about Eric Niebler's and C=
asey Carter's STL2 version?<br><br><div style=3D"margin-left:40px"><span st=
yle=3D"font-family:monospace,monospace">template <InputIterator I, Senti=
nel<I> S, WeaklyIncrementable O><br> requires<br>  =
; models::IndirectlyCopyable<I, O><br> tagged_pair<tag=
::in(I), tag::out(O)><br> copy(I first, S last, O result)<br> =
; {<br> for (; first !=3D last; ++first, ++result) {<br>&=
nbsp; *result =3D *first;<br> }<b=
r> return {__stl2::move(first), __stl2::move(result)};<br=
> }</span><br></div></div><div><br></div><div>It uses concepts alread=
y, but, where is a terse syntax here? Is someone going to use it? Where is=
<i>the most common and useful of case</i>s applies?<br></div><div><br></di=
v><div>STL1 is not the only now, and most probably, it will not use terse s=
yntax. And rule, that i am arguing about, is for terse syntax, and if it is=
not going to be used, for whom that rule is?<br><br><blockquote style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex" class=3D"gmail_quote"><..> to minimize template boilerplate <=
;..>. It is not intended to be a full-fledged <i>replacement</i> for dec=
laring template functions.<br></blockquote><br></div><div>I'm not suggestin=
g to replace it. I'm saying that it could be minimized to the ground.<br></=
div><div><span class=3D""><br><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote">There will always be cases where you need to use full template syntax.=
</blockquote><div><br></div></span><div>Not arguing with that. <br></div></=
div><span class=3D""><div> </div><blockquote style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"=
gmail_quote">Nobody has contested that full template syntax can do either o=
ne. Nobody has suggested that having terse syntax use one way means that th=
e other way becomes impossible.<br></blockquote><div><br></div></span><div>=
Suppose you writing a library with a lot of template functions. Some of the=
m take arguments of the same, type. Some of them not. Suppose you want to c=
onstrain all you functions properly, so you use terse syntax for parameters=
with same type and usual template syntax for parameters that share same co=
ncept but not required to have same type. <br><br>Will you be writing it li=
ke that<br><div style=3D"margin-left:40px"><span style=3D"font-family:monos=
pace,monospace"><br>template <R T2></span><br></div><div style=3D"mar=
gin-left:40px"><span style=3D"font-family:monospace,monospace"></span></div=
><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,monos=
pace">auto maybe_same(R p1, T2 p2)<br><br></span></div><div style=3D"margin=
-left:40px"><span style=3D"font-family:monospace,monospace">auto same(R p1,=
R p2)<br></span></div><br></div><div>or for the sake of consistency, like =
that:<span class=3D""><br><br><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace">template <R T1, R T2><br></span>=
</div></span><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace">auto maybe_same(T1 p1, T2 p2)</span><br><br></div><div st=
yle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace">te=
mplate <R T><br></span></div><div style=3D"margin-left:40px"><span st=
yle=3D"font-family:monospace,monospace">auto same(T p1, T p2)</span><br></d=
iv></div><div><span style=3D"font-family:monospace,monospace"></span></div>=
<div><br></div><div>?<br></div><div><br></div><div>Without same-type rule i=
t could be written like that:<br><br><div style=3D"margin-left:40px"><span =
style=3D"font-family:monospace,monospace">auto maybe_same(R p1, R p2)<br><b=
r></span></div><span style=3D"font-family:monospace,monospace"></span><span=
style=3D"font-family:monospace,monospace"></span><div style=3D"margin-left=
:40px"><span style=3D"font-family:monospace,monospace">R {T} auto same(T p1=
, T p2)</span></div></div><div><br></div><div>Aaand consistent version look=
s kinda, better than others.. maybe just more familliar. But first version,=
i don't like it at all.<br></div></div><div class=3D"HOEnZb"><div class=3D=
"h5"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">2015-11-25 1=
2:07 GMT+05:00 Nicol Bolas <span dir=3D"ltr"><<a href=3D"mailto:jmckesso=
n@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></span>:<br><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><span>On Tuesday, November 24, 2015 at 9:53:59 PM=
UTC-5, Andrei L wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
ltr"><div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">But what I said=
above still applies: since you used a different declaration,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, but the only pos=
sible. And let's not forget about RangesTS, and STL2, where that "common ca=
se" is not so common.<br><br>I'm saying that type checking has nothing to d=
o with defining parameters
of a function. It's just none of its business. User defines parameters. Us=
er defines their types. User decides, if they are of the same type or not.<=
br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace">merge(</span><span style=3D"font-family:monospace,monospa=
ce">Container src_a, </span><span style=3D"font-family:monospace,monospace"=
>Container src_b, Container output)</span></div><div><br></div><div>Do i wa=
nt `src_a', `src_b' and `output' be of the same type? No.</div></div></bloc=
kquote></span><div><br>I would say that your `merge` function here is under=
constrained. Why? Because even if those different `Container` instances cou=
ld deduce different types, those three different types need to have somethi=
ng in common. Namely, that the value type from `src_a` and `src_b` are conv=
ertible to the value type for `output`.<br><br>So if you actually applied a=
ll of the constraints that your function needs, you <i>couldn't</i> use ter=
se syntax. So this is not an example of the problem.<br><br>And I think tha=
t leads to an interesting question. How often do you have a function which:=
<br><br>1) Takes two arguments that can be of different types.<br><br>2) Th=
ose two arguments are constrained by the same concept.<br><br>3) There are =
no additional constraints on those types that would prevent you from using =
terse syntax.<br><br>Take your suggestion for `compare`. The first range an=
d second range need not be the same types. <i>But</i>, they do need to have=
comparable value types. And a properly constrained template function will =
apply that constraint, so that users who pass the wrong things will get rea=
sonable errors. And you can't apply such a constraint with terse syntax.<br=
><br>I'd bet that 90% of the time that #1 and #2 are true, there's probably=
some additional constraint that your function requires of those two types.=
<br><br><i></i></div><span><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>- But, because `Container' placed where types are placed, som=
eone might think that it's a type. That is confusing for that someone, lets=
make types the same. - Okay, but what is about ones who is not confused, w=
ho actually learned the language? Why make them pay and suffer? Is ones who=
don't learned prioritized over ones who learned?<br></div></div></blockquo=
te></span><div><br>Why make the language more confusing to users? Why make =
people <i>have</i> to learn esoteric rules?<br><br><i>Somebody</i> will be =
inconvenienced no matter what you do. Why is your side the one that deserve=
s to have the special syntax? Indeed, you seem to argue exactly why they sh=
ouldn't: because they're the ones who are willing to learn and use arcane r=
ules. And therefore, they will be less inconvenienced by such arcane rules =
than if you do it the other way around.<br><br></div><span><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>And how is that even possible=
that someone will try to use a function like above, without actually knowi=
ng what is a `Container'?</div></div></blockquote></span><div><br>The same =
way that people use std::vector without knowing that the type it takes actu=
ally has minimum requirements.<br> </div><span><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div>If you have a docs, you'll read that=
`merge' is a template function that accepts three objects, types of which =
meet a requirements of the `Container' concept. And if you doesn't have a d=
ocs you will go to source code and see for yourself that `Container' is not=
a type.<br><br>I say, there is no source of confusion. Right now, confusio=
n is not in the heads of a users.<br></div><div><br>Oh, and that terse synt=
ax hides that it's a template function. - But that is not a problem. It is =
purpose of that syntax, to get rid of template boilerplate, no?</div></div>=
</blockquote></span><div><br>The purpose of terse syntax is to minimize tem=
plate boilerplate in the most common and useful of cases. It is not intende=
d to be a full-fledged <i>replacement</i> for declaring template functions.=
There will always be cases where you need to use full template syntax.<br>=
<br>The question is why should your case be the one that gets favoritism?<b=
r> </div><span><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div><div><div></div><div>I used different declaration to show that i don=
't need InputIterator to force same type for begin and end, if i need same =
types i define them to be the same. Just like i do right now, by the way, b=
y writing<br><div style=3D"margin-left:40px"><br></div><div style=3D"margin=
-left:40px"><font face=3D"monospace,monospace">template <typename I, typ=
ename O><br></font></div><div style=3D"margin-left:40px"><font face=3D"m=
onospace,monospace">O copy(I begin, I end, O out)<br><br></font></div>I don=
't need obscure rules to define begin and end to be of the same type. I can=
use template-introduction for that, which is perfectly suitable. And by al=
lowing constrained parameters with same constraints be of different types, =
it's will be also easier to write functions where you just doesn't care abo=
ut actual types. And if it's not enough, you always have usual template syn=
tax, for both cases. Cake for you, and cake for you. Everyone is happy.<br>=
</div></div></div></div></blockquote></span><div><br>Nobody has contested t=
hat full template syntax can do either one. Nobody has suggested that havin=
g terse syntax use one way means that the other way becomes impossible.<br>=
<br>The question is who gets to use the simple syntax. Simply declaring tha=
t the other side can still use full template syntax is basically saying, "w=
hy don't you just let us win? After all, if you do, you lose."</div><br>Do =
a lot of people find this kind of argument convincing?<div><div><br>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br>
<br><!--end of _originalContent --></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 26 Nov 2015 23:12:22 +0100
Raw View
Le 26/11/2015 20:40, Tony V E a =C3=A9crit :
> Yes.
>
> Once a developer has the 'essence' of Concepts,=E2=80=8E ie that 'Contain=
er' means 'the
> type, whatever it is, must model/satisfy Container', then
>
> f(Container a, Container b)
>
> should/can/DOES have obvious meaning. =E2=80=8E That a and b model Contai=
ner. No more,
> no less. If we want to say more, if we want to say 'same' we should need =
to
> state that.
>
> It isn't about terseness or =E2=80=8Efrequency of use. It is about what f=
ollows
> logically from the initial principles. Terseness shouldn't override that.
+1
Vicente
--=20
---=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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Andrei L <aendaerel@gmail.com>
Date: Fri, 27 Nov 2015 04:03:11 +0500
Raw View
--047d7b2e4e3c37ab19052579940a
Content-Type: text/plain; charset=UTF-8
2015-11-26 22:50 GMT+05:00 Nicol Bolas <jmckesson@gmail.com>:
> And actually, you bring up a very important point. Namely, if we do things
> your way, we have to throw around a lot of `decltype(variableName)` to get
> the typename of a variable if you use terse syntax.
I agree, decltype will rise, and that is a drawback of a terse syntax. My
way of doing things isn't a reason for that.
Why is *your* confusion more important than someone else's confusion?
>
It is not more important, it is just exist.
Apparently, i can ask the same question, it is just will be about my
confusion being *less *important. But actually, not only mine, because i am
not the first who asked, "Why same type?". So we back again on question
about prioritizing users.
Somebody's going to be confused either way. It's either going to be the
> people who are acutely aware that using a constraint makes the function a
> template, or it's going to be the people who aren't aware of that.
>
>
As far as I'm concerned, the former group can handle it better than the
> latter.
>
Could you please elaborate on groups of users? What groups of users is
related to first ones, and what to the second ones?
It requires knowing:
>
> 1) That you're using a constraint rather than a typename, despite all
> appearances to the contrary.
>
To use a constraint you required to know that you're using a constraint? ;)
2) That the rules for using a constraint in a parameter list are different
> from the rules of using a typename in a parameter list.
>
Yes? I showed that at the very beginning `R a` is `R<auto> a` type-name
here is `auto`, not R.
Ducks, i brought you some amount of ducks. They look like a ducks, they
>> quack like a ducks, and you treat them like a ducks. But then, i take duck
>> consumes off, and you see that this is a cat, this is a dog, and this is a
>> horse! And quacking sounds was made with little speakers! What you will do,
>> put costumes back on, and say, "Nope, they're all ducks"?
>>
>
> You're arguing my case for me.
>
I, agree. This is more an example of the adapter pattern.
> If the point of putting a duck costume on a cat/dog/horse is that it
> behave like a duck, then *make it behave like a duck*. While it's wearing
> the duck costume, it should be as indistinguishable as possible from a duck.
>
Now you're arguing for me. That is what i said, object's behavior matters,
now what it actually is!
> If I have to know whether it's a cat or dog or whatever, then why make it
> look like a duck at all?
Do you see now? As a writer of a function, you don't need to know. That is
why you should not restrict user of your function to give it only objects
of the same type.
If the point of terse template syntax is to make a constrained template
> function act like a non-template function, then it should make it *act
> like a non-template function*.
>
You said yourself that point of terse syntax is to minimize template
boilerplate.
> Constraints used in place of typenames should therefore *act like
> typenames*. That is essentially how the Concepts TS makes it work.
>
Do type-names make sure that every other parameter of a function have the
same type?
Constraints can't fully act like type names, you saw that with your Thingy
example, that is just can't happen, because they're not types. And you
can't get rid of that.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b2e4e3c37ab19052579940a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra">2015-11-26 22:50 GMT+05:00 Nico=
l Bolas <span dir=3D"ltr"><<a href=3D"mailto:jmckesson@gmail.com" target=
=3D"_blank">jmckesson@gmail.com</a>></span>:<br><div class=3D"gmail_quot=
e"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex">And actually, you brin=
g up a very important point. Namely, if we do things your way, we have to t=
hrow around a lot of `decltype(variableName)` to get the typename of a vari=
able if you use terse syntax.</blockquote></div><br>I agree, decltype will =
rise, and that is a drawback of a terse syntax. My way of doing things isn&=
#39;t a reason for that.<br><br><blockquote style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_=
quote">Why is <i>your</i> confusion more important than someone else's =
confusion?<br></blockquote><div><br></div><div>It is not more important, it=
is just exist.<br><br></div><div>Apparently, i can ask the same question, =
it is just will be about my confusion being <i>less </i>important. But actu=
ally, not only mine, because i am not the first who asked, "Why same t=
ype?". So we back again on question about prioritizing users.<br></div=
><div><br></div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1=
px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>Some=
body's going to be confused either way. It's either going to be the=
=20
people who are acutely aware that using a constraint makes the function a
template, or it's going to be the people who aren't aware of that.=
</div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>=
=C2=A0</div></blockquote><div></div><blockquote style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gm=
ail_quote"><div>As far as I'm concerned, the former group can handle it=
better than the latter.<br></div></blockquote><div><br></div><div>Could yo=
u please elaborate on groups of users? What groups of users is related to f=
irst ones, and what to the second ones?<br><br><blockquote style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" =
class=3D"gmail_quote">It requires knowing:<br><br>1) That you're using =
a constraint rather than a typename, despite all appearances to the contrar=
y.<br></blockquote><br></div><div>To use a constraint you required to know =
that you're using a constraint? ;)<br><br><blockquote style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" c=
lass=3D"gmail_quote">2) That the rules for using a constraint in a paramete=
r list are=20
different from the rules of using a typename in a parameter list. <br></blo=
ckquote><div><br></div><div>Yes? I showed that at the very beginning `R a` =
is `R<auto> a` type-name here is `auto`, not R.<br><br><blockquote st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex" class=3D"gmail_quote"><span class=3D"im"><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(2=
04,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks&q=
uot;?</div></div></blockquote></span><br><div>You're arguing my case fo=
r me.</div></blockquote><div>=C2=A0</div><div>I, agree. This is more an exa=
mple of the adapter pattern.<br>=C2=A0</div><blockquote style=3D"margin:0px=
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" cla=
ss=3D"gmail_quote"><div>If the point of putting a duck costume on a cat/dog=
/horse is that it behave like a duck, then <i>make it behave like a duck</i=
>.
While it's wearing the duck costume, it should be as indistinguishable=
=20
as possible from a duck.<br></div></blockquote><div><br></div><div>Now you&=
#39;re arguing for me. That is what i said, object's behavior matters, =
now what it actually is!<br></div><div>=C2=A0<br><blockquote style=3D"margi=
n:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex=
" class=3D"gmail_quote">If I have to know whether it's a cat or dog or=
=20
whatever, then why make it look like a duck at all?</blockquote><br></div><=
div>Do you see now? As a writer of a function, you don't need to know. =
That is why you should not restrict user of your function to give it only o=
bjects of the same type.<br><br></div><blockquote style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"=
gmail_quote"><div>If the point=20
of terse template syntax is to make a constrained template function act=20
like a non-template function, then it should make it <i>act like a non-temp=
late function</i>. </div></blockquote><div><br></div><div>You said yourself=
that point of terse syntax is to minimize template boilerplate.<br></div><=
div>=C2=A0</div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1=
px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>Cons=
traints used in place of typenames should therefore <i>act like typenames</=
i>. That is essentially how the Concepts TS makes it work.<br></div></block=
quote><div></div><div><br></div>Do type-names make sure that every other pa=
rameter of a function have the same type?<br><br></div><div>Constraints can=
't fully act like type names, you saw that with your Thingy example, th=
at is just can't happen, because they're not types. And you can'=
;t get rid of that.<br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b2e4e3c37ab19052579940a--
.
Author: Andrei L <aendaerel@gmail.com>
Date: Fri, 27 Nov 2015 04:16:13 +0500
Raw View
--001a11c2e342dec7be052579c28c
Content-Type: text/plain; charset=UTF-8
2015-11-26 22:50 GMT+05:00 Nicol Bolas <jmckesson@gmail.com>:
> I'm not sure about whether `Sentinel<InputIterator>` can work as a
> constrained-type-name. But other than that though, what's the problem?
The problem is that same-type-terse-syntax is not used. Most useful case
did not applied.
Prove that the current syntax is not "the most common and useful of cases".
>
Ha! That is not working like that! Prove that it is.
STL1 is not the only now, and most probably, it will not use terse syntax.
>>
>
> ... again, so what? Does it need to?
>
> Right now, the algorithms and iterator libraries can't effectively use
> concepts at all. This is due to the fact that it wasn't designed with such
> constraints in mind, and imposing reasonable constraints now will likely
> break a lot of people's code.
>
You just proved that it is not.
I wouldn't expect someone to write the latter "for the sake of consistency"
>
Do you write curly braces on the same or on the next line? Do you jump
between styles? That is, you choose one style and you write using that
style.
Without same-type rule it could be written like that:
>>
>
>>
> auto maybe_same(R p1, R p2)
>>
>
>> R {T} auto same(T p1, T p2)
>>
>
>> Aaand consistent version looks kinda, better than others.. maybe just
>> more familliar. But first version, i don't like it at all.
>>
>
> I can't say that I agree that this is "consistent".
>
By consistent version i meant example with `template <typename>`s
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c2e342dec7be052579c28c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
2015-11-26 22:50 GMT+05:00 Nicol Bolas <span dir=3D"ltr"><<a href=3D"mai=
lto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></spa=
n>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
border-left:1px solid rgb(204,204,204);padding-left:1ex">I'm not sure a=
bout whether `Sentinel<InputIterator>` can work as a constrained-type=
-name. But other than that though, what's the problem?</blockquote></di=
v><br></div><div class=3D"gmail_extra">The problem is that same-type-terse-=
syntax is not used. Most useful case did not applied.<br><br><blockquote st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex" class=3D"gmail_quote">Prove that the current syntax is not &q=
uot;the most common and useful of cases".<br></blockquote><div><br></d=
iv><div>Ha! That is not working like that! Prove that it is.<br><br><blockq=
uote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex" class=3D"gmail_quote"><span class=3D"im"><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>STL1 is not the =
only now, and most probably, it will not use terse syntax.</div></div></blo=
ckquote></span><div><br>... again, so what? Does it need to?<br><br>Right
now, the algorithms and iterator libraries can't effectively use=20
concepts at all. This is due to the fact that it wasn't designed with=
=20
such constraints in mind, and imposing reasonable constraints now will=20
likely break a lot of people's code.</div></blockquote>=C2=A0<br></div>=
<div>You just proved that it is not.<br><br><blockquote style=3D"margin:0px=
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" cla=
ss=3D"gmail_quote">I wouldn't expect someone to write the latter "=
for the sake of consistency"<br></blockquote><div><br></div><div>Do yo=
u write curly braces on the same or on the next line? Do you jump between s=
tyles? That is, you choose one style and you write using that style.<br><br=
><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex" class=3D"gmail_quote"><span class=3D"im"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Without =
same-type rule it could be written like that:</div></div></blockquote></spa=
n></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1p=
x solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><blockquot=
e style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);=
padding-left:1ex" class=3D"gmail_quote"><div>=C2=A0</div></blockquote></blo=
ckquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid=
rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><span class=3D"im=
"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><=
div style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospa=
ce">auto maybe_same(R p1, R p2)</span></div></div></div></blockquote></span=
><span class=3D"im"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div =
dir=3D"ltr"><div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace"></span></div></div></div></blockquote></span><blockqu=
ote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex" class=3D"gmail_quote"><br></blockquote><span class=3D"i=
m"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>=
<div style=3D"margin-left:40px"><span style=3D"font-family:monospace,monosp=
ace"></span></div><span style=3D"font-family:monospace,monospace"></span><s=
pan style=3D"font-family:monospace,monospace"></span><div style=3D"margin-l=
eft:40px"><span style=3D"font-family:monospace,monospace">R {T} auto same(T=
p1, T p2)</span></div></div></div></blockquote></span><blockquote style=3D=
"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-le=
ft:1ex" class=3D"gmail_quote"><br></blockquote><span class=3D"im"><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px =
solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Aaand consis=
tent version looks kinda, better than others.. maybe just more familliar. B=
ut first version, i don't like it at all.</div></div></blockquote></spa=
n><span class=3D"im"></span><br>I can't say that I agree that this is &=
quot;consistent".<br></blockquote><div><br></div><div>By consistent ve=
rsion i meant example with `template <typename>`s<br></div></div></di=
v></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c2e342dec7be052579c28c--
.
Author: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Thu, 26 Nov 2015 15:29:10 -0800 (PST)
Raw View
------=_Part_5782_1320893473.1448580550671
Content-Type: multipart/alternative;
boundary="----=_Part_5783_900882898.1448580550672"
------=_Part_5783_900882898.1448580550672
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
This summarizes my own genuine reaction on this problem well - "This is so=
=20
logical and simple, why can't people see the truth?!" :)
But, heh, people have different backgrounds, different intuition...
On Thursday, November 26, 2015 at 10:40:58 PM UTC+3, Tony V E wrote:
>
> Yes.=20
>
> Once a developer has the 'essence' of Concepts,=E2=80=8E ie that 'Contain=
er' means=20
> 'the type, whatever it is, must model/satisfy Container', then=20
>
> f(Container a, Container b)
>
> should/can/DOES have obvious meaning. =E2=80=8E That a and b model Contai=
ner. No=20
> more, no less. If we want to say more, if we want to say 'same' we should=
=20
> need to state that.=20
>
> It isn't about terseness or =E2=80=8Efrequency of use. It is about what f=
ollows=20
> logically from the initial principles. Terseness shouldn't override that.=
=20
>
> Tony
>
>
> Sent from my BlackBerry portable Babbage Device
> *From: *Andrei L
> *Sent: *Wednesday, November 25, 2015 7:09 PM
> *To: *std-pr...@isocpp.org <javascript:>
> *Reply To: *std-pr...@isocpp.org <javascript:>
> *Subject: *Re: [std-proposals] Question about P0121R0 (Concepts TS)
>
> When you writing a function and you make use of type constraints, and you=
=20
> decided to use terse syntax, you think, "How that object (argument) shoul=
d=20
> behave?" First thing you think about - is behavior. And when you choose=
=20
> right behavior, you think, "What about its type? Do i need these be of th=
e=20
> same type?", not, "Do i need them to be different?". And you think that=
=20
> way, because you didn't specified their types, because you choose to use=
=20
> terse syntax, and same-type rule is basically saying, "Oh, i see you want=
=20
> them to be of the same type! I'll make it". But no you don't, you don't=
=20
> want, you don't care about type.
>
> Isn't that is how we do it in life? If we care, we take actions, we make=
=20
> statements, that we care, and if we don't, we do nothing. We don't take=
=20
> actions to show that we don't care, because if we do something, that=20
> usually means that we care. That is what bothers me.
>
> 2015-11-26 4:21 GMT+05:00 Andrei L <aend...@gmail.com <javascript:>>:
>
>> I would say that your `merge` function here is underconstrained. Why?=20
>>> Because even if those different `Container` instances could deduce=20
>>> different types, those three different types need to have something in=
=20
>>> common. Namely, that the value type from `src_a` and `src_b` are=20
>>> convertible to the value type for `output`.
>>>
>>
>> But, nothing was said about what is a Container, here. Maybe it's enough=
..=20
>> Maybe Container, it is something that can hold some type T, which can ho=
ld=20
>> any other type. And maybe that `merge` function is not an analogue of=20
>> `merge` in STL. And of course, it's not an example of perfectly=20
>> constrained, function. One, most probably, would need to add additional=
=20
>> requires-clause.
>>
>> So if you actually applied all of the constraints that your function=20
>>> needs, you *couldn't* use terse syntax.
>>>
>>
>>> And I think that leads to an interesting question. How often do you hav=
e=20
>>> a function which:
>>>
>>> 1) Takes two arguments that can be of different types.
>>>
>>> 2) Those two arguments are constrained by the same concept.
>>>
>>> 3) There are no additional constraints on those types that would preven=
t=20
>>> you from using terse syntax.
>>>
>>> I'd bet that 90% of the time that #1 and #2 are true, there's probably=
=20
>>> some additional constraint that your function requires of those two typ=
es.
>>>
>> =20
>>>
>> Take your suggestion for `compare`. The first range and second range nee=
d=20
>>> not be the same types. *But*, they do need to have comparable value=20
>>> types. And a properly constrained template function will apply that=20
>>> constraint, so that users who pass the wrong things will get reasonable=
=20
>>> errors. And you can't apply such a constraint with terse syntax.
>>>
>> =20
>> That's why i am unhappy with current situation, i can apply additional=
=20
>> constraints.
>>
>> InputIterator_Sentinel {I, S} bool compare(I begin1, S end1,=20
>> InputIterator begin2)
>> requires EquallyComparable<decltype(*begin1), decltype(*begin2)>
>> && /* any additional constraints */
>>
>> and if you need and actual type of begin2, and you don't want to use=20
>> decltype, you can use usual template syntax.
>>
>> Why make the language more confusing to users? Why make people *have* to=
=20
>>> learn esoteric rules?
>>>
>>
>> That is why i am here! Why? Rule that is made to make me, a user, less=
=20
>> confused, made me confused even before it came into effect!=20
>> =20
>>
>>> *Somebody* will be inconvenienced no matter what you do. Why is your=20
>>> side the one that deserves to have the special syntax? Indeed, you seem=
to=20
>>> argue exactly why they shouldn't: because they're the ones who are will=
ing=20
>>> to learn and use arcane rules. And therefore, they will be less=20
>>> inconvenienced by such arcane rules than if you do it the other way aro=
und.
>>>
>>
>> That is not an arcane rule. Again, what concept does (should do)? It=20
>> checks, that object of type T *behaves as you need*, not that everything=
=20
>> that behaves the same way have the same type.
>>
>> Ducks, i brought you some amount of ducks. They look like a ducks, they=
=20
>> quack like a ducks, and you treat them like a ducks. But then, i take du=
ck=20
>> consumes off, and you see that this is a cat, this is a dog, and this is=
a=20
>> horse! And quacking sounds was made with little speakers! What you will =
do,=20
>> put costumes back on, and say, "Nope, they're all ducks"?
>>
>> And how is that even possible that someone will try to use a function=20
>>>> like above, without actually knowing what is a `Container'?
>>>>
>>>
>>> The same way that people use std::vector without knowing that the type=
=20
>>> it takes actually has minimum requirements.
>>>
>>
>> People now what std::vector is. How it behaves, and how to use it. To=20
>> call a function F which takes object of type T, you *must*, know what=20
>> you can pass to that function, and what you get as a result.
>>
>> The purpose of terse syntax is to minimize template boilerplate in the=
=20
>>> most common and useful of cases.
>>>
>>
>> One of the most common and useful of cases:
>>
>> auto copy(InputIterator begin, InputIterator end, OutputIterator out) ->=
=20
>> OutputIterator
>> requires /* ... */
>>
>> Is this how it's written right now in GCC, Clang, MSVC? No (because it i=
s=20
>> not time to rewrite it, but anyways), in GCC it is like that:
>>
>> template<typename _II, typename _OI>=20
>>
>> inline _OI
>>
>> copy(_II __first, _II __last, _OI __result)
>>
>> {
>>
>> // concept requirements
>>
>> __glibcxx_function_requires(_InputIteratorConcept<_II>)
>>
>> __glibcxx_function_requires(_OutputIteratorConcept<_OI,
>>
>> typename iterator_traits<_II>::value_type>)
>>
>> __glibcxx_requires_valid_range(__first, __last);
>>
>>
>> return (std::__copy_move_a2<__is_move_iterator<_II>::__value>
>>
>> (std::__miter_base(__first), std::__miter_base(__last),
>>
>> __result));
>>
>> }
>>
>>
>> When GCC 6.0 will be released, will this function be made to use terse=
=20
>> syntax? Or __glibcxx_* macro will be redefined?
>>
>> What about Eric Niebler's and Casey Carter's STL2 version?
>>
>> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
>> requires
>> models::IndirectlyCopyable<I, O>
>> tagged_pair<tag::in(I), tag::out(O)>
>> copy(I first, S last, O result)
>> {
>> for (; first !=3D last; ++first, ++result) {
>> *result =3D *first;
>> }
>> return {__stl2::move(first), __stl2::move(result)};
>> }
>>
>> It uses concepts already, but, where is a terse syntax here? Is someone=
=20
>> going to use it? Where is *the most common and useful of case*s applies?
>>
>> STL1 is not the only now, and most probably, it will not use terse=20
>> syntax. And rule, that i am arguing about, is for terse syntax, and if i=
t=20
>> is not going to be used, for whom that rule is?
>>
>> <..> to minimize template boilerplate <..>. It is not intended to be a=
=20
>>> full-fledged *replacement* for declaring template functions.
>>>
>>
>> I'm not suggesting to replace it. I'm saying that it could be minimized=
=20
>> to the ground.
>>
>> There will always be cases where you need to use full template syntax.
>>
>>
>> Not arguing with that.=20
>> =20
>>
>>> Nobody has contested that full template syntax can do either one. Nobod=
y=20
>>> has suggested that having terse syntax use one way means that the other=
way=20
>>> becomes impossible.
>>>
>>
>> Suppose you writing a library with a lot of template functions. Some of=
=20
>> them take arguments of the same, type. Some of them not. Suppose you wan=
t=20
>> to constrain all you functions properly, so you use terse syntax for=20
>> parameters with same type and usual template syntax for parameters that=
=20
>> share same concept but not required to have same type.=20
>>
>> Will you be writing it like that
>>
>> template <R T2>
>> auto maybe_same(R p1, T2 p2)
>>
>> auto same(R p1, R p2)
>>
>> or for the sake of consistency, like that:
>>
>> template <R T1, R T2>
>> auto maybe_same(T1 p1, T2 p2)
>>
>> template <R T>
>> auto same(T p1, T p2)
>>
>> ?
>>
>> Without same-type rule it could be written like that:
>>
>> auto maybe_same(R p1, R p2)
>>
>> R {T} auto same(T p1, T p2)
>>
>> Aaand consistent version looks kinda, better than others.. maybe just=20
>> more familliar. But first version, i don't like it at all.
>>
>> 2015-11-25 12:07 GMT+05:00 Nicol Bolas <jmck...@gmail.com <javascript:>>=
:
>>
>>> On Tuesday, November 24, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:
>>>>
>>>> But what I said above still applies: since you used a different=20
>>>>> declaration,
>>>>> it does not support the argument that two InputIterator uses in the=
=20
>>>>> same
>>>>> declaration should be different.
>>>>
>>>>
>>>> I'm not making an argument that two iterators should be different.=20
>>>> Also, i am not talking about STL's "common case" which is not common, =
but=20
>>>> the only possible. And let's not forget about RangesTS, and STL2, wher=
e=20
>>>> that "common case" is not so common.
>>>>
>>>> I'm saying that type checking has nothing to do with defining=20
>>>> parameters of a function. It's just none of its business. User defines=
=20
>>>> parameters. User defines their types. User decides, if they are of the=
same=20
>>>> type or not.
>>>>
>>>> merge(Container src_a, Container src_b, Container output)
>>>>
>>>> Do i want `src_a', `src_b' and `output' be of the same type? No.
>>>>
>>>
>>> I would say that your `merge` function here is underconstrained. Why?=
=20
>>> Because even if those different `Container` instances could deduce=20
>>> different types, those three different types need to have something in=
=20
>>> common. Namely, that the value type from `src_a` and `src_b` are=20
>>> convertible to the value type for `output`.
>>>
>>> So if you actually applied all of the constraints that your function=20
>>> needs, you *couldn't* use terse syntax. So this is not an example of=20
>>> the problem.
>>>
>>> And I think that leads to an interesting question. How often do you hav=
e=20
>>> a function which:
>>>
>>> 1) Takes two arguments that can be of different types.
>>>
>>> 2) Those two arguments are constrained by the same concept.
>>>
>>> 3) There are no additional constraints on those types that would preven=
t=20
>>> you from using terse syntax.
>>>
>>> Take your suggestion for `compare`. The first range and second range=20
>>> need not be the same types. *But*, they do need to have comparable=20
>>> value types. And a properly constrained template function will apply th=
at=20
>>> constraint, so that users who pass the wrong things will get reasonable=
=20
>>> errors. And you can't apply such a constraint with terse syntax.
>>>
>>> I'd bet that 90% of the time that #1 and #2 are true, there's probably=
=20
>>> some additional constraint that your function requires of those two typ=
es.
>>>
>>> - But, because `Container' placed where types are placed, someone might=
=20
>>>> think that it's a type. That is confusing for that someone, lets make =
types=20
>>>> the same. - Okay, but what is about ones who is not confused, who actu=
ally=20
>>>> learned the language? Why make them pay and suffer? Is ones who don't=
=20
>>>> learned prioritized over ones who learned?
>>>>
>>>
>>> Why make the language more confusing to users? Why make people *have*=
=20
>>> to learn esoteric rules?
>>>
>>> *Somebody* will be inconvenienced no matter what you do. Why is your=20
>>> side the one that deserves to have the special syntax? Indeed, you seem=
to=20
>>> argue exactly why they shouldn't: because they're the ones who are will=
ing=20
>>> to learn and use arcane rules. And therefore, they will be less=20
>>> inconvenienced by such arcane rules than if you do it the other way aro=
und.
>>>
>>> And how is that even possible that someone will try to use a function=
=20
>>>> like above, without actually knowing what is a `Container'?
>>>>
>>>
>>> The same way that people use std::vector without knowing that the type=
=20
>>> it takes actually has minimum requirements.
>>> =20
>>>
>>>> If you have a docs, you'll read that `merge' is a template function=20
>>>> that accepts three objects, types of which meet a requirements of the=
=20
>>>> `Container' concept. And if you doesn't have a docs you will go to sou=
rce=20
>>>> code and see for yourself that `Container' is not a type.
>>>>
>>>> I say, there is no source of confusion. Right now, confusion is not in=
=20
>>>> the heads of a users.
>>>>
>>>> Oh, and that terse syntax hides that it's a template function. - But=
=20
>>>> that is not a problem. It is purpose of that syntax, to get rid of tem=
plate=20
>>>> boilerplate, no?
>>>>
>>>
>>> The purpose of terse syntax is to minimize template boilerplate in the=
=20
>>> most common and useful of cases. It is not intended to be a full-fledge=
d=20
>>> *replacement* for declaring template functions. There will always be=20
>>> cases where you need to use full template syntax.
>>>
>>> The question is why should your case be the one that gets favoritism?
>>> =20
>>>
>>>> I used different declaration to show that i don't need InputIterator t=
o=20
>>>> force same type for begin and end, if i need same types i define them =
to be=20
>>>> the same. Just like i do right now, by the way, by writing
>>>>
>>>> template <typename I, typename O>
>>>> O copy(I begin, I end, O out)
>>>>
>>>> I don't need obscure rules to define begin and end to be of the same=
=20
>>>> type. I can use template-introduction for that, which is perfectly=20
>>>> suitable. And by allowing constrained parameters with same constraints=
be=20
>>>> of different types, it's will be also easier to write functions where =
you=20
>>>> just doesn't care about actual types. And if it's not enough, you alwa=
ys=20
>>>> have usual template syntax, for both cases. Cake for you, and cake for=
you.=20
>>>> Everyone is happy.
>>>>
>>>
>>> Nobody has contested that full template syntax can do either one. Nobod=
y=20
>>> has suggested that having terse syntax use one way means that the other=
way=20
>>> becomes impossible.
>>>
>>> The question is who gets to use the simple syntax. Simply declaring tha=
t=20
>>> the other side can still use full template syntax is basically saying, =
"why=20
>>> don't you just let us win? After all, if you do, you lose."
>>>
>>> Do a lot of people find this kind of argument convincing?
>>>
>>> --=20
>>>
>>> ---=20
>>> You received this message because you are subscribed to the Google=20
>>> Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send=
=20
>>> an email to std-proposal...@isocpp.org <javascript:>.
>>> To post to this group, send email to std-pr...@isocpp.org <javascript:>=
..
>>> Visit this group at=20
>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>>
>>
> --=20
>
> ---=20
> You received this message because you are subscribed to the Google Groups=
=20
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
=20
> email to std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> Visit this group at=20
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
--=20
---=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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_5783_900882898.1448580550672
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">This summarizes my own genuine reaction on this problem we=
ll - "This is so logical and simple, why can't people see the trut=
h?!" :)<br>But, heh, people have different backgrounds, different intu=
ition...<br><br>On Thursday, November 26, 2015 at 10:40:58 PM UTC+3, Tony V=
E wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div lang=3D"en-US" s=
tyle=3D"background-color:rgb(255,255,255);line-height:initial"> =
<=
div style=3D"width:100%;font-size:initial;font-family:Calibri,'Slate Pr=
o',sans-serif,sans-serif;color:rgb(31,73,125);text-align:initial;backgr=
ound-color:rgb(255,255,255)">Yes.=C2=A0</div><div style=3D"width:100%;font-=
size:initial;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;=
color:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)">=
<br></div><div style=3D"width:100%;font-size:initial;font-family:Calibri,&#=
39;Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-align:ini=
tial;background-color:rgb(255,255,255)">Once a developer has the 'essen=
ce' of Concepts,=E2=80=8E ie that 'Container' means 'the ty=
pe, whatever it is, must model/satisfy =C2=A0Container', then=C2=A0</di=
v><div style=3D"width:100%;font-size:initial;font-family:Calibri,'Slate=
Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-align:initial;bac=
kground-color:rgb(255,255,255)"><br></div><div style=3D"width:100%;font-siz=
e:initial;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;col=
or:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)">f(C=
ontainer a, Container b)</div><div style=3D"width:100%;font-size:initial;fo=
nt-family:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73=
,125);text-align:initial;background-color:rgb(255,255,255)"><br></div><div =
style=3D"width:100%;font-size:initial;font-family:Calibri,'Slate Pro=
9;,sans-serif,sans-serif;color:rgb(31,73,125);text-align:initial;background=
-color:rgb(255,255,255)">should/can/DOES have obvious meaning. =E2=80=8E Th=
at a and b model Container. No more, no less. If we want to say more, if we=
want to say 'same' we should need to state that.=C2=A0</div><div s=
tyle=3D"width:100%;font-size:initial;font-family:Calibri,'Slate Pro'=
;,sans-serif,sans-serif;color:rgb(31,73,125);text-align:initial;background-=
color:rgb(255,255,255)"><br></div><div style=3D"width:100%;font-size:initia=
l;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(3=
1,73,125);text-align:initial;background-color:rgb(255,255,255)">It isn'=
t about terseness or =E2=80=8Efrequency of use. It is about what follows lo=
gically from the initial principles. Terseness shouldn't override that.=
=C2=A0</div><div style=3D"width:100%;font-size:initial;font-family:Calibri,=
'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-align:i=
nitial;background-color:rgb(255,255,255)"><br></div><div style=3D"width:100=
%;font-size:initial;font-family:Calibri,'Slate Pro',sans-serif,sans=
-serif;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,255=
,255)">Tony</div><div style=3D"width:100%;font-size:initial;font-family:Cal=
ibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-al=
ign:initial;background-color:rgb(255,255,255)"><br></div> =
=
<div style=3D"width:100%;font-size:=
initial;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;color=
:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)"><br s=
tyle=3D"display:initial"></div> =
=
=
<div style=3D"font-size:initial;font-family:Calibri,'Slate Pro',sa=
ns-serif,sans-serif;color:rgb(31,73,125);text-align:initial;background-colo=
r:rgb(255,255,255)">Sent=C2=A0from=C2=A0my=C2=A0BlackBerry=C2=A0<wbr>portab=
le=C2=A0Babbage=C2=A0Device</div> =
=
<table width=
=3D"100%" style=3D"background-color:white;border-spacing:0px"> <tbody><tr><=
td colspan=3D"2" style=3D"font-size:initial;text-align:initial;background-c=
olor:rgb(255,255,255)"> <div style=3D"border-styl=
e:solid none none;border-top-color:rgb(181,196,223);border-top-width:1pt;pa=
dding:3pt 0in 0in;font-family:Tahoma,'BB Alpha Sans','Slate Pro=
';font-size:10pt"> <div><b>From: </b>Andrei L</div><div><b>Sent: </b>W=
ednesday, November 25, 2015 7:09 PM</div><div><b>To: </b><a href=3D"javascr=
ipt:" target=3D"_blank" gdf-obfuscated-mailto=3D"Cr7YROkpBwAJ" rel=3D"nofol=
low" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=
=3D"this.href=3D'javascript:';return true;">std-pr...@isocpp.org</a=
></div><div><b>Reply To: </b><a href=3D"javascript:" target=3D"_blank" gdf-=
obfuscated-mailto=3D"Cr7YROkpBwAJ" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D'javascript:';return true;" onclick=3D"this.href=3D'javascr=
ipt:';return true;">std-pr...@isocpp.org</a></div><div><b>Subject: </b>=
Re: [std-proposals] Question about P0121R0 (Concepts TS)</div></div></td></=
tr></tbody></table><div style=3D"border-style:solid none none;border-top-co=
lor:rgb(186,188,209);border-top-width:1pt;font-size:initial;text-align:init=
ial;background-color:rgb(255,255,255)"></div><br><div><div dir=3D"ltr"><div=
>When you writing a function and you make use of type constraints, and you =
decided to use terse syntax, you think, "How that object (argument) sh=
ould behave?" First thing you think about - is behavior. And when you =
choose right behavior, you think, "What about its type? Do i need thes=
e be of the same type?", not, "Do i need them to be different?&qu=
ot;. And you think that way, because you didn't specified their types, =
because you choose to use terse syntax, and same-type rule is basically say=
ing, "Oh, i see you want them to be of the same type! I'll make it=
". But no you don't, you don't want, you don't care about =
type.<br><br></div>Isn't that is how we do it in life? If we care, we t=
ake actions, we make statements, that we care, and if we don't, we do n=
othing. We don't take actions to show that we don't care, because i=
f we do something, that usually means that we care. That is what bothers me=
..<br></div><div><br><div class=3D"gmail_quote">2015-11-26 4:21 GMT+05:00 An=
drei L <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-=
obfuscated-mailto=3D"Cr7YROkpBwAJ" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D'javascript:';return true;" onclick=3D"this.href=3D'javascr=
ipt:';return true;">aend...@gmail.com</a>></span>:<br><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><span><blockquote style=3D"margin:0px 0px=
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=
=3D"gmail_quote">I
would say that your `merge` function here is underconstrained. Why?=20
Because even if those different `Container` instances could deduce=20
different types, those three different types need to have something in=20
common. Namely, that the value type from `src_a` and `src_b` are=20
convertible to the value type for `output`.<br></blockquote><div><br></div>=
</span><div>But,
nothing was said about what is a Container, here. Maybe it's enough.=
=20
Maybe Container, it is something that can hold some type T, which can=20
hold any other type. And maybe that `merge` function is not an analogue=20
of `merge` in STL. And of course, it's not an example of perfectly=20
constrained, function. One, most probably, would need to add additional=20
requires-clause.<span><br><br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex"><div>So if you actually applied all of the constraints that your funct=
ion needs, you <i>couldn't</i> use terse syntax.<br></div></blockquote>=
<blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex" class=3D"gmail_quote"><br></blockquote></span><=
span><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex" class=3D"gmail_quote">And I think that lea=
ds to an interesting question. How often do you have a function which:<br><=
br>1) Takes two arguments that can be of different types.<br><br>2) Those t=
wo arguments are constrained by the same concept.<br><br>3) There are no ad=
ditional constraints on those types that would prevent you from using terse=
syntax.<br><br></blockquote></span></div><span><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex"><div>I'd
bet that 90% of the time that #1 and #2 are true, there's probably som=
e
additional constraint that your function requires of those two types.<br><=
/div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div>=
=C2=A0 <br></div></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_qu=
ote"><div>Take your suggestion for `compare`. The first range and second ra=
nge need not be the same types. <i>But</i>,
they do need to have comparable value types. And a properly constrained
template function will apply that constraint, so that users who pass=20
the wrong things will get reasonable errors. And you can't apply such a=
=20
constraint with terse syntax.<br></div></blockquote><div>=C2=A0</div></span=
><div>That's why i am unhappy with current situation, i can apply addit=
ional constraints.<br><br><span style=3D"font-family:monospace,monospace"><=
span>InputIterator_Sentinel {I, S} bool compare(I begin1, S end1, InputIter=
ator begin2)<br></span>=C2=A0 requires EquallyComparable<decltype(*<wbr>=
begin1), decltype(*begin2)><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 && /* any additional constraints */<br></span></div><div><br>an=
d if you need and actual type of begin2, and you don't want to use decl=
type, you can use usual template syntax.<span><br><br><blockquote style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex" class=3D"gmail_quote">Why make the language more confusing to users?=
Why make people <i>have</i> to learn esoteric rules?<br></blockquote></spa=
n></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span></span></bl=
ockquote><div><br></div><div>That
is why i am here! Why? Rule that is made to make me, a user, less=20
confused, made me confused even before it came into effect! <br></div><span=
><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><i=
>Somebody</i>
will be inconvenienced no matter what you do. Why is your side the one=20
that deserves to have the special syntax? Indeed, you seem to argue=20
exactly why they shouldn't: because they're the ones who are willin=
g to=20
learn and use arcane rules. And therefore, they will be less=20
inconvenienced by such arcane rules than if you do it the other way=20
around.</div></blockquote><div><br></div></span><div>That is not an arcane =
rule. Again, what concept does (should do)? It checks, that object of type =
T <i>behaves as you need</i>, not that everything that behaves the same way=
have the same type.<br><br>Ducks,
i brought you some amount of ducks. They look like a ducks, they quack=20
like a ducks, and you treat them like a ducks. But then, i take duck=20
consumes off, and you see that this is a cat, this is a dog, and this is
a horse! And quacking sounds was made with little speakers! What you=20
will do, put costumes back on, and say, "Nope, they're all ducks&q=
uot;?<br><br></div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
<span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>And
how is that even possible that someone will try to use a function like=20
above, without actually knowing what is a `Container'?</div></div></blo=
ckquote></span><div><br>The same way that people use std::vector without kn=
owing that the type it takes actually has minimum requirements.</div></bloc=
kquote><div><br></div></span><div>People now what std::vector is. How it be=
haves, and how to use it. To call a function F which takes object of type T=
, you <b>must</b>, know what you can pass to that function, and what you ge=
t as a result.<br></div><span><div><br><blockquote style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D=
"gmail_quote">The purpose of terse syntax is to minimize template boilerpla=
te in the most common and useful of cases.<br></blockquote></div><div><br><=
/div></span><div>One of the most common and useful of cases:<br></div><div>=
<br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,mo=
nospace">auto copy(InputIterator begin, InputIterator end, OutputIterator o=
ut) -> OutputIterator<br></span></div><div style=3D"margin-left:40px"><s=
pan style=3D"font-family:monospace,monospace">=C2=A0 requires /* ... */<br>=
</span></div></div><div><br></div><div>Is
this how it's written right now in GCC, Clang, MSVC? No (because it is=
=20
not time to rewrite it, but anyways), in GCC it is like that:<br><br><div s=
tyle=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"><=
span style=3D"color:rgb(0,0,0)">template<typename _II, typename _OI>
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> inline _OI</span></span></pre><div style=3D"margin-left:40px"><sp=
an style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0=
)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> copy(_II __first, _II __last, _OI __result)</span></span></pre><d=
iv style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospac=
e"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> {</span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> // concept requirements</span></span></pre><div style=3D"margin=
-left:40px"><span style=3D"font-family:monospace,monospace"><span style=3D"=
color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_<wbr>InputIteratorConcept<_II&g=
t;)</span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-=
family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_function_requires(_<wbr>OutputIteratorConcept<_OI,=
</span></span></pre><div style=3D"margin-left:40px"><span style=3D"font-fam=
ily:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> typename iterator_traits<_II>::value_<wbr>type>)</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __glibcxx_requires_valid_<wbr>range(__first, __last);</span></s=
pan></pre><div style=3D"margin-left:40px"><span style=3D"font-family:monosp=
ace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"><br></span></span></pre><div style=3D"margin-left:40px"><span style=
=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> return (std::__copy_move_a2<__is_<wbr>move_iterator<_II&g=
t;::__value></span></span></pre><div style=3D"margin-left:40px"><span st=
yle=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> (std::__miter_base(__first), std::__miter_base(__last),</span>=
</span></pre><div style=3D"margin-left:40px"><span style=3D"font-family:mon=
ospace,monospace"><span style=3D"color:rgb(0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> __result));</span></span></pre><div style=3D"margin-left:40px=
"><span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(=
0,0,0)">
</span></span></div><pre style=3D"margin:0px 0px 0px 40px;text-indent:0px">=
<span style=3D"font-family:monospace,monospace"><span style=3D"color:rgb(0,=
0,0)"> }</span></span></pre><br></div><div>When GCC 6.0 will be released=
, will this function be made to use terse syntax? Or __glibcxx_* macro will=
be redefined?<br></div><div><br></div><div>What about Eric Niebler's a=
nd Casey Carter's STL2 version?<br><br><div style=3D"margin-left:40px">=
<span style=3D"font-family:monospace,monospace">template <InputIterator =
I, Sentinel<I> S, WeaklyIncrementable O><br>=C2=A0 requires<br>=C2=
=A0=C2=A0=C2=A0 models::IndirectlyCopyable<I, O><br>=C2=A0 tagged_pai=
r<tag::in(I), tag::out(O)><br>=C2=A0 copy(I first, S last, O result)<=
br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 for (; first !=3D last; ++first, ++result=
) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *result =3D *first;<br>=C2=A0=C2=A0=
=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 return {__stl2::move(first), __stl2::move(re=
sult)};<br>=C2=A0 }</span><br></div></div><div><br></div><div>It uses conce=
pts already, but, where is a terse syntax here? Is someone going to use it=
? Where is <i>the most common and useful of case</i>s applies?<br></div><di=
v><br></div><div>STL1 is not the only now, and most probably, it will not u=
se terse syntax. And rule, that i am arguing about, is for terse syntax, an=
d if it is not going to be used, for whom that rule is?<br><br><blockquote =
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex" class=3D"gmail_quote"><..> to minimize template boile=
rplate <..>. It is not intended to be a full-fledged <i>replacement</=
i> for declaring template functions.<br></blockquote><br></div><div>I'm=
not suggesting to replace it. I'm saying that it could be minimized to=
the ground.<br></div><div><span><br><blockquote style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"g=
mail_quote">There will always be cases where you need to use full template =
syntax.</blockquote><div><br></div></span><div>Not arguing with that. <br><=
/div></div><span><div>=C2=A0</div><blockquote style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmai=
l_quote">Nobody has contested that full template syntax can do either one. =
Nobody has suggested that having terse syntax use one way means that the ot=
her way becomes impossible.<br></blockquote><div><br></div></span><div>Supp=
ose you writing a library with a lot of template functions. Some of them ta=
ke arguments of the same, type. Some of them not. Suppose you want to const=
rain all you functions properly, so you use terse syntax for parameters wit=
h same type and usual template syntax for parameters that share same concep=
t but not required to have same type. <br><br>Will you be writing it like t=
hat<br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace=
,monospace"><br>template <R T2></span><br></div><div style=3D"margin-=
left:40px"><span style=3D"font-family:monospace,monospace"></span></div><di=
v style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace=
">auto maybe_same(R p1, T2 p2)<br><br></span></div><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">auto same(R p1, R p=
2)<br></span></div><br></div><div>or for the sake of consistency, like that=
:<span><br><br><div style=3D"margin-left:40px"><span style=3D"font-family:m=
onospace,monospace">template <R T1, R T2><br></span></div></span><div=
style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospace"=
>auto maybe_same(T1 p1, T2 p2)</span><br><br></div><div style=3D"margin-lef=
t:40px"><span style=3D"font-family:monospace,monospace">template <R T>=
;<br></span></div><div style=3D"margin-left:40px"><span style=3D"font-famil=
y:monospace,monospace">auto same(T p1, T p2)</span><br></div></div><div><sp=
an style=3D"font-family:monospace,monospace"></span></div><div><br></div><d=
iv>?<br></div><div><br></div><div>Without same-type rule it could be writte=
n like that:<br><br><div style=3D"margin-left:40px"><span style=3D"font-fam=
ily:monospace,monospace">auto maybe_same(R p1, R p2)<br><br></span></div><s=
pan style=3D"font-family:monospace,monospace"></span><span style=3D"font-fa=
mily:monospace,monospace"></span><div style=3D"margin-left:40px"><span styl=
e=3D"font-family:monospace,monospace">R {T} auto same(T p1, T p2)</span></d=
iv></div><div><br></div><div>Aaand consistent version looks kinda, better t=
han others.. maybe just more familliar. But first version, i don't like=
it at all.<br></div></div><div><div><div><br><div class=3D"gmail_quote">20=
15-11-25 12:07 GMT+05:00 Nicol Bolas <span dir=3D"ltr"><<a href=3D"javas=
cript:" target=3D"_blank" gdf-obfuscated-mailto=3D"Cr7YROkpBwAJ" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D'javascript:';return true;" oncli=
ck=3D"this.href=3D'javascript:';return true;">jmck...@gmail.com</a>=
></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><span>On Tuesday, November 2=
4, 2015 at 9:53:59 PM UTC-5, Andrei L wrote:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div><blockquote style=3D"margin:0px 0px 0px 0.8e=
x;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_q=
uote">But what I said above still applies: since you used a different decla=
ration,<br>
it does not support the argument that two InputIterator uses in the same<br=
>
declaration should be different.</blockquote><div><br></div>I'm not
making an argument that two iterators should be different. Also, i am=20
not talking about STL's "common case" which is not common, bu=
t the only possible. And let's not forget about RangesTS, and STL2, whe=
re that "common case" is not so common.<br><br>I'm saying tha=
t type checking has nothing to do with defining parameters
of a function. It's just none of its business. User defines parameters=
.. User defines their types. User decides, if they are of the same type or n=
ot.<br><br></div><div style=3D"margin-left:40px"><span style=3D"font-family=
:monospace,monospace">merge(</span><span style=3D"font-family:monospace,mon=
ospace">Container src_a, </span><span style=3D"font-family:monospace,monosp=
ace">Container src_b, Container output)</span></div><div><br></div><div>Do =
i want `src_a', `src_b' and `output' be of the same type? No.</=
div></div></blockquote></span><div><br>I would say that your `merge` functi=
on here is underconstrained. Why? Because even if those different `Containe=
r` instances could deduce different types, those three different types need=
to have something in common. Namely, that the value type from `src_a` and =
`src_b` are convertible to the value type for `output`.<br><br>So if you ac=
tually applied all of the constraints that your function needs, you <i>coul=
dn't</i> use terse syntax. So this is not an example of the problem.<br=
><br>And I think that leads to an interesting question. How often do you ha=
ve a function which:<br><br>1) Takes two arguments that can be of different=
types.<br><br>2) Those two arguments are constrained by the same concept.<=
br><br>3) There are no additional constraints on those types that would pre=
vent you from using terse syntax.<br><br>Take your suggestion for `compare`=
.. The first range and second range need not be the same types. <i>But</i>, =
they do need to have comparable value types. And a properly constrained tem=
plate function will apply that constraint, so that users who pass the wrong=
things will get reasonable errors. And you can't apply such a constrai=
nt with terse syntax.<br><br>I'd bet that 90% of the time that #1 and #=
2 are true, there's probably some additional constraint that your funct=
ion requires of those two types.<br><br><i></i></div><span><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>- But, because `Container'=
; placed where types are placed, someone might think that it's a type. =
That is confusing for that someone, lets make types the same. - Okay, but w=
hat is about ones who is not confused, who actually learned the language? W=
hy make them pay and suffer? Is ones who don't learned prioritized over=
ones who learned?<br></div></div></blockquote></span><div><br>Why make the=
language more confusing to users? Why make people <i>have</i> to learn eso=
teric rules?<br><br><i>Somebody</i> will be inconvenienced no matter what y=
ou do. Why is your side the one that deserves to have the special syntax? I=
ndeed, you seem to argue exactly why they shouldn't: because they'r=
e the ones who are willing to learn and use arcane rules. And therefore, th=
ey will be less inconvenienced by such arcane rules than if you do it the o=
ther way around.<br><br></div><span><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div>And how is that even possible that someone will try =
to use a function like above, without actually knowing what is a `Container=
'?</div></div></blockquote></span><div><br>The same way that people use=
std::vector without knowing that the type it takes actually has minimum re=
quirements.<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>If you have a docs, you'll read that `merge' is=
a template function that accepts three objects, types of which meet a requ=
irements of the `Container' concept. And if you doesn't have a docs=
you will go to source code and see for yourself that `Container' is no=
t a type.<br><br>I say, there is no source of confusion. Right now, confusi=
on is not in the heads of a users.<br></div><div><br>Oh, and that terse syn=
tax hides that it's a template function. - But that is not a problem. I=
t is purpose of that syntax, to get rid of template boilerplate, no?</div><=
/div></blockquote></span><div><br>The purpose of terse syntax is to minimiz=
e template boilerplate in the most common and useful of cases. It is not in=
tended to be a full-fledged <i>replacement</i> for declaring template funct=
ions. There will always be cases where you need to use full template syntax=
..<br><br>The question is why should your case be the one that gets favoriti=
sm?<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div><div></div><div>I used different declaration to show tha=
t i don't need InputIterator to force same type for begin and end, if i=
need same types i define them to be the same. Just like i do right now, by=
the way, by writing<br><div style=3D"margin-left:40px"><br></div><div styl=
e=3D"margin-left:40px"><font face=3D"monospace,monospace">template <type=
name I, typename O><br></font></div><div style=3D"margin-left:40px"><fon=
t face=3D"monospace,monospace">O copy(I begin, I end, O out)<br><br></font>=
</div>I don't need obscure rules to define begin and end to be of the s=
ame type. I can use template-introduction for that, which is perfectly suit=
able. And by allowing constrained parameters with same constraints be of di=
fferent types, it's will be also easier to write functions where you ju=
st doesn't care about actual types. And if it's not enough, you alw=
ays have usual template syntax, for both cases. Cake for you, and cake for =
you. Everyone is happy.<br></div></div></div></div></blockquote></span><div=
><br>Nobody has contested that full template syntax can do either one. Nobo=
dy has suggested that having terse syntax use one way means that the other =
way becomes impossible.<br><br>The question is who gets to use the simple s=
yntax. Simply declaring that the other side can still use full template syn=
tax is basically saying, "why don't you just let us win? After all=
, if you do, you lose."</div><br>Do a lot of people find this kind of =
argument convincing?<div><div><br>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
Cr7YROkpBwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"Cr7YROkpBwAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
;javascript:';return true;">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';ret=
urn true;" onclick=3D"this.href=3D'http://groups.google.com/a/isocpp.or=
g/group/std-proposals/';return true;">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
Cr7YROkpBwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"Cr7YROkpBwAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
;javascript:';return true;">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';ret=
urn true;" onclick=3D"this.href=3D'http://groups.google.com/a/isocpp.or=
g/group/std-proposals/';return true;">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
<br></div></div>
</blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5783_900882898.1448580550672--
------=_Part_5782_1320893473.1448580550671--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 27 Nov 2015 01:59:13 +0200
Raw View
On 27 November 2015 at 01:16, Andrei L <aendaerel@gmail.com> wrote:
>> Prove that the current syntax is not "the most common and useful of
>> cases".
> Ha! That is not working like that! Prove that it is.
Perhaps it doesn't work like that for a discussion. But that is the way it works
if you want to change a specification or a working draft; in order to
make a change,
you need to convince enough people to attain consensus to make a
change, otherwise
status quo will prevail.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Andrei L <aendaerel@gmail.com>
Date: Fri, 27 Nov 2015 05:10:45 +0500
Raw View
--089e01176311e4120205257a8569
Content-Type: text/plain; charset=UTF-8
2015-11-27 4:59 GMT+05:00 Ville Voutilainen <ville.voutilainen@gmail.com>:
> Perhaps it doesn't work like that for a discussion. But that is the way it
> works
> if you want to change a specification or a working draft; in order to
> make a change,
> you need to convince enough people to attain consensus to make a
> change, otherwise
> status quo will prevail.
>
No one doubts that.
That exchange was in context of the discussion or I am misunderstood
something?
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e01176311e4120205257a8569
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
2015-11-27 4:59 GMT+05:00 Ville Voutilainen <span dir=3D"ltr"><<a href=
=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">ville.voutilainen=
@gmail.com</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div id=3D":7g=
" class=3D"a3s" style=3D"overflow:hidden">Perhaps it doesn't work like =
that for a discussion. But that is the way it works<br>
if you want to change a specification or a working draft; in order to<br>
make a change,<br>
you need to convince enough people to attain consensus to make a<br>
change, otherwise<br>
status quo will prevail.</div></blockquote></div><br></div><div class=3D"gm=
ail_extra">No one doubts that.<br><br></div><div class=3D"gmail_extra">That=
exchange was in context of the discussion or I am misunderstood something?=
<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e01176311e4120205257a8569--
.
Author: Casey Carter <cartec69@gmail.com>
Date: Thu, 26 Nov 2015 20:59:12 -0800 (PST)
Raw View
------=_Part_4229_2142272194.1448600352406
Content-Type: multipart/alternative;
boundary="----=_Part_4230_1978760835.1448600352406"
------=_Part_4230_1978760835.1448600352406
Content-Type: text/plain; charset=UTF-8
On Thursday, November 26, 2015 at 11:50:46 AM UTC-6, Nicol Bolas wrote:
>
>
> What about Eric Niebler's and Casey Carter's STL2 version?
>>
>> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
>> requires
>> models::IndirectlyCopyable<I, O>
>> tagged_pair<tag::in(I), tag::out(O)>
>> copy(I first, S last, O result)
>> {
>> for (; first != last; ++first, ++result) {
>> *result = *first;
>> }
>> return {__stl2::move(first), __stl2::move(result)};
>> }
>>
>> It uses concepts already, but, where is a terse syntax here?
>>
>
> auto copy(InputIterator first, Sentinel<InputIterator> last,
> OutputIterator result) requires IndirectlyCopyable<InputIterator,
> OutputIterator>
>
> I'm not sure about whether `Sentinel<InputIterator>` can work as a
> constrained-type-name. But other than that though, what's the problem?
>
>
According to N4553, a partial-concept-id is perfectly acceptable as a
placeholder in a parameter declaration of an abbreviated function template
- there's even an example that includes such a usage. However, there's
nothing in N4553 to indicate that the replacement of placeholder parameter
types with invented template parameters in the parameter-declaration-clause
also happens in an associated requires-clause. That does seem like a
consistent extension to me, and it would allow terse syntax to be
applicable to many more cases. Someone should propose it.
(You also technically need to replace the occurrences of OutputIterator
with WeaklyIncrementable for this declaration to be equivalent, but I'm
nitpicking and it has no bearing on the discussion.)
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4230_1978760835.1448600352406
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, November 26, 2015 at 11:50:46 AM UTC-6, Nicol Bolas wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div></di=
v><div>What about Eric Niebler's and Casey Carter's STL2 version?<b=
r><br><div style=3D"margin-left:40px"><span style=3D"font-family:monospace,=
monospace">template <InputIterator I, Sentinel<I> S, WeaklyIncreme=
ntable O><br>=C2=A0 requires<br>=C2=A0=C2=A0=C2=A0 models::IndirectlyCop=
yable<I, O><br>=C2=A0 tagged_pair<tag::in(I), tag::out(O)><br>=
=C2=A0 copy(I first, S last, O result)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 fo=
r (; first !=3D last; ++first, ++result) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 *result =3D *first;<br>=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 retur=
n {__stl2::move(first), __stl2::move(result)};<br>=C2=A0 }</span><br></div>=
</div><div><br></div><div>It uses concepts already, but, where is a terse s=
yntax here?<br></div></div></blockquote><div><br><div style=3D"background-c=
olor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bord=
er-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">au=
to</span><span style=3D"color:#000"> copy</span><span style=3D"color:#660">=
(</span><span style=3D"color:#606">InputIterator</span><span style=3D"color=
:#000"> first</span><span style=3D"color:#660">,</span><span style=3D"color=
:#000"> </span><span style=3D"color:#606">Sentinel</span><span style=3D"col=
or:#660"><</span><span style=3D"color:#606">InputIterator</span><span st=
yle=3D"color:#660">></span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#008">last</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">OutputIterator</span><sp=
an style=3D"color:#000"> result</span><span style=3D"color:#660">)</span><s=
pan style=3D"color:#000"> requires </span><span style=3D"color:#606">Indire=
ctlyCopyable</span><span style=3D"color:#660"><</span><span style=3D"col=
or:#606">InputIterat<wbr>or</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#606">OutputIterator</spa=
n><span style=3D"color:#660">></span></div></code></div><br>I'm not =
sure about whether `Sentinel<InputIterator>` can work as a constraine=
d-type-name. But other than that though, what's the problem?<br>=C2=A0<=
/div></div></blockquote><div><br></div><div>According to N4553, a partial-c=
oncept-id is perfectly acceptable as a placeholder in a parameter declarati=
on of an abbreviated function template - there's even an example that i=
ncludes such a usage. However, there's nothing in N4553 to indicate tha=
t the replacement of placeholder parameter types with invented template par=
ameters in the parameter-declaration-clause also happens in an associated r=
equires-clause. That does seem like a consistent extension to me, and it wo=
uld allow terse syntax to be applicable to many more cases. Someone should =
propose it.</div><div><br></div><div>(You also technically need to replace =
the occurrences of OutputIterator with WeaklyIncrementable for this declara=
tion to be equivalent, but I'm nitpicking and it has no bearing on the =
discussion.)</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4230_1978760835.1448600352406--
------=_Part_4229_2142272194.1448600352406--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 27 Nov 2015 07:55:15 -0800 (PST)
Raw View
------=_Part_10493_1536255867.1448639715667
Content-Type: multipart/alternative;
boundary="----=_Part_10494_1960735259.1448639715667"
------=_Part_10494_1960735259.1448639715667
Content-Type: text/plain; charset=UTF-8
On Thursday, November 26, 2015 at 1:07:40 PM UTC-5, Ville Voutilainen wrote:
>
> On 26 November 2015 at 19:50, Nicol Bolas <jmck...@gmail.com <javascript:>>
> wrote:
> > Or more to the point, if I do this:
> >
> > void foo(Thingy t)
> > {
> > Thingy j = <expr>;
> > static_assert(is_same<decltype(t), decltype(j)>::value, "Why should
> this
> > ever be false?");
> > }
> > Given absolutely no knowledge of what `Thingy` is, why should any user
> ever
> > expect that assert to trigger? Or more to the point, if we define terse
>
> With the current semantics as implemented by gcc, that assert may very
> well trigger, so I don't follow
> what point you're making here. Multiple occurrences of Thingy in the
> parameter
> list are required to be of the same type, but occurrences of Thingy in
> the function
> body are not required to be of that type.
>
.... I see what I did now.
I misread 7.1.6.4, p4. It's talking about the equivalence between
constrained-type-specifiers in parameter lists and the *return type*, but I
thought it operated throughout the entire function definition.
So never mind.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_10494_1960735259.1448639715667
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, November 26, 2015 at 1:07:40 PM UTC-5, Ville Voutilainen wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;">On 26 November 2015 at 19:50,=
Nicol Bolas <<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"WDqttNEkBwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';re=
turn true;">jmck...@gmail.com</a>> wrote:
<br>> Or more to the point, if I do this:
<br>>
<br>> void foo(Thingy t)
<br>> {
<br>> =C2=A0 Thingy j =3D <expr>;
<br>> =C2=A0 static_assert(is_same<<wbr>decltype(t), decltype(j)>:=
:value, "Why should this
<br>> ever be false?");
<br>> }
<br>> Given absolutely no knowledge of what `Thingy` is, why should any =
user ever
<br>> expect that assert to trigger? Or more to the point, if we define =
terse
<br>
<br>With the current semantics as implemented by gcc, that assert may very
<br>well trigger, so I don't follow
<br>what point you're making here. Multiple occurrences of Thingy in th=
e parameter
<br>list are required to be of the same type, but occurrences of Thingy in
<br>the function
<br>body are not required to be of that type.
<br></blockquote><div><br>... I see what I did now.<br><br>I misread 7.1.6.=
4, p4. It's talking about the equivalence between constrained-type-spec=
ifiers in parameter lists and the <i>return type</i>, but I thought it oper=
ated throughout the entire function definition.<br><br>So never mind.<br></=
div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_10494_1960735259.1448639715667--
------=_Part_10493_1536255867.1448639715667--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 27 Nov 2015 08:33:25 -0800 (PST)
Raw View
------=_Part_745_319504255.1448642005283
Content-Type: multipart/alternative;
boundary="----=_Part_746_716022000.1448642005283"
------=_Part_746_716022000.1448642005283
Content-Type: text/plain; charset=UTF-8
On Thursday, November 26, 2015 at 6:16:15 PM UTC-5, Andrei L wrote:
>
>
> 2015-11-26 22:50 GMT+05:00 Nicol Bolas <jmck...@gmail.com <javascript:>>:
>
>> I'm not sure about whether `Sentinel<InputIterator>` can work as a
>> constrained-type-name. But other than that though, what's the problem?
>
>
> The problem is that same-type-terse-syntax is not used. Most useful case
> did not applied.
>
My point was that the current Concepts TS does not in any way preclude you
from writing this using abbreviated function template syntax. It doesn't
matter if this particular function doesn't make use of type consistency in
abbreviated functions. So long as it doesn't *preclude* you from writing
this example, it's meaningless.
Prove that the current syntax is not "the most common and useful of cases".
>>
>
> Ha! That is not working like that! Prove that it is.
>
Who has the burden of proof here? Concepts TS is an ISO standard that is
being implemented as we speak. Therefore, the person requesting a change is
the one upon whom the burden of proof rests. Not to mention, providing
evidence *always* makes your case stronger, even if the burden of proof
isn't on you.
And it's not even that hard. If you want to prove which is more common,
just go through the standard library and ranges TS algorithms, and see how
many of them could use abbreviated function template syntax under the
current concepts TS and how many could use it under your proposed changes.
If you are correct about what is "the most common and useful of cases",
then evidence shouldn't be that hard to find, right?
STL1 is not the only now, and most probably, it will not use terse syntax.
>>>
>>
>> ... again, so what? Does it need to?
>>
>> Right now, the algorithms and iterator libraries can't effectively use
>> concepts at all. This is due to the fact that it wasn't designed with such
>> constraints in mind, and imposing reasonable constraints now will likely
>> break a lot of people's code.
>>
>
> You just proved that it is not.
>
*ahem*: "imposing reasonable constraints now will likely break a lot of
people's code."
Nothing I showed proved in any way that *that statement* was false. Yes,
you could conceptualize the standard library. But you can't do it
retroactively, when people have been (silently) violating constraints for
decades.
> I wouldn't expect someone to write the latter "for the sake of consistency"
>>
>
> Do you write curly braces on the same or on the next line? Do you jump
> between styles? That is, you choose one style and you write using that
> style.
>
Are we even talking about the same thing? Because your statement here
doesn't seem to address the point.
You will not be able to write everything in terse syntax, and there's no
getting around that fact. Because of that, you *will* have to select your
syntax based on what you *can* use for your particular use case. You will
have functions that can use terse syntax and you will have functions that
can't.
Consistency of using terse syntax is not achievable. Therefore, what does
it matter if some cases require falling back to full template syntax?
Without same-type rule it could be written like that:
>>>
>>
>>>
>> auto maybe_same(R p1, R p2)
>>>
>>
>>> R {T} auto same(T p1, T p2)
>>>
>>
>>> Aaand consistent version looks kinda, better than others.. maybe just
>>> more familliar. But first version, i don't like it at all.
>>>
>>
>> I can't say that I agree that this is "consistent".
>>
>
> By consistent version i meant example with `template <typename>`s
>
It's obvious you meant that, but that doesn't make it consistent as far as
I'm concerned. You're still introducing a template parameter, just with a
different syntax that doesn't use the word "template". In fact, this form
of `same` doesn't even use abbreviated function template syntax at all. So
it doesn't trigger that part of the compiler.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_746_716022000.1448642005283
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Thursday, November 26, 2015 at 6:16:15 PM UTC-5=
, Andrei L wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><br><div class=3D"gmail_quote">2015-11-26 22:50 GMT+05:00 Nicol Bo=
las <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obf=
uscated-mailto=3D"H_2jr6g1BwAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascri=
pt:';return true;">jmck...@gmail.com</a>></span>:<br><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex">I'm not sure about whether `Sentinel=
<InputIterator>` can work as a constrained-type-name. But other than =
that though, what's the problem?</blockquote></div><br></div><div>The p=
roblem is that same-type-terse-syntax is not used. Most useful case did not=
applied.<br></div></div></blockquote><div><br>My point was that the curren=
t Concepts TS does not in any way preclude you from writing this using abbr=
eviated function template syntax. It doesn't matter if this particular =
function doesn't make use of type consistency in abbreviated functions.=
So long as it doesn't <i>preclude</i> you from writing this example, i=
t's meaningless.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div><blockquote style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quot=
e">Prove that the current syntax is not "the most common and useful of=
cases".<br></blockquote><div><br></div><div>Ha! That is not working l=
ike that! Prove that it is.<br></div></div></div></blockquote><div><br>Who =
has the burden of proof here? Concepts TS is an ISO standard that is being =
implemented as we speak. Therefore, the person requesting a change is the o=
ne upon whom the burden of proof rests. Not to mention, providing evidence =
<i>always</i> makes your case stronger, even if the burden of proof isn'=
;t on you.<br><br>And it's not even that hard. If you want to prove whi=
ch is more common, just go through the standard library and ranges TS algor=
ithms, and see how many of them could use abbreviated function template syn=
tax under the current concepts TS and how many could use it under your prop=
osed changes.<br><br>If you are correct about what is "the most common=
and useful of cases", then evidence shouldn't be that hard to fin=
d, right?<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><div><div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><span=
><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border=
-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>ST=
L1 is not the only now, and most probably, it will not use terse syntax.</d=
iv></div></blockquote></span><div><br>... again, so what? Does it need to?<=
br><br>Right
now, the algorithms and iterator libraries can't effectively use=20
concepts at all. This is due to the fact that it wasn't designed with=
=20
such constraints in mind, and imposing reasonable constraints now will=20
likely break a lot of people's code.</div></blockquote>=C2=A0<br></div>=
<div>You just proved that it is not.<br></div></div></div></blockquote><div=
><br>*ahem*: "imposing reasonable constraints now will=20
likely break a lot of people's code."<br><br>Nothing I showed prov=
ed in any way that <i>that statement</i> was false. Yes, you could conceptu=
alize the standard library. But you can't do it retroactively, when peo=
ple have been (silently) violating constraints for decades.<br>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div><bl=
ockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,20=
4,204);padding-left:1ex" class=3D"gmail_quote">I wouldn't expect someon=
e to write the latter "for the sake of consistency"<br></blockquo=
te><div><br></div><div>Do you write curly braces on the same or on the next=
line? Do you jump between styles? That is, you choose one style and you wr=
ite using that style.<br></div></div></div></div></blockquote><div><br>Are =
we even talking about the same thing? Because your statement here doesn'=
;t seem to address the point.<br><br>You will not be able to write everythi=
ng in terse syntax, and there's no getting around that fact. Because of=
that, you <i>will</i> have to select your syntax based on what you <i>can<=
/i> use for your particular use case. You will have functions that can use =
terse syntax and you will have functions that can't.<br><br>Consistency=
of using terse syntax is not achievable. Therefore, what does it matter if=
some cases require falling back to full template syntax?<br><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div><div><b=
lockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,2=
04,204);padding-left:1ex" class=3D"gmail_quote"><span><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Without same-type rule i=
t could be written like that:</div></div></blockquote></span></blockquote><=
blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,=
204,204);padding-left:1ex" class=3D"gmail_quote"><blockquote style=3D"margi=
n:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex=
" class=3D"gmail_quote"><div>=C2=A0</div></blockquote></blockquote><blockqu=
ote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex" class=3D"gmail_quote"><span><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex"><div dir=3D"ltr"><div><div style=3D"margin-left:40px=
"><span style=3D"font-family:monospace,monospace">auto maybe_same(R p1, R p=
2)</span></div></div></div></blockquote></span><span><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div style=3D"margin-left=
:40px"><span style=3D"font-family:monospace,monospace"></span></div></div><=
/div></blockquote></span><blockquote style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">=
<br></blockquote><span><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><d=
iv dir=3D"ltr"><div><div style=3D"margin-left:40px"><span style=3D"font-fam=
ily:monospace,monospace"></span></div><span style=3D"font-family:monospace,=
monospace"></span><span style=3D"font-family:monospace,monospace"></span><d=
iv style=3D"margin-left:40px"><span style=3D"font-family:monospace,monospac=
e">R {T} auto same(T p1, T p2)</span></div></div></div></blockquote></span>=
<blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex" class=3D"gmail_quote"><br></blockquote><span><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Aaand=
consistent version looks kinda, better than others.. maybe just more famil=
liar. But first version, i don't like it at all.</div></div></blockquot=
e></span><span></span><br>I can't say that I agree that this is "c=
onsistent".<br></blockquote><div><br></div><div>By consistent version =
i meant example with `template <typename>`s<br></div></div></div></di=
v></div></blockquote><div><br>It's obvious you meant that, but that doe=
sn't make it consistent as far as I'm concerned. You're still i=
ntroducing a template parameter, just with a different syntax that doesn=
9;t use the word "template". In fact, this form of `same` doesn&#=
39;t even use abbreviated function template syntax at all. So it doesn'=
t trigger that part of the compiler.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_746_716022000.1448642005283--
------=_Part_745_319504255.1448642005283--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 27 Nov 2015 08:38:39 -0800 (PST)
Raw View
------=_Part_287_1483737679.1448642319108
Content-Type: multipart/alternative;
boundary="----=_Part_288_1406255125.1448642319108"
------=_Part_288_1406255125.1448642319108
Content-Type: text/plain; charset=UTF-8
On Thursday, November 26, 2015 at 11:59:12 PM UTC-5, Casey Carter wrote:
>
> On Thursday, November 26, 2015 at 11:50:46 AM UTC-6, Nicol Bolas wrote:
>>
>>
>> What about Eric Niebler's and Casey Carter's STL2 version?
>>>
>>> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
>>> requires
>>> models::IndirectlyCopyable<I, O>
>>> tagged_pair<tag::in(I), tag::out(O)>
>>> copy(I first, S last, O result)
>>> {
>>> for (; first != last; ++first, ++result) {
>>> *result = *first;
>>> }
>>> return {__stl2::move(first), __stl2::move(result)};
>>> }
>>>
>>> It uses concepts already, but, where is a terse syntax here?
>>>
>>
>> auto copy(InputIterator first, Sentinel<InputIterator> last,
>> OutputIterator result) requires IndirectlyCopyable<InputIterator,
>> OutputIterator>
>>
>> I'm not sure about whether `Sentinel<InputIterator>` can work as a
>> constrained-type-name. But other than that though, what's the problem?
>>
>>
>
> According to N4553, a partial-concept-id is perfectly acceptable as a
> placeholder in a parameter declaration of an abbreviated function template
> - there's even an example that includes such a usage. However, there's
> nothing in N4553 to indicate that the replacement of placeholder parameter
> types with invented template parameters in the parameter-declaration-clause
> also happens in an associated requires-clause. That does seem like a
> consistent extension to me, and it would allow terse syntax to be
> applicable to many more cases. Someone should propose it.
>
That sounds more like a defect. Granted, you can `decltype` your way around
it, so they may just NAD it. But it does seem quite odd.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_288_1406255125.1448642319108
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, November 26, 2015 at 11:59:12 PM UTC-5, Casey Carter wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">On Thursday, November 26, 2015 at=
11:50:46 AM UTC-6, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div></div><div></div><div>What about Eric Niebler's =
and Casey Carter's STL2 version?<br><br><div style=3D"margin-left:40px"=
><span style=3D"font-family:monospace,monospace">template <InputIterator=
I, Sentinel<I> S, WeaklyIncrementable O><br>=C2=A0 requires<br>=
=C2=A0=C2=A0=C2=A0 models::IndirectlyCopyable<I, O><br>=C2=A0 tagged_=
pair<tag::in(I), tag::out(O)><br>=C2=A0 copy(I first, S last, O resul=
t)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 for (; first !=3D last; ++first, ++res=
ult) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *result =3D *first;<br>=C2=A0=C2=
=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 return {__stl2::move(first), __stl2::move=
(result)};<br>=C2=A0 }</span><br></div></div><div><br></div><div>It uses co=
ncepts already, but, where is a terse syntax here?<br></div></div></blockqu=
ote><div><br><div style=3D"background-color:rgb(250,250,250);border-color:r=
gb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><=
code><div><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
copy</span><span style=3D"color:#660">(</span><span style=3D"color:#606">I=
nputIterator</span><span style=3D"color:#000"> first</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:=
#606">Sentinel</span><span style=3D"color:#660"><</span><span style=3D"c=
olor:#606">InputIterator</span><span style=3D"color:#660">></span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">last</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#606">OutputIterator</span><span style=3D"color:#000"> result</sp=
an><span style=3D"color:#660">)</span><span style=3D"color:#000"> requires =
</span><span style=3D"color:#606">IndirectlyCopyable</span><span style=3D"c=
olor:#660"><</span><span style=3D"color:#606">InputIterat<wbr>or</span><=
span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span =
style=3D"color:#606">OutputIterator</span><span style=3D"color:#660">></=
span></div></code></div><br>I'm not sure about whether `Sentinel<Inp=
utIterator>` can work as a constrained-type-name. But other than that th=
ough, what's the problem?<br>=C2=A0</div></div></blockquote><div><br></=
div><div>According to N4553, a partial-concept-id is perfectly acceptable a=
s a placeholder in a parameter declaration of an abbreviated function templ=
ate - there's even an example that includes such a usage. However, ther=
e's nothing in N4553 to indicate that the replacement of placeholder pa=
rameter types with invented template parameters in the parameter-declaratio=
n-clause also happens in an associated requires-clause. That does seem like=
a consistent extension to me, and it would allow terse syntax to be applic=
able to many more cases. Someone should propose it.</div></blockquote><div>=
<br>That sounds more like a defect. Granted, you can `decltype` your way ar=
ound it, so they may just NAD it. But it does seem quite odd.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_288_1406255125.1448642319108--
------=_Part_287_1483737679.1448642319108--
.
Author: Andrei L <aendaerel@gmail.com>
Date: Sat, 28 Nov 2015 06:47:10 +0500
Raw View
--001a1137be2882fe9905258ffc4d
Content-Type: text/plain; charset=UTF-8
2015-11-27 21:33 GMT+05:00 Nicol Bolas <jmckesson@gmail.com>:
> It's obvious you meant that, but that doesn't make it consistent as far as
> I'm concerned.
> I wouldn't expect someone to write the latter "for the sake of consistency"
>>
>>
>>
> Do you write curly braces on the same or on the next line? Do you jump
>> between styles? That is, you choose one style and you write using that
>> style.
>>
>
> Are we even talking about the same thing? Because your statement here
> doesn't seem to address the point.
>
Consistency of using same syntax, and not jumping around using different
style of code? Where do you write braces, naming convention, other things
like that. This is important. What syntax to use for declaring template
functions, and when, will become part of these things.
You're still introducing a template parameter, just with a different syntax
> that doesn't use the word "template". In fact, this form of `same` doesn't
> even use abbreviated function template syntax at all. So it doesn't trigger
> that part of the compiler.
>
I, wasn't wha..
Are we even talking about the same thing?
It seems like we're not. Misunderstanding happened at some point.
You will not be able to write everything in terse syntax, and there's no
> getting around that fact. Because of that, you *will* have to select your
> syntax based on what you *can* use for your particular use case. You will
> have functions that can use terse syntax and you will have functions that
> can't.
>
> Consistency of using terse syntax is not achievable. Therefore, what does
> it matter if some cases require falling back to full template syntax?
>
Yes, yes i agree with that. With what i don't agree is that using same
concept for different parameters forces me to use different syntax to
explicitly specify that i don't care if they have same type or not.
My point was that the current Concepts TS does not in any way preclude you
> from writing this using abbreviated function template syntax. It doesn't
> matter if this particular function doesn't make use of type consistency in
> abbreviated functions. So long as it doesn't *preclude* you from writing
> this example, it's meaningless.
I asked wrong question.
template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
> requires
> models::IndirectlyCopyable<I, O>
> tagged_pair<tag::in(I), tag::out(O)>
> copy(I first, S last, O result)
That question, "It uses concepts already, but, where is a terse syntax
here?", should be, "<..> where is our common case here?"
And it's not even that hard. If you want to prove which is more common,
> just go through the standard library and ranges TS algorithms, and see how
> many of them could use abbreviated function template syntax under the
> current concepts TS and how many could use it under your proposed changes.
>
Ranges TS - none, because it uses iterator sentinel pairs. STL2 - none, for
same reason. STL - could use, could not, you can't say, and as we found,
abbreviated function template syntax forces us to use decltype, so i'd
expect that `template <typename T>` will stay.
If you are correct about what is "the most common and useful of cases",
> then evidence shouldn't be that hard to find, right?
Ranges TS and STL2. That is enough to drop "the most common" part. That is
also enough to drop "the most useful" part.
Who has the burden of proof here? Concepts TS is an ISO standard that is
> being implemented as we speak. Therefore, the person requesting a change is
> the one upon whom the burden of proof rests. Not to mention, providing
> evidence *always* makes your case stronger, even if the burden of proof
> isn't on you.
I showed example, where same-type rule is not helping and is not used, and
has no use. I showed example where it is questionable if it will be used or
not, so you can't rely on that. Then i asked, "Where is it applies?" What i
got? "Prove that it's not". Like, if you can't prove that it's not then it
is true, but where is a proof that it is true?
I came here because i was curious, why that decision was made. I wanted to
know a reason, but all what was behind that is - because STL uses iterator
pairs (Thing that share same concept are having same type, because in STL
begin and end iterators have same type. Great reason).
auto copy(InputIterator first, Sentinel<InputIterator> last, OutputIterator
result) requires IndirectlyCopyable<InputIterator, OutputIterator>
Now, finally, with this example it is obvious, why would you want same
concept names be replaced with same type. Not excuses with confused library
writers, and users familiar with templates (you don't expect just starters
writing a template functions and classes right?).
So, from one hand, there is cases where same-type rule can be useful, there
is also cases where it is not, from the other hand this rule is illogical,
and without that rule you could have a way to care only about objects
behavior and not it's actual type, and all what you loose is that at some
cases you need to explicitly specify that some things have same type, when
you want them to have same type.
At that point i have nothing more to say.
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a1137be2882fe9905258ffc4d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
2015-11-27 21:33 GMT+05:00 Nicol Bolas <span dir=3D"ltr"><<a href=3D"mai=
lto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></spa=
n>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
border-left:1px solid rgb(204,204,204);padding-left:1ex">It's obvious y=
ou meant that, but that doesn't make it consistent as far as I'm co=
ncerned.</blockquote><div>=C2=A0</div></div><blockquote style=3D"margin:0px=
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" cla=
ss=3D"gmail_quote"><span class=3D"im"><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddi=
ng-left:1ex"><div dir=3D"ltr"><div><div><blockquote style=3D"margin:0px 0px=
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=
=3D"gmail_quote">I wouldn't expect someone to write the latter "fo=
r the sake of consistency"</blockquote></div></div></div></blockquote>=
</span></blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><bloc=
kquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex" class=3D"gmail_quote"><div>=C2=A0</div></blockquote>=
</blockquote><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px =
solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><span class=
=3D"im"></span><span class=3D"im"><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div dir=3D"ltr"><div><div><div>Do
you write curly braces on the same or on the next line? Do you jump=20
between styles? That is, you choose one style and you write using that=20
style.</div></div></div></div></blockquote></span><span class=3D"im"></span=
><br>Are we even talking about the same thing? Because your statement here =
doesn't seem to address the point.<br></blockquote><br></div><div class=
=3D"gmail_extra">Consistency of using same syntax, and not jumping around u=
sing different style of code? Where do you write braces, naming convention,=
other things like that. This is important. What syntax to use for declarin=
g template functions, and when, will become part of these things.<br><br><b=
lockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,2=
04,204);padding-left:1ex" class=3D"gmail_quote">You're still introducin=
g a template parameter, just with a different=20
syntax that doesn't use the word "template". In fact, this fo=
rm of=20
`same` doesn't even use abbreviated function template syntax at all. So=
=20
it doesn't trigger that part of the compiler.<br></blockquote><div><div=
><br></div><div>I, wasn't wha..<br></div><div><br><blockquote style=3D"=
margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex" class=3D"gmail_quote">Are we even talking about the same thing?</blo=
ckquote><div><br></div><div>It seems like we're not. Misunderstanding h=
appened at some point.<br></div></div><div><br><blockquote style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" =
class=3D"gmail_quote">You will not be able to write everything in terse syn=
tax, and there's no getting around that fact. Because of that, you <i>w=
ill</i> have to select your syntax based on what you <i>can</i> use for you=
r particular use case. You will have functions that can use terse syntax an=
d you will have functions that can't.<br><br>Consistency
of using terse syntax is not achievable. Therefore, what does it matter
if some cases require falling back to full template syntax?<br></blockquot=
e><div><br></div><div>Yes, yes i agree with that. With what i don't agr=
ee is that using same concept for different parameters forces me to use dif=
ferent syntax to explicitly specify that i don't care if they have same=
type or not.<br></div></div><br><blockquote style=3D"margin:0px 0px 0px 0.=
8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail=
_quote">My point was that the current Concepts TS does not in any way precl=
ude=20
you from writing this using abbreviated function template syntax. It=20
doesn't matter if this particular function doesn't make use of type=
=20
consistency in abbreviated functions. So long as it doesn't <i>preclude=
</i> you from writing this example, it's meaningless.</blockquote><div>=
<br></div><div>I asked wrong question.<span><br></span><br><blockquote styl=
e=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddin=
g-left:1ex" class=3D"gmail_quote"><span><span style=3D"font-family:monospac=
e,monospace">template <InputIterator I, Sentinel<I> S, WeaklyIncre=
mentable O><br>=C2=A0 requires<br>=C2=A0=C2=A0=C2=A0 models::IndirectlyC=
opyable<I, O><br>=C2=A0 tagged_pair<tag::in(I), tag::out(O)><br=
>=C2=A0 copy(I first, S last, O result)</span></span></blockquote><br> That=
question, "<span>It uses concepts already, but, where is a terse synt=
ax here?", should=C2=A0 be, "<..> where is our common case =
here?"</span><br><div><div><br></div><blockquote style=3D"margin:0px 0=
px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=
=3D"gmail_quote">And
it's not even that hard. If you want to prove which is more common,=20
just go through the standard library and ranges TS algorithms, and see=20
how many of them could use abbreviated function template syntax under=20
the current concepts TS and how many could use it under your proposed=20
changes.<br></blockquote><div><br></div>Ranges TS - none, because it uses i=
terator sentinel pairs. STL2 - none, for same reason. STL - could use, coul=
d not, you can't say, and as we found, abbreviated function template sy=
ntax forces us to use decltype, so i'd expect that `template <typena=
me T>` will stay.<br><div><br></div><blockquote style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D=
"gmail_quote">If you are correct about what is "the most common and us=
eful of cases", then evidence shouldn't be that hard to find, righ=
t?</blockquote><div><br></div><div>Ranges TS and STL2. That is enough to dr=
op "the most common" part. That is also enough to drop "the =
most useful" part.<br><br><blockquote style=3D"margin:0px 0px 0px 0.8e=
x;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_q=
uote">Who has the burden of proof here? Concepts TS is an ISO standard that=
is
being implemented as we speak. Therefore, the person requesting a=20
change is the one upon whom the burden of proof rests. Not to mention,=20
providing evidence <i>always</i> makes your case stronger, even if the burd=
en of proof isn't on you.</blockquote><br>I showed example, where same-=
type rule is not helping and is not used,=20
and has no use. I showed example where it is questionable if it will be=20
used or not, so you can't rely on that. Then i asked, "Where is it=
=20
applies?" What i got? "Prove that it's not". Like, if yo=
u can't prove that it's not then it is true, but where is a proof t=
hat it is true?<br><br>I came here because i was curious, why that decision=
was made. I wanted to know a reason, but all what was behind that is - bec=
ause STL uses iterator pairs (Thing that share same concept are having same=
type, because in STL begin and end iterators have same type. Great reason)=
..<br><br><font size=3D"1"><span class=3D"im"><div style=3D"background-color=
:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-w=
idth:1px;word-wrap:break-word"><code><div><span style=3D"color:rgb(0,0,136)=
">auto</span><span style=3D"color:rgb(0,0,0)"> copy</span><span style=3D"co=
lor:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0,102)">InputItera=
tor</span><span style=3D"color:rgb(0,0,0)"> first</span><span style=3D"colo=
r:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(102,0,102)">Sentinel</span><span style=3D"color:rgb(102,10=
2,0)"><</span><span style=3D"color:rgb(102,0,102)">InputIterator</span><=
span style=3D"color:rgb(102,102,0)">></span><span style=3D"color:rgb(0,0=
,0)"> </span><span style=3D"color:rgb(0,0,136)">last</span><span style=3D"c=
olor:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span><span=
style=3D"color:rgb(102,0,102)">OutputIterator</span><span style=3D"color:r=
gb(0,0,0)"> result</span><span style=3D"color:rgb(102,102,0)">)</span><span=
style=3D"color:rgb(0,0,0)"> requires </span><span style=3D"color:rgb(102,0=
,102)">IndirectlyCopyable</span><span style=3D"color:rgb(102,102,0)"><</=
span><span style=3D"color:rgb(102,0,102)">InputIterator</span><span style=
=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(102,0,102)">OutputIterator</span><span style=3D"co=
lor:rgb(102,102,0)">></span></div></code></div></span></font><br></div><=
div>Now, finally, with this example it is obvious, why would you want same =
concept names be replaced with same type. Not excuses with confused library=
writers, and users familiar with templates (you don't expect just star=
ters writing a template functions and classes right?).<br><br></div><div>So=
, from one hand, there is cases where same-type rule can be useful, there i=
s also cases where it is not, from the other hand this rule is illogical, a=
nd without that rule you could have a way to care only about objects behavi=
or and not it's actual type, and all what you loose is that at some cas=
es you need to explicitly specify that some things have same type, when you=
want them to have same type.<br><br></div><div>At that point i have nothin=
g more to say.<br></div></div></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a1137be2882fe9905258ffc4d--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 28 Nov 2015 14:11:59 +0100
Raw View
This is a multi-part message in MIME format.
--------------050507070401000304050604
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 27/11/2015 17:38, Nicol Bolas a =C3=A9crit :
> On Thursday, November 26, 2015 at 11:59:12 PM UTC-5, Casey Carter wrote:
>> On Thursday, November 26, 2015 at 11:50:46 AM UTC-6, Nicol Bolas wrote:
>>>
>>> What about Eric Niebler's and Casey Carter's STL2 version?
>>>> template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
>>>> requires
>>>> models::IndirectlyCopyable<I, O>
>>>> tagged_pair<tag::in(I), tag::out(O)>
>>>> copy(I first, S last, O result)
>>>> {
>>>> for (; first !=3D last; ++first, ++result) {
>>>> *result =3D *first;
>>>> }
>>>> return {__stl2::move(first), __stl2::move(result)};
>>>> }
>>>>
>>>> It uses concepts already, but, where is a terse syntax here?
>>>>
>>> auto copy(InputIterator first, Sentinel<InputIterator> last,
>>> OutputIterator result) requires IndirectlyCopyable<InputIterator,
>>> OutputIterator>
>>>
>>> I'm not sure about whether `Sentinel<InputIterator>` can work as a
>>> constrained-type-name. But other than that though, what's the problem?
>>> =20
>>>
>> According to N4553, a partial-concept-id is perfectly acceptable as a
>> placeholder in a parameter declaration of an abbreviated function templa=
te
>> - there's even an example that includes such a usage. However, there's
>> nothing in N4553 to indicate that the replacement of placeholder paramet=
er
>> types with invented template parameters in the parameter-declaration-cla=
use
>> also happens in an associated requires-clause. That does seem like a
>> consistent extension to me, and it would allow terse syntax to be
>> applicable to many more cases. Someone should propose it.
>>
> That sounds more like a defect. Granted, you can `decltype` your way arou=
nd
> it, so they may just NAD it. But it does seem quite odd.
>
Could you clarify why this would be a defect?
Vicente
--=20
---=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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------050507070401000304050604
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">
<div class=3D"moz-cite-prefix">Le 27/11/2015 17:38, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:68cc2a1f-31bd-4cd2-873c-8818aa80acd3@isocpp.org"
type=3D"cite">
<pre wrap=3D"">On Thursday, November 26, 2015 at 11:59:12 PM UTC-5, C=
asey Carter wrote:
</pre>
<blockquote type=3D"cite">
<pre wrap=3D"">
On Thursday, November 26, 2015 at 11:50:46 AM UTC-6, Nicol Bolas wrote:
</pre>
<blockquote type=3D"cite">
<pre wrap=3D"">
What about Eric Niebler's and Casey Carter's STL2 version?
</pre>
<blockquote type=3D"cite">
<pre wrap=3D"">
template <InputIterator I, Sentinel<I> S, WeaklyIncrementable O>=
;
requires
models::IndirectlyCopyable<I, O>
tagged_pair<tag::in(I), tag::out(O)>
copy(I first, S last, O result)
{
for (; first !=3D last; ++first, ++result) {
*result =3D *first;
}
return {__stl2::move(first), __stl2::move(result)};
}
It uses concepts already, but, where is a terse syntax here?
</pre>
</blockquote>
<pre wrap=3D"">
auto copy(InputIterator first, Sentinel<InputIterator> last,=20
OutputIterator result) requires IndirectlyCopyable<InputIterator,=20
OutputIterator>
I'm not sure about whether `Sentinel<InputIterator>` can work as a=20
constrained-type-name. But other than that though, what's the problem?
=20
</pre>
</blockquote>
<pre wrap=3D"">
According to N4553, a partial-concept-id is perfectly acceptable as a=20
placeholder in a parameter declaration of an abbreviated function template=
=20
- there's even an example that includes such a usage. However, there's=20
nothing in N4553 to indicate that the replacement of placeholder parameter=
=20
types with invented template parameters in the parameter-declaration-clause=
=20
also happens in an associated requires-clause. That does seem like a=20
consistent extension to me, and it would allow terse syntax to be=20
applicable to many more cases. Someone should propose it.
</pre>
</blockquote>
<pre wrap=3D"">
That sounds more like a defect. Granted, you can `decltype` your way around=
=20
it, so they may just NAD it. But it does seem quite odd.
</pre>
</blockquote>
<font size=3D"+1">Could you clarify why this would be a defect?</font><=
br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------050507070401000304050604--
.
Author: barry.revzin@gmail.com
Date: Thu, 3 Dec 2015 12:46:45 -0800 (PST)
Raw View
------=_Part_390_262842325.1449175606030
Content-Type: multipart/alternative;
boundary="----=_Part_391_140549380.1449175606030"
------=_Part_391_140549380.1449175606030
Content-Type: text/plain; charset=UTF-8
I'll throw in a contrary opinion here. What is the advantage of having
abbreviated function templates at all? It's barely even terser. The
following:
void foo(InputIterator a, InputIterator b);
is a mere SEVEN characters shorter than the MUCH more understandable:
template <InputIterator It>
void foo(It a, It b);
Not to mention that the former devolves into this large argument about
whether or not a or b can have the same type or not, and whether or not
that makes sense or is reasonable, and cannot even support two different
types that both meet the InputIterator criteria. In the latter, it is
obvious that a and b have the same type and it is obvious how to provide
for two different InputIterators.
Seriously. Why.
On Monday, November 23, 2015 at 10:27:37 PM UTC-6, Andrei L wrote:
>
> Hello,
>
> I've been reading through the paper and noticed this:
>
> <..> An abbreviated function template is equivalent to a function template
>> (14.6.6) whose template-parameter-list includes one invented
>> template-parameter for each occurrence of a placeholder in the
>> parameter-declaration-clause, in order of appearance <..>
>>
>
> Is this means that in such code:
>
> template <typename T>
> concept bool R = CheckSomething<T>;
>
> auto foo(R a, R b) { /* ... */ }
>
> parameters `a' and `b' have the same type? And if so, why? What is the
> rationale behind that?
>
--
---
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-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_391_140549380.1449175606030
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I'll throw in a contrary opinion here. What is the adv=
antage of having abbreviated function templates at all? It's barely eve=
n terser. The following:<div><br></div><div>void foo(InputIterator a, Input=
Iterator b);</div><div><br></div><div>is a mere SEVEN characters shorter th=
an the MUCH more understandable:</div><div><br></div><div>template <Inpu=
tIterator It></div><div>void foo(It a, It b);</div><div><br></div><div>N=
ot to mention that the former devolves into this large argument about wheth=
er or not a or b can have the same type or not, and whether or not that mak=
es sense or is reasonable, and cannot even support two different types that=
both meet the InputIterator criteria. In the latter, it is obvious that a =
and b have the same type and it is obvious how to provide for two different=
InputIterators.=C2=A0</div><div><br></div><div>Seriously. Why. =C2=A0<br><=
br>On Monday, November 23, 2015 at 10:27:37 PM UTC-6, Andrei L wrote:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Hello,<br><br>I'=
;ve been reading through the paper and noticed this:<br><br><blockquote sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddi=
ng-left:1ex" class=3D"gmail_quote"><..> An abbreviated function templ=
ate is equivalent to a function template (14.6.6) whose template-parameter-=
list includes one invented template-parameter for each occurrence of a plac=
eholder in the parameter-declaration-clause, in order of appearance <..&=
gt;<br></blockquote><br>Is this means that in such code:<br><span style=3D"=
font-family:courier new,monospace"><br></span><div style=3D"margin-left:40p=
x"><span style=3D"font-family:courier new,monospace">template <typename =
T></span><br><span style=3D"font-family:courier new,monospace"></span><s=
pan style=3D"font-family:courier new,monospace">concept bool R =3D CheckSom=
ething<T>;</span><br><span style=3D"font-family:courier new,monospace=
"></span><br><span style=3D"font-family:courier new,monospace"></span><span=
style=3D"font-family:courier new,monospace">auto foo(R a, R b) { /* ... */=
}</span><br></div><span style=3D"font-family:courier new,monospace"></span=
><span style=3D"font-family:courier new,monospace"></span><br><div style=3D=
"text-align:left">parameters `a' and `b' have the same type? And if=
so, why? What is the rationale behind that?<br></div></div></blockquote></=
div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_391_140549380.1449175606030--
------=_Part_390_262842325.1449175606030--
.
Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Thu, 3 Dec 2015 21:30:02 +0000
Raw View
--Apple-Mail-E2ED4517-537D-4E18-8267-F43B1785D352
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
There's a strong push to rid modern c++ of its perceived verbosity. Range-b=
ased-for, auto and the proposed auto {x,y,z} for tuple result capture are a=
ll illustrative of this.
I'm sure there are deeper reasons for such a drive beyond reducing characte=
r count.
I'm an engineer not a language designer though. How will reducing the verbo=
sity alter the way we use the language?
> On 3 Dec 2015, at 20:46, barry.revzin@gmail.com wrote:
>=20
> I'll throw in a contrary opinion here. What is the advantage of having ab=
breviated function templates at all? It's barely even terser. The following=
:
>=20
> void foo(InputIterator a, InputIterator b);
>=20
> is a mere SEVEN characters shorter than the MUCH more understandable:
>=20
> template <InputIterator It>
> void foo(It a, It b);
>=20
> Not to mention that the former devolves into this large argument about wh=
ether or not a or b can have the same type or not, and whether or not that =
makes sense or is reasonable, and cannot even support two different types t=
hat both meet the InputIterator criteria. In the latter, it is obvious that=
a and b have the same type and it is obvious how to provide for two differ=
ent InputIterators.=20
>=20
> Seriously. Why. =20
>=20
>> On Monday, November 23, 2015 at 10:27:37 PM UTC-6, Andrei L wrote:
>> Hello,
>>=20
>> I've been reading through the paper and noticed this:
>>=20
>>> <..> An abbreviated function template is equivalent to a function templ=
ate (14.6.6) whose template-parameter-list includes one invented template-p=
arameter for each occurrence of a placeholder in the parameter-declaration-=
clause, in order of appearance <..>
>>=20
>> Is this means that in such code:
>>=20
>> template <typename T>
>> concept bool R =3D CheckSomething<T>;
>>=20
>> auto foo(R a, R b) { /* ... */ }
>>=20
>> parameters `a' and `b' have the same type? And if so, why? What is the r=
ationale behind that?
>=20
> --=20
>=20
> ---=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-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-propo=
sals/.
--=20
---=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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail-E2ED4517-537D-4E18-8267-F43B1785D352
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div></div><div>There's a strong push t=
o rid modern c++ of its perceived verbosity. Range-based-for, auto and the =
proposed auto {x,y,z} for tuple result capture are all illustrative of this=
..</div><div><br></div><div>I'm sure there are deeper reasons for such a dri=
ve beyond reducing character count.</div><div><br></div><div>I'm an enginee=
r not a language designer though. How will reducing the verbosity alter the=
way we use the language?</div><div><br>On 3 Dec 2015, at 20:46, <a href=3D=
"mailto:barry.revzin@gmail.com">barry.revzin@gmail.com</a> wrote:<br><br></=
div><blockquote type=3D"cite"><div><div dir=3D"ltr">I'll throw in a contrar=
y opinion here. What is the advantage of having abbreviated function templa=
tes at all? It's barely even terser. The following:<div><br></div><div>void=
foo(InputIterator a, InputIterator b);</div><div><br></div><div>is a mere =
SEVEN characters shorter than the MUCH more understandable:</div><div><br><=
/div><div>template <InputIterator It></div><div>void foo(It a, It b);=
</div><div><br></div><div>Not to mention that the former devolves into this=
large argument about whether or not a or b can have the same type or not, =
and whether or not that makes sense or is reasonable, and cannot even suppo=
rt two different types that both meet the InputIterator criteria. In the la=
tter, it is obvious that a and b have the same type and it is obvious how t=
o provide for two different InputIterators. </div><div><br></div><div>=
Seriously. Why. <br><br>On Monday, November 23, 2015 at 10:27:37 PM U=
TC-6, Andrei L wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">Hello,<br><br>I've been reading through the paper and noticed this=
:<br><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><..> An ab=
breviated function template is equivalent to a function template (14.6.6) w=
hose template-parameter-list includes one invented template-parameter for e=
ach occurrence of a placeholder in the parameter-declaration-clause, in ord=
er of appearance <..><br></blockquote><br>Is this means that in such =
code:<br><span style=3D"font-family:courier new,monospace"><br></span><div =
style=3D"margin-left:40px"><span style=3D"font-family:courier new,monospace=
">template <typename T></span><br><span style=3D"font-family:courier =
new,monospace"></span><span style=3D"font-family:courier new,monospace">con=
cept bool R =3D CheckSomething<T>;</span><br><span style=3D"font-fami=
ly:courier new,monospace"></span><br><span style=3D"font-family:courier new=
,monospace"></span><span style=3D"font-family:courier new,monospace">auto f=
oo(R a, R b) { /* ... */ }</span><br></div><span style=3D"font-family:couri=
er new,monospace"></span><span style=3D"font-family:courier new,monospace">=
</span><br><div style=3D"text-align:left">parameters `a' and `b' have the s=
ame type? And if so, why? What is the rationale behind that?<br></div></div=
></blockquote></div></div>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br>
</div></blockquote></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail-E2ED4517-537D-4E18-8267-F43B1785D352--
.
Author: Ren Industries <renindustries@gmail.com>
Date: Thu, 3 Dec 2015 17:42:09 -0500
Raw View
--001a114293a8eb167c05260619f4
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Have you heard of the Sapir=E2=80=93Whorf hypothesis?
In essence, the idea is the tools we use for thought change how we think.
While disproven in its strong form, it's clearly obvious in its weak form
in C++11 through an example: lambdas.
Lambdas don't really add any "power"; you can easily simulate them via an
explicit named functor, with explicit capture, which I still do in C++03.
However, they do make it much easier; for_each with lambdas is clean and
easy, where as with explicit functors it is rarely worthwhile.
Another example is constexpr; it is entirely possible to do without
constexpr, but would you want to write the metatemplate code every time?
In reality, since it is so verbose, you'd probably only write it when you
absolutely need the speed (such as numerical libraries).
With constexpr, it becomes trivial, which means you'll almost certainly do
it more, leading to faster, more elegant programs.
By making features less verbose, we make it easier to get simple things
done; while this adds no computational power to the language, I'd argue it
adds "linguistic power".
By adding this linguistic power, we change how people code.
By changing how people code, we can increase productivity and/or speed of
execution.
On Thu, Dec 3, 2015 at 4:30 PM, Jonathan Coe <jonathanbcoe@gmail.com> wrote=
:
> There's a strong push to rid modern c++ of its perceived verbosity.
> Range-based-for, auto and the proposed auto {x,y,z} for tuple result
> capture are all illustrative of this.
>
> I'm sure there are deeper reasons for such a drive beyond reducing
> character count.
>
> I'm an engineer not a language designer though. How will reducing the
> verbosity alter the way we use the language?
>
> On 3 Dec 2015, at 20:46, barry.revzin@gmail.com wrote:
>
> I'll throw in a contrary opinion here. What is the advantage of having
> abbreviated function templates at all? It's barely even terser. The
> following:
>
> void foo(InputIterator a, InputIterator b);
>
> is a mere SEVEN characters shorter than the MUCH more understandable:
>
> template <InputIterator It>
> void foo(It a, It b);
>
> Not to mention that the former devolves into this large argument about
> whether or not a or b can have the same type or not, and whether or not
> that makes sense or is reasonable, and cannot even support two different
> types that both meet the InputIterator criteria. In the latter, it is
> obvious that a and b have the same type and it is obvious how to provide
> for two different InputIterators.
>
> Seriously. Why.
>
> On Monday, November 23, 2015 at 10:27:37 PM UTC-6, Andrei L wrote:
>>
>> Hello,
>>
>> I've been reading through the paper and noticed this:
>>
>> <..> An abbreviated function template is equivalent to a function
>>> template (14.6.6) whose template-parameter-list includes one invented
>>> template-parameter for each occurrence of a placeholder in the
>>> parameter-declaration-clause, in order of appearance <..>
>>>
>>
>> Is this means that in such code:
>>
>> template <typename T>
>> concept bool R =3D CheckSomething<T>;
>>
>> auto foo(R a, R b) { /* ... */ }
>>
>> parameters `a' and `b' have the same type? And if so, why? What is the
>> rationale behind that?
>>
> --
>
> ---
> 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-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
> --
>
> ---
> 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-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a114293a8eb167c05260619f4
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Have you heard of the=C2=A0Sapir=E2=80=93Whorf hypothesis?=
=C2=A0<div><br></div><div>In essence, the idea is the tools we use for thou=
ght change how we think. While disproven in its strong form, it's clear=
ly obvious in its weak form in C++11 through an example: lambdas.</div><div=
>Lambdas don't really add any "power"; you can easily simulat=
e them via an explicit named functor, with explicit capture, which I still =
do in C++03.</div><div>However, they do make it much easier; for_each with =
lambdas is clean and easy, where as with explicit functors it is rarely wor=
thwhile.</div><div><br></div><div>Another example is constexpr; it is entir=
ely possible to do without constexpr, but would you want to write the metat=
emplate code every time?</div><div>In reality, since it is so verbose, you&=
#39;d probably only write it when you absolutely need the speed (such as nu=
merical libraries).</div><div>With constexpr, it becomes trivial, which mea=
ns you'll almost certainly do it more, leading to faster, more elegant =
programs.</div><div><br></div><div><div>By making features less verbose, we=
make it easier to get simple things done; while this adds no computational=
power to the language, I'd argue it adds "linguistic power".=
</div><div>By adding this linguistic power, we change how people code.</div=
></div><div>By changing how people code, we can increase productivity and/o=
r speed of execution.</div></div><div class=3D"gmail_extra"><br><div class=
=3D"gmail_quote">On Thu, Dec 3, 2015 at 4:30 PM, Jonathan Coe <span dir=3D"=
ltr"><<a href=3D"mailto:jonathanbcoe@gmail.com" target=3D"_blank">jonath=
anbcoe@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote"=
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"auto"><div></div><div>There's a strong push to rid modern c++=
of its perceived verbosity. Range-based-for, auto and the proposed auto {x=
,y,z} for tuple result capture are all illustrative of this.</div><div><br>=
</div><div>I'm sure there are deeper reasons for such a drive beyond re=
ducing character count.</div><div><br></div><div>I'm an engineer not a =
language designer though. How will reducing the verbosity alter the way we =
use the language?</div><div><div class=3D"h5"><div><br>On 3 Dec 2015, at 20=
:46, <a href=3D"mailto:barry.revzin@gmail.com" target=3D"_blank">barry.revz=
in@gmail.com</a> wrote:<br><br></div><blockquote type=3D"cite"><div><div di=
r=3D"ltr">I'll throw in a contrary opinion here. What is the advantage =
of having abbreviated function templates at all? It's barely even terse=
r. The following:<div><br></div><div>void foo(InputIterator a, InputIterato=
r b);</div><div><br></div><div>is a mere SEVEN characters shorter than the =
MUCH more understandable:</div><div><br></div><div>template <InputIterat=
or It></div><div>void foo(It a, It b);</div><div><br></div><div>Not to m=
ention that the former devolves into this large argument about whether or n=
ot a or b can have the same type or not, and whether or not that makes sens=
e or is reasonable, and cannot even support two different types that both m=
eet the InputIterator criteria. In the latter, it is obvious that a and b h=
ave the same type and it is obvious how to provide for two different InputI=
terators.=C2=A0</div><div><br></div><div>Seriously. Why. =C2=A0<br><br>On M=
onday, November 23, 2015 at 10:27:37 PM UTC-6, Andrei L wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr">Hello,<br><br>I've been rea=
ding through the paper and noticed this:<br><br><blockquote style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
class=3D"gmail_quote"><..> An abbreviated function template is equiv=
alent to a function template (14.6.6) whose template-parameter-list include=
s one invented template-parameter for each occurrence of a placeholder in t=
he parameter-declaration-clause, in order of appearance <..><br></blo=
ckquote><br>Is this means that in such code:<br><span style=3D"font-family:=
courier new,monospace"><br></span><div style=3D"margin-left:40px"><span sty=
le=3D"font-family:courier new,monospace">template <typename T></span>=
<br><span style=3D"font-family:courier new,monospace"></span><span style=3D=
"font-family:courier new,monospace">concept bool R =3D CheckSomething<T&=
gt;;</span><br><span style=3D"font-family:courier new,monospace"></span><br=
><span style=3D"font-family:courier new,monospace"></span><span style=3D"fo=
nt-family:courier new,monospace">auto foo(R a, R b) { /* ... */ }</span><br=
></div><span style=3D"font-family:courier new,monospace"></span><span style=
=3D"font-family:courier new,monospace"></span><br><div style=3D"text-align:=
left">parameters `a' and `b' have the same type? And if so, why? Wh=
at is the rationale behind that?<br></div></div></blockquote></div></div>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></blockquote></div></div></div><div class=3D"HOEnZb"><div class=3D"h5=
">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a114293a8eb167c05260619f4--
.