Topic: Solving the std::swap embarrassment*?


Author: Marc Mutz <marc.mutz@kdab.com>
Date: Tue, 2 May 2017 20:23:38 +0200
Raw View
* technical term, not judgmental

Hi,

I thought this was solved in C++11 but Ville proved me wrong today:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#229 motivates
partial function specialisation for solving the problem that the world outside
namespace std has to write

   using std::swap;
   swap(a, b);

(where swap() is a stand-in for any std function, incl. e.g. sin(),
for_each()). They can't just write

    std::swap(a, b);

because class authors are forbidden by [namespace.std] to add new declarations
(that includes function overloads) to namespace std, even though they are
allowed to partically specialise class templates there. You cannot partially
specialise function templates, you need to overload them. But you can't. Not
in namespace std. So users need to activate ADL, while still allowing falling
back to the std version, thus the using declaration + unqualified name lookup.

I don't know when I learned about this the first time, but I do know from
where: Scott Meyer's books. Those are ~20 years old by now.

Can't we do better than forcing the world to permanently add that

   using std::name;

for essentially any call to a function in namespace std?

Can't [namespace.std] be extended to allow function overloads as a kin to the
(allowed) partial class temlate specialisations? With the same caveats? Must
use user type, must actually work as the std versions?

Or, alternatively, can't

  int i, j;
  swap(i, j);

automagically find the std version?

Thanks,
Marc

--
Marc Mutz <marc.mutz@kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/201705022023.38635.marc.mutz%40kdab.com.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 2 May 2017 22:31:49 +0300
Raw View
On 2 May 2017 at 21:23, Marc Mutz <marc.mutz@kdab.com> wrote:
> Can't [namespace.std] be extended to allow function overloads as a kin to the
> (allowed) partial class temlate specialisations? With the same caveats? Must
> use user type, must actually work as the std versions?

...must be an overload of an existing function specified by the
library, must not change
any overload resolution results, I think. Something like that makes
sense to me when I
vaguely remember the days when I was a mere language user, while still
remembering
why the restrictions that we currently have are there.

> Or, alternatively, can't
>
>   int i, j;
>   swap(i, j);
>
> automagically find the std version?


I bet that idea breaks some code somewhere.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUb2QCim3QPwNCGrvitfMv3S5EOaMtRSESus4uALQ7kxqQ%40mail.gmail.com.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 2 May 2017 15:09:06 -0700 (PDT)
Raw View
------=_Part_2521_1187088980.1493762946388
Content-Type: multipart/alternative;
 boundary="----=_Part_2522_355650694.1493762946388"

------=_Part_2522_355650694.1493762946388
Content-Type: text/plain; charset=UTF-8

On Tuesday, May 2, 2017 at 2:25:03 PM UTC-4, Marc Mutz wrote:
>
> * technical term, not judgmental
>
> Hi,
>
> I thought this was solved in C++11 but Ville proved me wrong today:
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#229 motivates
> partial function specialisation for solving the problem that the world
> outside
> namespace std has to write
>
>    using std::swap;
>    swap(a, b);
>
> (where swap() is a stand-in for any std function, incl. e.g. sin(),
> for_each()). They can't just write
>
>     std::swap(a, b);
>
> because class authors are forbidden by [namespace.std] to add new
> declarations
> (that includes function overloads) to namespace std, even though they are
> allowed to partically specialise class templates there. You cannot
> partially
> specialise function templates, you need to overload them. But you can't.
> Not
> in namespace std. So users need to activate ADL, while still allowing
> falling
> back to the std version, thus the using declaration + unqualified name
> lookup.
>
> I don't know when I learned about this the first time, but I do know from
> where: Scott Meyer's books. Those are ~20 years old by now.
>
> Can't we do better than forcing the world to permanently add that
>
>    using std::name;
>
> for essentially any call to a function in namespace std?
>

It's not "any call". It's only for calls where users would reasonably be
expected to provide overloads for their types. So that means just `swap`.

And `begin` and `end`. And `cbegin` and `cend`. And `rbegin/rend`. And
`crbegin/crend`. And `size` ;)

The problem really is that we want interfaces to allow 3 things though the
same syntax, and C++ doesn't really support this combination very well:

1) Users can specify the behavior of these functions via member functions.

2) Users can specify the behavior of these functions for types via
functions that are not members of that type.

3) Fundamental types can have defaults applied.

The problem is really #1 and #3. Both of these are important, and both of
them are provided by the same overload. And neither of them use ADL

The solution to this insanity was supposed to be unified function call
syntax, but the standards committee took a knee on that and refuses to even
think about fixing it anymore.

So no, it's not gonna be fixed.

Or, alternatively, can't
>
>   int i, j;
>   swap(i, j);
>
> automagically find the std version?
>

Even ignoring what breakage that could cause, it would still not be enough.
Remember that #1 is implemented through the same mechanism: `std::swap`
calling the type's member function. So if you have a type that provides a
member `swap` but it doesn't have a `swap` at namespace scope (and let's be
frank, it's *stupid* to have both), you still need `using std::swap` to get
an unqualified call to `swap` to call the member function.

Again, UFC would have fixed this, but we cannot have nice things in C++.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/dbbdbc10-3f83-48ea-9a78-beb179bd113a%40isocpp.org.

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

<div dir=3D"ltr">On Tuesday, May 2, 2017 at 2:25:03 PM UTC-4, Marc Mutz wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">* technical term, not judgm=
ental
<br>
<br>Hi,
<br>
<br>I thought this was solved in C++11 but Ville proved me wrong today:
<br>
<br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#=
229" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;htt=
p://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fw=
g21%2Fdocs%2Fcwg_closed.html%23229\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCN=
FxTv-rQxEI42eHIzhGojw1j-CMEQ&#39;;return true;" onclick=3D"this.href=3D&#39=
;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22=
%2Fwg21%2Fdocs%2Fcwg_closed.html%23229\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAF=
QjCNFxTv-rQxEI42eHIzhGojw1j-CMEQ&#39;;return true;">http://www.open-std.org=
/jtc1/<wbr>sc22/wg21/docs/cwg_closed.<wbr>html#229</a> motivates=20
<br>partial function specialisation for solving the problem that the world =
outside=20
<br>namespace std has to write
<br>
<br>=C2=A0 =C2=A0using std::swap;
<br>=C2=A0 =C2=A0swap(a, b);
<br>
<br>(where swap() is a stand-in for any std function, incl. e.g. sin(),=20
<br>for_each()). They can&#39;t just write
<br>
<br>=C2=A0 =C2=A0 std::swap(a, b);
<br>
<br>because class authors are forbidden by [namespace.std] to add new decla=
rations=20
<br>(that includes function overloads) to namespace std, even though they a=
re=20
<br>allowed to partically specialise class templates there. You cannot part=
ially=20
<br>specialise function templates, you need to overload them. But you can&#=
39;t. Not=20
<br>in namespace std. So users need to activate ADL, while still allowing f=
alling=20
<br>back to the std version, thus the using declaration + unqualified name =
lookup.
<br>
<br>I don&#39;t know when I learned about this the first time, but I do kno=
w from=20
<br>where: Scott Meyer&#39;s books. Those are ~20 years old by now.
<br>
<br>Can&#39;t we do better than forcing the world to permanently add that
<br>
<br>=C2=A0 =C2=A0using std::name;
<br>
<br>for essentially any call to a function in namespace std?<br></blockquot=
e><div><br>It&#39;s not &quot;any call&quot;. It&#39;s only for calls where=
 users would reasonably be expected to provide overloads for their types. S=
o that means just `swap`.<br><br>And `begin` and `end`. And `cbegin` and `c=
end`. And `rbegin/rend`. And `crbegin/crend`. And `size` ;)<br><br>The prob=
lem really is that we want interfaces to allow 3 things though the same syn=
tax, and C++ doesn&#39;t really support this combination very well:<br><br>=
1) Users can specify the behavior of these functions via member functions.<=
br><br>2) Users can specify the behavior of these functions for types via f=
unctions that are not members of that type.<br><br>3) Fundamental types can=
 have defaults applied.<br><br>The problem is really #1 and #3. Both of the=
se are important, and both of them are provided by the same overload. And n=
either of them use ADL<br><br>The solution to this insanity was supposed to=
 be unified function call syntax, but the standards committee took a knee o=
n that and refuses to even think about fixing it anymore.<br><br>So no, it&=
#39;s not gonna be fixed.<br><br><blockquote class=3D"gmail_quote" style=3D=
"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padd=
ing-left: 1ex;">Or, alternatively, can&#39;t<br><br>=C2=A0 int i, j;<br>=C2=
=A0 swap(i, j);<br><br>automagically find the std version? <br></blockquote=
></div><br>Even ignoring what breakage that could cause, it would still not=
 be enough. Remember that #1 is implemented through the same mechanism: `st=
d::swap` calling the type&#39;s member function. So if you have a type that=
 provides a member `swap` but it doesn&#39;t have a `swap` at namespace sco=
pe (and let&#39;s be frank, it&#39;s <i>stupid</i> to have both), you still=
 need `using std::swap` to get an unqualified call to `swap` to call the me=
mber function.<br><br>Again, UFC would have fixed this, but we cannot have =
nice things in C++.<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/dbbdbc10-3f83-48ea-9a78-beb179bd113a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/dbbdbc10-3f83-48ea-9a78-beb179bd113a=
%40isocpp.org</a>.<br />

------=_Part_2522_355650694.1493762946388--

------=_Part_2521_1187088980.1493762946388--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Tue, 2 May 2017 19:30:25 -0400
Raw View
--001a1145b01eadbd0b054e92ecea
Content-Type: text/plain; charset=UTF-8

On Tue, May 2, 2017 at 6:09 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Tuesday, May 2, 2017 at 2:25:03 PM UTC-4, Marc Mutz wrote:
>>
>> * technical term, not judgmental
>>
>> Hi,
>>
>> I thought this was solved in C++11 but Ville proved me wrong today:
>>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#229
>> motivates
>> partial function specialisation for solving the problem that the world
>> outside
>> namespace std has to write
>>
>>    using std::swap;
>>    swap(a, b);
>>
>> (where swap() is a stand-in for any std function, incl. e.g. sin(),
>> for_each()). They can't just write
>>
>>     std::swap(a, b);
>>
>> because class authors are forbidden by [namespace.std] to add new
>> declarations
>> (that includes function overloads) to namespace std, even though they are
>> allowed to partically specialise class templates there. You cannot
>> partially
>> specialise function templates, you need to overload them. But you can't.
>> Not
>> in namespace std. So users need to activate ADL, while still allowing
>> falling
>> back to the std version, thus the using declaration + unqualified name
>> lookup.
>>
>> I don't know when I learned about this the first time, but I do know from
>> where: Scott Meyer's books. Those are ~20 years old by now.
>>
>> Can't we do better than forcing the world to permanently add that
>>
>>    using std::name;
>>
>> for essentially any call to a function in namespace std?
>>
>
> It's not "any call". It's only for calls where users would reasonably be
> expected to provide overloads for their types. So that means just `swap`.
>
> And `begin` and `end`. And `cbegin` and `cend`. And `rbegin/rend`. And
> `crbegin/crend`. And `size` ;)
>

And we keep adding to the list, with no end in sight.


>
> The problem really is that we want interfaces to allow 3 things though the
> same syntax, and C++ doesn't really support this combination very well:
>
> 1) Users can specify the behavior of these functions via member functions.
>
> 2) Users can specify the behavior of these functions for types via
> functions that are not members of that type.
>
> 3) Fundamental types can have defaults applied.
>
> The problem is really #1 and #3. Both of these are important, and both of
> them are provided by the same overload. And neither of them use ADL
>
> The solution to this insanity was supposed to be unified function call
> syntax, but the standards committee took a knee on that and refuses to even
> think about fixing it anymore.
>
> So no, it's not gonna be fixed.
>


There are many potential fixes.  One simple one that just doesn't look
"elegant":

namespace std {
  template<typename T>
  auto foo(T t) { return std_foo(t); }  // plus forwarding, etc
}

Users call std::foo(),
Extenders implement std_foo() for their type(s).  Found by ADL.

This is basically an application of Herb's "Non virtual interface" pattern
(ie make virtuals private http://www.gotw.ca/publications/mill18.htm), just
at a different level.

Tony



>
> Or, alternatively, can't
>>
>>   int i, j;
>>   swap(i, j);
>>
>> automagically find the std version?
>>
>
> Even ignoring what breakage that could cause, it would still not be
> enough. Remember that #1 is implemented through the same mechanism:
> `std::swap` calling the type's member function. So if you have a type that
> provides a member `swap` but it doesn't have a `swap` at namespace scope
> (and let's be frank, it's *stupid* to have both), you still need `using
> std::swap` to get an unqualified call to `swap` to call the member function.
>
> Again, UFC would have fixed this, but we cannot have nice things in C++.
>
> --
> 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.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/dbbdbc10-3f83-48ea-
> 9a78-beb179bd113a%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/dbbdbc10-3f83-48ea-9a78-beb179bd113a%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>



--
Be seeing you,
Tony

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbisJiEuiC%2BwRFS5fMxsejUFiKzwxt8_DWMOD%2B%2BafBjFYmQ%40mail.gmail.com.

--001a1145b01eadbd0b054e92ecea
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, May 2, 2017 at 6:09 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a hr=
ef=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>=
&gt;</span> wrote:<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"><di=
v dir=3D"ltr"><span class=3D"gmail-">On Tuesday, May 2, 2017 at 2:25:03 PM =
UTC-4, Marc Mutz wrote:<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">* =
technical term, not judgmental
<br>
<br>Hi,
<br>
<br>I thought this was solved in C++11 but Ville proved me wrong today:
<br>
<br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#=
229" rel=3D"nofollow" target=3D"_blank">http://www.open-std.org/jtc1/s<wbr>=
c22/wg21/docs/cwg_closed.html#<wbr>229</a> motivates=20
<br>partial function specialisation for solving the problem that the world =
outside=20
<br>namespace std has to write
<br>
<br>=C2=A0 =C2=A0using std::swap;
<br>=C2=A0 =C2=A0swap(a, b);
<br>
<br>(where swap() is a stand-in for any std function, incl. e.g. sin(),=20
<br>for_each()). They can&#39;t just write
<br>
<br>=C2=A0 =C2=A0 std::swap(a, b);
<br>
<br>because class authors are forbidden by [namespace.std] to add new decla=
rations=20
<br>(that includes function overloads) to namespace std, even though they a=
re=20
<br>allowed to partically specialise class templates there. You cannot part=
ially=20
<br>specialise function templates, you need to overload them. But you can&#=
39;t. Not=20
<br>in namespace std. So users need to activate ADL, while still allowing f=
alling=20
<br>back to the std version, thus the using declaration + unqualified name =
lookup.
<br>
<br>I don&#39;t know when I learned about this the first time, but I do kno=
w from=20
<br>where: Scott Meyer&#39;s books. Those are ~20 years old by now.
<br>
<br>Can&#39;t we do better than forcing the world to permanently add that
<br>
<br>=C2=A0 =C2=A0using std::name;
<br>
<br>for essentially any call to a function in namespace std?<br></blockquot=
e></span><div><br>It&#39;s not &quot;any call&quot;. It&#39;s only for call=
s where users would reasonably be expected to provide overloads for their t=
ypes. So that means just `swap`.<br><br>And `begin` and `end`. And `cbegin`=
 and `cend`. And `rbegin/rend`. And `crbegin/crend`. And `size` ;)<br></div=
></div></blockquote><div><br></div><div>And we keep adding to the list, wit=
h no end in sight.<br>=C2=A0<br></div><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><br>The problem really is that we want i=
nterfaces to allow 3 things though the same syntax, and C++ doesn&#39;t rea=
lly support this combination very well:<br><br>1) Users can specify the beh=
avior of these functions via member functions.<br><br>2) Users can specify =
the behavior of these functions for types via functions that are not member=
s of that type.<br><br>3) Fundamental types can have defaults applied.<br><=
br>The problem is really #1 and #3. Both of these are important, and both o=
f them are provided by the same overload. And neither of them use ADL<br><b=
r>The solution to this insanity was supposed to be unified function call sy=
ntax, but the standards committee took a knee on that and refuses to even t=
hink about fixing it anymore.<br><br>So no, it&#39;s not gonna be fixed.<sp=
an class=3D"gmail-"><br></span></div></div></blockquote><div><br><br></div>=
<div>There are many potential fixes.=C2=A0 One simple one that just doesn&#=
39;t look &quot;elegant&quot;:<br><br></div><div>namespace std {<br></div><=
div>=C2=A0 template&lt;typename T&gt;<br></div><div>=C2=A0 auto foo(T t) { =
return std_foo(t); }=C2=A0 // plus forwarding, etc<br>}<br><br></div><div>U=
sers call std::foo(),<br></div><div>Extenders implement std_foo() for their=
 type(s).=C2=A0 Found by ADL.<br><br></div><div>This is basically an applic=
ation of Herb&#39;s &quot;Non virtual interface&quot; pattern (ie make virt=
uals private <a href=3D"http://www.gotw.ca/publications/mill18.htm">http://=
www.gotw.ca/publications/mill18.htm</a>), just at a different level.<br></d=
iv><div><br></div><div>Tony<br><br></div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><span class=3D"gmail=
-"><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">Or, alternatively,=
 can&#39;t<br><br>=C2=A0 int i, j;<br>=C2=A0 swap(i, j);<br><br>automagical=
ly find the std version? <br></blockquote></span></div><br>Even ignoring wh=
at breakage that could cause, it would still not be enough. Remember that #=
1 is implemented through the same mechanism: `std::swap` calling the type&#=
39;s member function. So if you have a type that provides a member `swap` b=
ut it doesn&#39;t have a `swap` at namespace scope (and let&#39;s be frank,=
 it&#39;s <i>stupid</i> to have both), you still need `using std::swap` to =
get an unqualified call to `swap` to call the member function.<br><br>Again=
, UFC would have fixed this, but we cannot have nice things in C++.<br></di=
v><span class=3D"gmail-">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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@<wbr>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></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/dbbdbc10-3f83-48ea-9a78-beb179bd113a%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/dbbd=
bc10-3f83-48ea-<wbr>9a78-beb179bd113a%40isocpp.org</a><wbr>.<br>
</blockquote></div><br><br clear=3D"all"><br>-- <br><div class=3D"gmail_sig=
nature"><div dir=3D"ltr"><div>Be seeing you,<br></div>Tony<br></div></div>
</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOHCbisJiEuiC%2BwRFS5fMxsejUFiKzwxt8=
_DWMOD%2B%2BafBjFYmQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbisJiE=
uiC%2BwRFS5fMxsejUFiKzwxt8_DWMOD%2B%2BafBjFYmQ%40mail.gmail.com</a>.<br />

--001a1145b01eadbd0b054e92ecea--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 2 May 2017 19:08:11 -0700 (PDT)
Raw View
------=_Part_3423_196116191.1493777291905
Content-Type: multipart/alternative;
 boundary="----=_Part_3424_1546959205.1493777291905"

------=_Part_3424_1546959205.1493777291905
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, May 2, 2017 at 4:30:29 PM UTC-7, Tony V E wrote:
>
> On Tue, May 2, 2017 at 6:09 PM, Nicol Bolas <jmck...@gmail.com=20
> <javascript:>> wrote:
>
>> On Tuesday, May 2, 2017 at 2:25:03 PM UTC-4, Marc Mutz wrote:
>>>
>>> * technical term, not judgmental=20
>>>
>>> Hi,=20
>>>
>>> I thought this was solved in C++11 but Ville proved me wrong today:=20
>>>
>>> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#229=20
>>> motivates=20
>>> partial function specialisation for solving the problem that the world=
=20
>>> outside=20
>>> namespace std has to write=20
>>>
>>>    using std::swap;=20
>>>    swap(a, b);=20
>>> [...]
>>> Can't we do better [...] ?
>>>
>>
>> It's not "any call". It's only for calls where users would reasonably be=
=20
>> expected to provide overloads for their types. So that means just `swap`=
..
>> And `begin` and `end`. And `cbegin` and `cend`. And `rbegin/rend`. And=
=20
>> `crbegin/crend`. And `size` ;)
>>
>
> And we keep adding to the list, with no end in sight.
> [...]
> There are many potential fixes.  One simple one that just doesn't look=20
> "elegant":
>
> namespace std {
>   template<typename T>
>   auto foo(T t) { return std_foo(t); }  // plus forwarding, etc
> }
>
> Users call std::foo(),
> Extenders implement std_foo() for their type(s).  Found by ADL.
>

Eric Niebler has done some proposal-work in this area. I think I've also=20
chatted with Vicente Botet and Eric Fiselier on the subject. The search=20
term you're looking for is "customization points."
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
IMHO, the most elegant solution (basically Eric Niebler's proposal) would=
=20
involve MASSIVE breakage of old code and is thus suited only for "std2".

namespace std2 {
inline auto swap =3D [](auto& x, auto& y) constexpr -> void {
    if constexpr (__has_adl_swap(x, y)) {
        swap(x, y);
    } else if constexpr (__has_swap_member_function(x, y)) {
        x.swap(y);
    } else {
        auto temp =3D x;
        x =3D std::move(y);
        y =3D std::move(temp);
    }
};
} // namespace std2

(My intention with the __has_adl_swap and __has_swap_member_function=20
pseudo-traits is that they should return constexpr true iff the=20
corresponding expressions are well-formed.)

Notice that because this "std2::swap" is an object, not a function:
- you can pass it to an STL function template without any hassle (as=20
opposed to the punctuation soup of std::less<>{})
- there is no temptation to "specialize" it via reopening namespace std2=20
(as there is, dangerously, with std::swap)
- there is no temptation to "overload" it via reopening namespace std2 (as=
=20
there is, fatally, with std::swap)

Notice also that:
- it can swap heterogeneous types: I have not thought deeply about this=20
aspect but I don't immediately see anything wrong with it
- it automagically works with your x.swap(y) member functions, thus you can=
=20
avoid implementing ADL swap if you want (as opposed to today's best=20
practice: implementing ADL-swap-in-terms-of-member-swap)

=E2=80=93Arthur

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/50d6b1fa-618f-42c4-893e-3c20a855ea80%40isocpp.or=
g.

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

<div dir=3D"ltr">On Tuesday, May 2, 2017 at 4:30:29 PM UTC-7, Tony V E wrot=
e:<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">On Tue, May=
 2, 2017 at 6:09 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"javascrip=
t:" target=3D"_blank" gdf-obfuscated-mailto=3D"4gxNMPf_AwAJ" rel=3D"nofollo=
w" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=
=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck...@gmail.com</a>&g=
t;</span> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,=
204,204);padding-left:1ex"><div dir=3D"ltr"><span>On Tuesday, May 2, 2017 a=
t 2:25:03 PM UTC-4, Marc Mutz wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex">* technical term, not judgmental
<br>
<br>Hi,
<br>
<br>I thought this was solved in C++11 but Ville proved me wrong today:
<br>
<br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#=
229" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;htt=
p://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fw=
g21%2Fdocs%2Fcwg_closed.html%23229\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCN=
FxTv-rQxEI42eHIzhGojw1j-CMEQ&#39;;return true;" onclick=3D"this.href=3D&#39=
;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22=
%2Fwg21%2Fdocs%2Fcwg_closed.html%23229\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAF=
QjCNFxTv-rQxEI42eHIzhGojw1j-CMEQ&#39;;return true;">http://www.open-std.org=
/jtc1/<wbr>sc22/wg21/docs/cwg_closed.<wbr>html#229</a> motivates=20
<br>partial function specialisation for solving the problem that the world =
outside=20
<br>namespace std has to write
<br>
<br>=C2=A0 =C2=A0using std::swap;
<br>=C2=A0 =C2=A0swap(a, b);
<br>[...]<br>Can&#39;t we do better [...]=C2=A0?<br></blockquote></span><di=
v><br>It&#39;s not &quot;any call&quot;. It&#39;s only for calls where user=
s would reasonably be expected to provide overloads for their types. So tha=
t means just `swap`.<br>And `begin` and `end`. And `cbegin` and `cend`. And=
 `rbegin/rend`. And `crbegin/crend`. And `size` ;)<br></div></div></blockqu=
ote><div><br></div><div>And we keep adding to the list, with no end in sigh=
t.<br></div><div>[...]</div><div>There are many potential fixes.=C2=A0 One =
simple one that just doesn&#39;t look &quot;elegant&quot;:<br><br></div><di=
v>namespace std {<br></div><div>=C2=A0 template&lt;typename T&gt;<br></div>=
<div>=C2=A0 auto foo(T t) { return std_foo(t); }=C2=A0 // plus forwarding, =
etc<br>}<br><br></div><div>Users call std::foo(),<br></div><div>Extenders i=
mplement std_foo() for their type(s).=C2=A0 Found by ADL.<br></div></div></=
div></div></blockquote><div><br></div><div>Eric Niebler has done some propo=
sal-work in this area. I think I&#39;ve also chatted with Vicente Botet and=
 Eric Fiselier on the subject. The search term you&#39;re looking for is &q=
uot;customization points.&quot;</div><div><a href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2015/n4381.html">http://www.open-std.org/jtc1/=
sc22/wg21/docs/papers/2015/n4381.html</a><br></div><div>IMHO, the most eleg=
ant solution (basically Eric Niebler&#39;s proposal) would involve MASSIVE =
breakage of old code and is thus suited only for &quot;std2&quot;.</div><di=
v><br></div><div>namespace std2 {</div><div>inline auto swap =3D [](auto&am=
p; x, auto&amp; y) constexpr -&gt; void {</div><div>=C2=A0 =C2=A0 if conste=
xpr (__has_adl_swap(x, y)) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 swap(x, =
y);</div><div>=C2=A0 =C2=A0 } else if constexpr (__has_swap_member_function=
(x, y)) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 x.swap(y);</div><div>=C2=A0=
 =C2=A0 } else {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto temp =3D x;</di=
v><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 x =3D std::move(y);</div><div>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 y =3D std::move(temp);</div><div>=C2=A0 =C2=A0 }<br></div=
><div>};</div><div>} // namespace std2</div><div><br></div><div>(My intenti=
on with the __has_adl_swap and __has_swap_member_function pseudo-traits is =
that they should return constexpr true iff the corresponding expressions ar=
e well-formed.)</div><div><br></div><div>Notice that because this &quot;std=
2::swap&quot; is an object, not a function:</div><div>- you can pass it to =
an STL function template without any hassle (as opposed to the punctuation =
soup of std::less&lt;&gt;{})</div><div>- there is no temptation to &quot;sp=
ecialize&quot; it via reopening namespace std2 (as there is, dangerously, w=
ith std::swap)<br></div><div>- there is no temptation to &quot;overload&quo=
t; it via reopening namespace std2 (as there is, fatally, with std::swap)<b=
r></div><div><br></div><div>Notice also that:</div><div>- it can swap heter=
ogeneous types: I have not thought deeply about this aspect but I don&#39;t=
 immediately see anything wrong with it</div><div>- it automagically works =
with your x.swap(y) member functions, thus you can avoid implementing ADL s=
wap if you want (as opposed to today&#39;s best practice: implementing ADL-=
swap-in-terms-of-member-swap)</div><div><br></div><div>=E2=80=93Arthur</div=
></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/50d6b1fa-618f-42c4-893e-3c20a855ea80%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/50d6b1fa-618f-42c4-893e-3c20a855ea80=
%40isocpp.org</a>.<br />

------=_Part_3424_1546959205.1493777291905--

------=_Part_3423_196116191.1493777291905--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 2 May 2017 19:26:18 -0700 (PDT)
Raw View
------=_Part_1299_1623943467.1493778378984
Content-Type: multipart/alternative;
 boundary="----=_Part_1300_1466061432.1493778378985"

------=_Part_1300_1466061432.1493778378985
Content-Type: text/plain; charset=UTF-8

On Tuesday, May 2, 2017 at 10:08:12 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Tuesday, May 2, 2017 at 4:30:29 PM UTC-7, Tony V E wrote:
>>
>> On Tue, May 2, 2017 at 6:09 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> On Tuesday, May 2, 2017 at 2:25:03 PM UTC-4, Marc Mutz wrote:
>>>>
>>>> * technical term, not judgmental
>>>>
>>>> Hi,
>>>>
>>>> I thought this was solved in C++11 but Ville proved me wrong today:
>>>>
>>>> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#229
>>>> motivates
>>>> partial function specialisation for solving the problem that the world
>>>> outside
>>>> namespace std has to write
>>>>
>>>>    using std::swap;
>>>>    swap(a, b);
>>>> [...]
>>>> Can't we do better [...] ?
>>>>
>>>
>>> It's not "any call". It's only for calls where users would reasonably be
>>> expected to provide overloads for their types. So that means just `swap`.
>>> And `begin` and `end`. And `cbegin` and `cend`. And `rbegin/rend`. And
>>> `crbegin/crend`. And `size` ;)
>>>
>>
>> And we keep adding to the list, with no end in sight.
>> [...]
>> There are many potential fixes.  One simple one that just doesn't look
>> "elegant":
>>
>> namespace std {
>>   template<typename T>
>>   auto foo(T t) { return std_foo(t); }  // plus forwarding, etc
>> }
>>
>> Users call std::foo(),
>> Extenders implement std_foo() for their type(s).  Found by ADL.
>>
>
> Eric Niebler has done some proposal-work in this area. I think I've also
> chatted with Vicente Botet and Eric Fiselier on the subject. The search
> term you're looking for is "customization points."
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
> IMHO, the most elegant solution (basically Eric Niebler's proposal) would
> involve MASSIVE breakage of old code and is thus suited only for "std2".
>
> namespace std2 {
> inline auto swap = [](auto& x, auto& y) constexpr -> void {
>     if constexpr (__has_adl_swap(x, y)) {
>         swap(x, y);
>     } else if constexpr (__has_swap_member_function(x, y)) {
>         x.swap(y);
>     } else {
>         auto temp = x;
>         x = std::move(y);
>         y = std::move(temp);
>     }
> };
> } // namespace std2
>

I'm not sure I entirely agree with the specific implementation, but this
kind of thing really sounds like something that ought to be supported in
the language in some way. I justify that by pointing out that the language
actually does support this in two places: range-based `for` and structured
binding, in searching for `begin/end` and `get`, respectively.

Note that in both cases, there is a also a default version. Ranged-based
`for` has specialized behavior for C++ array types, and structured binding
has special behavior for both arrays and publicly accessible structures.

This is also why I don't agree with the specific implementation, since
non-member functions have overriding priority over members. By contrast,
both `for` and structured binding give members priority.

If language features like range-based `for` and structured binding can do
this specific kind of thing, then it seems clear that users of the language
ought to be able to set such things up as well. And not with ad-hoc
solutions like the above, but with some kind of real language feature.

Maybe to avoid the UFC issues, it would work like this. We provide a way to
call a function (which is distinct from regular call syntax, thus pacifying
the anti-UFC people) where you specify at the call cite that you're using
the special lookup rules (check members, then check ADL, and if neither of
them work, use the default). And you provide a way to define a function
which represents one of the default cases when calling via these special
lookup rules (otherwise, it acts like a regular function).


>
> (My intention with the __has_adl_swap and __has_swap_member_function
> pseudo-traits is that they should return constexpr true iff the
> corresponding expressions are well-formed.)
>
> Notice that because this "std2::swap" is an object, not a function:
> - you can pass it to an STL function template without any hassle (as
> opposed to the punctuation soup of std::less<>{})
>

Or we could just have lifting lambdas and deal with it that way. Whatever
happened to P0119, anyway?


> - there is no temptation to "specialize" it via reopening namespace std2
> (as there is, dangerously, with std::swap)
> - there is no temptation to "overload" it via reopening namespace std2 (as
> there is, fatally, with std::swap)
>

A good language feature for customization points would remove such
temptations as well.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ede33ec9-cd19-4729-8f32-7045622830ff%40isocpp.org.

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

<div dir=3D"ltr">On Tuesday, May 2, 2017 at 10:08:12 PM UTC-4, Arthur O&#39=
;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
On Tuesday, May 2, 2017 at 4:30:29 PM UTC-7, Tony V E wrote:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr">On Tue, May 2, 2017 at 6:09 PM, N=
icol Bolas <span dir=3D"ltr">&lt;<a rel=3D"nofollow">jmck...@gmail.com</a>&=
gt;</span> wrote:<br><div><div class=3D"gmail_quote"><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"><span>On Tuesday, May 2, 2017 =
at 2:25:03 PM UTC-4, Marc Mutz wrote:<blockquote class=3D"gmail_quote" styl=
e=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddin=
g-left:1ex">* technical term, not judgmental
<br>
<br>Hi,
<br>
<br>I thought this was solved in C++11 but Ville proved me wrong today:
<br>
<br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#=
229" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;htt=
p://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fw=
g21%2Fdocs%2Fcwg_closed.html%23229\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCN=
FxTv-rQxEI42eHIzhGojw1j-CMEQ&#39;;return true;" onclick=3D"this.href=3D&#39=
;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22=
%2Fwg21%2Fdocs%2Fcwg_closed.html%23229\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAF=
QjCNFxTv-rQxEI42eHIzhGojw1j-CMEQ&#39;;return true;">http://www.open-std.org=
/jtc1/<wbr>sc22/wg21/docs/cwg_closed.<wbr>html#229</a> motivates=20
<br>partial function specialisation for solving the problem that the world =
outside=20
<br>namespace std has to write
<br>
<br>=C2=A0 =C2=A0using std::swap;
<br>=C2=A0 =C2=A0swap(a, b);
<br>[...]<br>Can&#39;t we do better [...]=C2=A0?<br></blockquote></span><di=
v><br>It&#39;s not &quot;any call&quot;. It&#39;s only for calls where user=
s would reasonably be expected to provide overloads for their types. So tha=
t means just `swap`.<br>And `begin` and `end`. And `cbegin` and `cend`. And=
 `rbegin/rend`. And `crbegin/crend`. And `size` ;)<br></div></div></blockqu=
ote><div><br></div><div>And we keep adding to the list, with no end in sigh=
t.<br></div><div>[...]</div><div>There are many potential fixes.=C2=A0 One =
simple one that just doesn&#39;t look &quot;elegant&quot;:<br><br></div><di=
v>namespace std {<br></div><div>=C2=A0 template&lt;typename T&gt;<br></div>=
<div>=C2=A0 auto foo(T t) { return std_foo(t); }=C2=A0 // plus forwarding, =
etc<br>}<br><br></div><div>Users call std::foo(),<br></div><div>Extenders i=
mplement std_foo() for their type(s).=C2=A0 Found by ADL.<br></div></div></=
div></div></blockquote><div><br></div><div>Eric Niebler has done some propo=
sal-work in this area. I think I&#39;ve also chatted with Vicente Botet and=
 Eric Fiselier on the subject. The search term you&#39;re looking for is &q=
uot;customization points.&quot;</div><div><a href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2015/n4381.html" target=3D"_blank" rel=3D"nofo=
llow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3=
A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fn4381=
..html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFLiQ7Hx7gXLuMVFVN3Tb7h1FvcMw&=
#39;;return true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\=
x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F201=
5%2Fn4381.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFLiQ7Hx7gXLuMVFVN3Tb=
7h1FvcMw&#39;;return true;">http://www.open-std.org/jtc1/<wbr>sc22/wg21/doc=
s/papers/2015/<wbr>n4381.html</a><br></div><div>IMHO, the most elegant solu=
tion (basically Eric Niebler&#39;s proposal) would involve MASSIVE breakage=
 of old code and is thus suited only for &quot;std2&quot;.</div><div><br></=
div><div>namespace std2 {</div><div>inline auto swap =3D [](auto&amp; x, au=
to&amp; y) constexpr -&gt; void {</div><div>=C2=A0 =C2=A0 if constexpr (__h=
as_adl_swap(x, y)) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 swap(x, y);</div=
><div>=C2=A0 =C2=A0 } else if constexpr (__has_swap_member_function(x, y)) =
{</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 x.swap(y);</div><div>=C2=A0 =C2=A0 =
} else {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto temp =3D x;</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 x =3D std::move(y);</div><div>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 y =3D std::move(temp);</div><div>=C2=A0 =C2=A0 }<br></div><div>}=
;</div><div>} // namespace std2</div></div></blockquote><div><br>I&#39;m no=
t sure I entirely agree with the specific implementation, but this kind of =
thing really sounds like something that ought to be supported in the langua=
ge in some way. I justify that by pointing out that the language actually d=
oes support this in two places: range-based `for` and structured binding, i=
n searching for `begin/end` and `get`, respectively.<br><br>Note that in bo=
th cases, there is a also a default version. Ranged-based `for` has special=
ized behavior for C++ array types, and structured binding has special behav=
ior for both arrays and publicly accessible structures.<br><br>This is also=
 why I don&#39;t agree with the specific implementation, since non-member f=
unctions have overriding priority over members. By contrast, both `for` and=
 structured binding give members priority.<br><br>If language features like=
 range-based `for` and structured binding can do this specific kind of thin=
g, then it seems clear that users of the language ought to be able to set s=
uch things up as well. And not with ad-hoc solutions like the above, but wi=
th some kind of real language feature.<br><br>Maybe to avoid the UFC issues=
, it would work like this. We provide a way to call a function (which is di=
stinct from regular call syntax, thus pacifying the anti-UFC people) where =
you specify at the call cite that you&#39;re using the special lookup rules=
 (check members, then check ADL, and if neither of them work, use the defau=
lt). And you provide a way to define a function which represents one of the=
 default cases when calling via these special lookup rules (otherwise, it a=
cts like a regular function).<br>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>(My intention with the =
__has_adl_swap and __has_swap_member_function pseudo-traits is that they sh=
ould return constexpr true iff the corresponding expressions are well-forme=
d.)</div><div><br></div><div>Notice that because this &quot;std2::swap&quot=
; is an object, not a function:</div><div>- you can pass it to an STL funct=
ion template without any hassle (as opposed to the punctuation soup of std:=
:less&lt;&gt;{})</div></div></blockquote><div><br>Or we could just have lif=
ting lambdas and deal with it that way. Whatever happened to P0119, anyway?=
<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"lt=
r"><div>- there is no temptation to &quot;specialize&quot; it via reopening=
 namespace std2 (as there is, dangerously, with std::swap)<br></div><div>- =
there is no temptation to &quot;overload&quot; it via reopening namespace s=
td2 (as there is, fatally, with std::swap)<br></div></div></blockquote><div=
><br>A good language feature for customization points would remove such tem=
ptations as well.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ede33ec9-cd19-4729-8f32-7045622830ff%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ede33ec9-cd19-4729-8f32-7045622830ff=
%40isocpp.org</a>.<br />

------=_Part_1300_1466061432.1493778378985--

------=_Part_1299_1623943467.1493778378984--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 2 May 2017 20:16:28 -0700
Raw View
--f403045c297e098d0e054e961565
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tue, May 2, 2017 at 7:26 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Tuesday, May 2, 2017 at 10:08:12 PM UTC-4, Arthur O'Dwyer wrote:
>>
>> Eric Niebler has done some proposal-work in this area. I think I've also
>> chatted with Vicente Botet and Eric Fiselier on the subject. The search
>> term you're looking for is "customization points."
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
>> IMHO, the most elegant solution (basically Eric Niebler's proposal) woul=
d
>> involve MASSIVE breakage of old code and is thus suited only for "std2".
>>
>> namespace std2 {
>> inline auto swap =3D [](auto& x, auto& y) constexpr -> void {
>>     if constexpr (__has_adl_swap(x, y)) {
>>         swap(x, y);
>>     } else if constexpr (__has_swap_member_function(x, y)) {
>>         x.swap(y);
>>     } else {
>>         auto temp =3D x;
>>         x =3D std::move(y);
>>         y =3D std::move(temp);
>>     }
>> };
>> } // namespace std2
>>
>
> I'm not sure I entirely agree with the specific implementation, but this
> kind of thing really sounds like something that ought to be supported in
> the language in some way. I justify that by pointing out that the languag=
e
> actually does support this in two places: range-based `for` and structure=
d
> binding, in searching for `begin/end` and `get`, respectively.
>

FWIW: Structured binding actually searches for a whole mess of names,
including `tuple_size` and `tuple_element` (both of which it looks up *only=
*
in namespace std). So IMO "structured binding" should be an item on the
ever-growing list of "ill-advised places where a customization-point
feature was clearly needed but never actually designed," and *not* on the
list of "nice things to copy the design of."


[...] This is also why I don't agree with the specific implementation,
> since non-member functions have overriding priority over members. By
> contrast, both `for` and structured binding give members priority.
>

That's fair. Consider the specific implementation hereby amended to prefer
member x.swap(y) over non-member swap(x,y).



> If language features like range-based `for` and structured binding can do
> this specific kind of thing, then it seems clear that users of the langua=
ge
> ought to be able to set such things up as well. And not with ad-hoc
> solutions like the above, but with some kind of real language feature.
>

We agree that regular users ought to be able to set up customization points
for their own stuff; indeed, basically every library in existence *already*
has to solve the customization-point problem one way or another.  The
problem with making customization points like std::swap into "language
features" is that (AFAICT) that seems to point in the direction of a
solution that is *more* special-cased and *harder* for regular users to
adapt for their own libraries.

If I can solve the problem with an idiom that relies only on existing C++17
language features, then surely it would be a bad idea to come up with an
idiom that relies on non-existent language features; especially if we then
had to *propose* those language features and ram them through EWG motivated
only by this new swap idiom?


Maybe to avoid the UFC issues, it would work like this. We provide a way to
> call a function (which is distinct from regular call syntax, thus pacifyi=
ng
> the anti-UFC people) where you specify at the call site that you're using
> the special lookup rules (check members, then check ADL, and if neither o=
f
> them work, use the default). And you provide a way to define a function
> which represents one of the default cases when calling via these special
> lookup rules (otherwise, it acts like a regular function).
>

I have no really smart things to contribute here, but I'll note in passing
that this sounds like the sort of thing that reflection
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0194r3.html>
might be good at; e.g. we could write a template my::specialcall taking a
compile-time string and using reflection to figure out whether any member
function by that name actually existed =E2=80=94

    my::specialcall<"swap"sl
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4121.pdf>>(x, y);

=E2=80=94 except for the above's high probability of breaking cross-referen=
cing
utilities like Kythe by hiding function names inside things that look like
arbitrary string values. (Which might already be a known issue blocking
reflection, for all I know.)


Notice that because this "std2::swap" is an object, not a function:
>> - you can pass it to an STL function template without any hassle (as
>> opposed to the punctuation soup of std::less<>{})
>>
>
> Or we could just have lifting lambdas and deal with it that way. Whatever
> happened to P0119, anyway?
>

No idea. I've been toying with the idea of writing a real proposal for the
[]foo syntax for Albuquerque, but I've got too many other things going on
to actually get started on that.


>
> - there is no temptation to "specialize" it via reopening namespace std2
>> (as there is, dangerously, with std::swap)
>> - there is no temptation to "overload" it via reopening namespace std2
>> (as there is, fatally, with std::swap)
>>
>
> A good language feature for customization points would remove such
> temptations as well.
>

Yes; or to put it equivalently, "If a [language] feature does *not* remove
such temptations, then it is *not* good."  We agree on this.  I merely
listed those bullet points to demonstrate that my/Eric's proposed feature
isn't conspicuously not-good. (But logically, it might be not-good for some
other reason.  "Removing such temptations" is a *necessary* but
*insufficient* condition for goodness.)

Arthur

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0%2BdnpNXSaJUvgGf%2BV3XxTAnzYR7V4x-RbMu5Eg=
3v5f6LQ%40mail.gmail.com.

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

<div dir=3D"ltr">On Tue, May 2, 2017 at 7:26 PM, Nicol Bolas <span dir=3D"l=
tr">&lt;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@=
gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D=
"gmail_quote"><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><div cla=
ss=3D"h5">On Tuesday, May 2, 2017 at 10:08:12 PM UTC-4, Arthur O&#39;Dwyer =
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>Eric Ni=
ebler has done some proposal-work in this area. I think I&#39;ve also chatt=
ed with Vicente Botet and Eric Fiselier on the subject. The search term you=
&#39;re looking for is &quot;customization points.&quot;</div><div><a href=
=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html" rel=
=3D"nofollow" target=3D"_blank">http://www.open-std.org/jtc1/s<wbr>c22/wg21=
/docs/papers/2015/n438<wbr>1.html</a><br></div><div>IMHO, the most elegant =
solution (basically Eric Niebler&#39;s proposal) would involve MASSIVE brea=
kage of old code and is thus suited only for &quot;std2&quot;.</div><div><b=
r></div><div>namespace std2 {</div><div>inline auto swap =3D [](auto&amp; x=
, auto&amp; y) constexpr -&gt; void {</div><div>=C2=A0 =C2=A0 if constexpr =
(__has_adl_swap(x, y)) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 swap(x, y);<=
/div><div>=C2=A0 =C2=A0 } else if constexpr (__has_swap_member_function(x, =
y)) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 x.swap(y);</div><div>=C2=A0 =C2=
=A0 } else {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto temp =3D x;</div><d=
iv>=C2=A0 =C2=A0 =C2=A0 =C2=A0 x =3D std::move(y);</div><div>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 y =3D std::move(temp);</div><div>=C2=A0 =C2=A0 }<br></div><di=
v>};</div><div>} // namespace std2</div></div></blockquote></div></div><div=
><br>I&#39;m not sure I entirely agree with the specific implementation, bu=
t this kind of thing really sounds like something that ought to be supporte=
d in the language in some way. I justify that by pointing out that the lang=
uage actually does support this in two places: range-based `for` and struct=
ured binding, in searching for `begin/end` and `get`, respectively.<br></di=
v></div></blockquote><div><br></div><div>FWIW: Structured binding actually =
searches for a whole mess of names, including `tuple_size` and `tuple_eleme=
nt` (both of which it looks up <i><b>only</b></i> in namespace std). So IMO=
 &quot;structured binding&quot; should be an item on the ever-growing list =
of &quot;ill-advised places where a customization-point feature was clearly=
 needed but never actually designed,&quot; and <b><i>not</i></b> on the lis=
t of &quot;nice things to copy the design of.&quot;</div><div><br></div><di=
v><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>[...] This=
 is also why I don&#39;t agree with the specific implementation, since non-=
member functions have overriding priority over members. By contrast, both `=
for` and structured binding give members priority.<br></div></div></blockqu=
ote><div><br></div><div>That&#39;s fair. Consider the specific implementati=
on hereby amended to prefer member x.swap(y) over non-member swap(x,y).</di=
v><div><br></div><div>=C2=A0</div><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>If language features like range-based `for` and structured bi=
nding can do this specific kind of thing, then it seems clear that users of=
 the language ought to be able to set such things up as well. And not with =
ad-hoc solutions like the above, but with some kind of real language featur=
e.<br></div></div></blockquote><div><br></div><div>We agree that regular us=
ers ought to be able to set up customization points for their own stuff; in=
deed, basically every library in existence <i><b>already</b></i> has to sol=
ve the customization-point problem one way or another.=C2=A0 The problem wi=
th making customization points like std::swap into &quot;language features&=
quot; is that (AFAICT) that seems to point in the direction of a solution t=
hat is=C2=A0<i>more</i> special-cased and=C2=A0<i>harder</i> for regular us=
ers to adapt for their own libraries.</div><div><br></div><div>If I can sol=
ve the problem with an idiom that relies only on existing C++17 language fe=
atures, then surely it would be a bad idea to come up with an idiom that re=
lies on non-existent language features; especially if we then had to <i>pro=
pose</i> those language features and ram them through EWG motivated only by=
 this new swap idiom?</div><div><br></div><div><br></div><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>Maybe to avoid the UFC issues, it would=
 work like this. We provide a way to call a function (which is distinct fro=
m regular call syntax, thus pacifying the anti-UFC people) where you specif=
y at the call site that you&#39;re using the special lookup rules (check me=
mbers, then check ADL, and if neither of them work, use the default). And y=
ou provide a way to define a function which represents one of the default c=
ases when calling via these special lookup rules (otherwise, it acts like a=
 regular function).<br></div></div></blockquote><div><br></div><div>I have =
no really smart things to contribute here, but I&#39;ll note in passing tha=
t this sounds like the sort of thing that <a href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2017/p0194r3.html">reflection</a> might be goo=
d at; e.g. we could write a template my::specialcall taking a compile-time =
string and using reflection to figure out whether any member function by th=
at name actually existed =E2=80=94</div><div><br></div><div><font face=3D"m=
onospace, monospace">=C2=A0 =C2=A0 my::specialcall&lt;<a href=3D"http://www=
..open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4121.pdf">&quot;swap&quot;sl=
</a>&gt;(x, y);</font></div><div><br></div><div>=E2=80=94 except for the ab=
ove&#39;s high probability of breaking cross-referencing utilities like Kyt=
he by hiding function names inside things that look like arbitrary string v=
alues. (Which might already be a known issue blocking reflection, for all I=
 know.)</div><div><br></div><div><br></div><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 class=3D""><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>Notice that because this &quot;std2::swap&quot; is an o=
bject, not a function:<br></div><div>- you can pass it to an STL function t=
emplate without any hassle (as opposed to the punctuation soup of std::less=
&lt;&gt;{})</div></div></blockquote></span><div><br>Or we could just have l=
ifting lambdas and deal with it that way. Whatever happened to P0119, anywa=
y?<br></div></div></blockquote><div><br></div><div>No idea. I&#39;ve been t=
oying with the idea of writing a real proposal for the <font face=3D"monosp=
ace, monospace">[]foo</font> syntax for Albuquerque, but I&#39;ve got too m=
any other things going on to actually get started on that.</div><div>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><span =
class=3D""><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>- =
there is no temptation to &quot;specialize&quot; it via reopening namespace=
 std2 (as there is, dangerously, with std::swap)<br></div><div>- there is n=
o temptation to &quot;overload&quot; it via reopening namespace std2 (as th=
ere is, fatally, with std::swap)<br></div></div></blockquote></span><div><b=
r>A good language feature for customization points would remove such tempta=
tions as well.</div></div></blockquote><div><br></div><div>Yes; or to put i=
t equivalently, &quot;If a [language] feature does <i>not</i> remove such t=
emptations, then it is <i>not</i> good.&quot; =C2=A0We agree on this.=C2=A0=
 I merely listed those bullet points to demonstrate that my/Eric&#39;s prop=
osed feature isn&#39;t conspicuously not-good. (But logically, it might be =
not-good for some other reason. =C2=A0&quot;Removing such temptations&quot;=
 is a <i>necessary</i> but <i>insufficient</i> condition for goodness.)</di=
v><div><br></div><div>Arthur</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BdnpNXSaJUvgGf%2BV3XxTAnzYR7=
V4x-RbMu5Eg3v5f6LQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2Bdnp=
NXSaJUvgGf%2BV3XxTAnzYR7V4x-RbMu5Eg3v5f6LQ%40mail.gmail.com</a>.<br />

--f403045c297e098d0e054e961565--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 2 May 2017 21:13:16 -0700 (PDT)
Raw View
------=_Part_4979_1734191924.1493784796252
Content-Type: multipart/alternative;
 boundary="----=_Part_4980_1965275390.1493784796253"

------=_Part_4980_1965275390.1493784796253
Content-Type: text/plain; charset=UTF-8

On Tuesday, May 2, 2017 at 11:16:31 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Tue, May 2, 2017 at 7:26 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> On Tuesday, May 2, 2017 at 10:08:12 PM UTC-4, Arthur O'Dwyer wrote:
>>>
>>> Eric Niebler has done some proposal-work in this area. I think I've also
>>> chatted with Vicente Botet and Eric Fiselier on the subject. The search
>>> term you're looking for is "customization points."
>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
>>> IMHO, the most elegant solution (basically Eric Niebler's proposal)
>>> would involve MASSIVE breakage of old code and is thus suited only for
>>> "std2".
>>>
>>> namespace std2 {
>>> inline auto swap = [](auto& x, auto& y) constexpr -> void {
>>>     if constexpr (__has_adl_swap(x, y)) {
>>>         swap(x, y);
>>>     } else if constexpr (__has_swap_member_function(x, y)) {
>>>         x.swap(y);
>>>     } else {
>>>         auto temp = x;
>>>         x = std::move(y);
>>>         y = std::move(temp);
>>>     }
>>> };
>>> } // namespace std2
>>>
>>
>> I'm not sure I entirely agree with the specific implementation, but this
>> kind of thing really sounds like something that ought to be supported in
>> the language in some way. I justify that by pointing out that the language
>> actually does support this in two places: range-based `for` and structured
>> binding, in searching for `begin/end` and `get`, respectively.
>>
>
> FWIW: Structured binding actually searches for a whole mess of names,
> including `tuple_size` and `tuple_element` (both of which it looks up
> *only* in namespace std). So IMO "structured binding" should be an item
> on the ever-growing list of "ill-advised places where a customization-point
> feature was clearly needed but never actually designed," and *not* on the
> list of "nice things to copy the design of."
>

To be honest... how else *could* it work? Oh sure, you might have found
some way to make `tuple_size` be a `constexpr` function or something
(though how you pass a parameter of type `E` to allow ADL without actually
having to *create* an object of that type would be an interesting trick).
But `tuple_element` has got to resolve to a *type*. And ADL just doesn't
exist for meta-functions.

Now this actually argues strongly for a more comprehensive approach to
customization points as a language feature. One that can include both
runtime and *compile-time* function customization. This would essentially
allow a user to invoke the rules of ADL to look up the exact template being
instantiated.

[...] This is also why I don't agree with the specific implementation,
>> since non-member functions have overriding priority over members. By
>> contrast, both `for` and structured binding give members priority.
>>
>
> That's fair. Consider the specific implementation hereby amended to prefer
> member x.swap(y) over non-member swap(x,y).
>
>
>> If language features like range-based `for` and structured binding can do
>> this specific kind of thing, then it seems clear that users of the language
>> ought to be able to set such things up as well. And not with ad-hoc
>> solutions like the above, but with some kind of real language feature.
>>
>
> We agree that regular users ought to be able to set up customization
> points for their own stuff; indeed, basically every library in existence
> *already* has to solve the customization-point problem one way or
> another.  The problem with making customization points like std::swap into
> "language features" is that (AFAICT) that seems to point in the direction
> of a solution that is *more* special-cased and *harder* for regular users
> to adapt for their own libraries.
>
> If I can solve the problem with an idiom that relies only on existing
> C++17 language features, then surely it would be a bad idea to come up with
> an idiom that relies on non-existent language features; especially if we
> then had to *propose* those language features and ram them through EWG
> motivated only by this new swap idiom?
>

Um, no, it wouldn't be a bad idea at all.

Consider the code you just showed me. I pointed out a deficiency in it: the
fact that it works the wrong way, relative to the hard-coded customization
points. And that was written by an actual C++ expert, which means that it's
very easy for a novice to get this idiom wrong. And a novice is far less
likely to realize they got it wrong. After all, in 99% of the cases, it'll
still work. It just has a subtle bug in it, which is worse in many respects
than being straight-up broken.

Having all customization points work the same way is really important.
Relying on everyone to use an idiom like this in exactly the same way is
essentially begging to fail. Oh sure, the standard library can mandate the
behavior of its customization points. But users need to be able to build
their own customization points, and to do so in a way that works just like
standard library ones.

And that's assuming that users are clever enough to implement
`__has_adl_swap` and `__has_swap_member_function` *correctly* in the first
place. I'm no metaprogramming expert, but I have no idea how to even *begin*
implementing the ADL check.

Just as Boost.Lambda helped prove that lambdas ought to be a language
feature, I think the weaknesses of this idiom (which is the best
customization interface we've been able to create thus far) helps show that
this ought to be a language feature too.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/991619cd-f935-43e0-85a5-b417cd6afe58%40isocpp.org.

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

<div dir=3D"ltr">On Tuesday, May 2, 2017 at 11:16:31 PM UTC-4, Arthur O&#39=
;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
On Tue, May 2, 2017 at 7:26 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"ROWa40wMBAAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck...@gmai=
l.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><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><div>On Tuesday, May 2, 2017 at 10=
:08:12 PM UTC-4, Arthur O&#39;Dwyer wrote:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div>Eric Niebler has done some proposal-work in th=
is area. I think I&#39;ve also chatted with Vicente Botet and Eric Fiselier=
 on the subject. The search term you&#39;re looking for is &quot;customizat=
ion points.&quot;</div><div><a href=3D"http://www.open-std.org/jtc1/sc22/wg=
21/docs/papers/2015/n4381.html" rel=3D"nofollow" target=3D"_blank" onmoused=
own=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.ope=
n-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fn4381.html\x26sa\x3=
dD\x26sntz\x3d1\x26usg\x3dAFQjCNFLiQ7Hx7gXLuMVFVN3Tb7h1FvcMw&#39;;return tr=
ue;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%=
2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fn4381.html=
\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFLiQ7Hx7gXLuMVFVN3Tb7h1FvcMw&#39;;=
return true;">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2015/=
<wbr>n4381.html</a><br></div><div>IMHO, the most elegant solution (basicall=
y Eric Niebler&#39;s proposal) would involve MASSIVE breakage of old code a=
nd is thus suited only for &quot;std2&quot;.</div><div><br></div><div>names=
pace std2 {</div><div>inline auto swap =3D [](auto&amp; x, auto&amp; y) con=
stexpr -&gt; void {</div><div>=C2=A0 =C2=A0 if constexpr (__has_adl_swap(x,=
 y)) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 swap(x, y);</div><div>=C2=A0 =
=C2=A0 } else if constexpr (__has_swap_member_function(x, y)) {</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 x.swap(y);</div><div>=C2=A0 =C2=A0 } else {</di=
v><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto temp =3D x;</div><div>=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 x =3D std::move(y);</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 y =
=3D std::move(temp);</div><div>=C2=A0 =C2=A0 }<br></div><div>};</div><div>}=
 // namespace std2</div></div></blockquote></div></div><div><br>I&#39;m not=
 sure I entirely agree with the specific implementation, but this kind of t=
hing really sounds like something that ought to be supported in the languag=
e in some way. I justify that by pointing out that the language actually do=
es support this in two places: range-based `for` and structured binding, in=
 searching for `begin/end` and `get`, respectively.<br></div></div></blockq=
uote><div><br></div><div>FWIW: Structured binding actually searches for a w=
hole mess of names, including `tuple_size` and `tuple_element` (both of whi=
ch it looks up <i><b>only</b></i> in namespace std). So IMO &quot;structure=
d binding&quot; should be an item on the ever-growing list of &quot;ill-adv=
ised places where a customization-point feature was clearly needed but neve=
r actually designed,&quot; and <b><i>not</i></b> on the list of &quot;nice =
things to copy the design of.&quot;</div></div></div></div></blockquote><di=
v><br>To be honest... how else <i>could</i> it work? Oh sure, you might hav=
e found some way to make `tuple_size` be a `constexpr` function or somethin=
g (though how you pass a parameter of type `E` to allow ADL without actuall=
y having to <i>create</i> an object of that type would be an interesting tr=
ick). But `tuple_element` has got to resolve to a <i>type</i>. And ADL just=
 doesn&#39;t exist for meta-functions.<br><br>Now this actually argues stro=
ngly for a more comprehensive approach to customization points as a languag=
e feature. One that can include both runtime and <i>compile-time</i> functi=
on customization. This would essentially allow a user to invoke the rules o=
f ADL to look up the exact template being instantiated.<br><br></div><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"><div><div class=3D"=
gmail_quote"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>[...] This is also why I don&#39;t agree with the specific implementation=
, since non-member functions have overriding priority over members. By cont=
rast, both `for` and structured binding give members priority.<br></div></d=
iv></blockquote><div><br></div><div>That&#39;s fair. Consider the specific =
implementation hereby amended to prefer member x.swap(y) over non-member sw=
ap(x,y).</div><div></div><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>If language features like range-based `for` and structu=
red binding can do this specific kind of thing, then it seems clear that us=
ers of the language ought to be able to set such things up as well. And not=
 with ad-hoc solutions like the above, but with some kind of real language =
feature.<br></div></div></blockquote><div><br></div><div>We agree that regu=
lar users ought to be able to set up customization points for their own stu=
ff; indeed, basically every library in existence <i><b>already</b></i> has =
to solve the customization-point problem one way or another.=C2=A0 The prob=
lem with making customization points like std::swap into &quot;language fea=
tures&quot; is that (AFAICT) that seems to point in the direction of a solu=
tion that is=C2=A0<i>more</i> special-cased and=C2=A0<i>harder</i> for regu=
lar users to adapt for their own libraries.</div><div><br></div><div>If I c=
an solve the problem with an idiom that relies only on existing C++17 langu=
age features, then surely it would be a bad idea to come up with an idiom t=
hat relies on non-existent language features; especially if we then had to =
<i>propose</i> those language features and ram them through EWG motivated o=
nly by this new swap idiom?</div></div></div></div></blockquote><div><br>Um=
, no, it wouldn&#39;t be a bad idea at all.<br><br>Consider the code you ju=
st showed me. I pointed out a deficiency in it: the fact that it works the =
wrong way, relative to the hard-coded customization points. And that was wr=
itten by an actual C++ expert, which means that it&#39;s very easy for a no=
vice to get this idiom wrong. And a novice is far less likely to realize th=
ey got it wrong. After all, in 99% of the cases, it&#39;ll still work. It j=
ust has a subtle bug in it, which is worse in many respects than being stra=
ight-up broken.<br><br>Having all customization points work the same way is=
 really important. Relying on everyone to use an idiom like this in exactly=
 the same way is essentially begging to fail. Oh sure, the standard library=
 can mandate the behavior of its customization points. But users need to be=
 able to build their own customization points, and to do so in a way that w=
orks just like standard library ones.<br><br>And that&#39;s assuming that u=
sers are clever enough to implement `__has_adl_swap` and `__has_swap_member=
_function` <i>correctly</i> in the first place. I&#39;m no metaprogramming =
expert, but I have no idea how to even <i>begin</i> implementing the ADL ch=
eck.<br><br>Just as Boost.Lambda helped prove that lambdas ought to be a la=
nguage feature, I think the weaknesses of this idiom (which is the best cus=
tomization interface we&#39;ve been able to create thus far) helps show tha=
t this ought to be a language feature too.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/991619cd-f935-43e0-85a5-b417cd6afe58%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/991619cd-f935-43e0-85a5-b417cd6afe58=
%40isocpp.org</a>.<br />

------=_Part_4980_1965275390.1493784796253--

------=_Part_4979_1734191924.1493784796252--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 2 May 2017 22:17:30 -0700
Raw View
--94eb2c195d90ea3550054e97c584
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tue, May 2, 2017 at 9:13 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Tuesday, May 2, 2017 at 11:16:31 PM UTC-4, Arthur O'Dwyer wrote:
>>
>>
>> FWIW: Structured binding actually searches for a whole mess of names,
>> including `tuple_size` and `tuple_element` (both of which it looks up
>> *only* in namespace std). So IMO "structured binding" should be an item
>> on the ever-growing list of "ill-advised places where a customization-po=
int
>> feature was clearly needed but never actually designed," and *not* on
>> the list of "nice things to copy the design of."
>>
>
> To be honest... how else *could* it work? Oh sure, you might have found
> some way to make `tuple_size` be a `constexpr` function or something
> (though how you pass a parameter of type `E` to allow ADL without actuall=
y
> having to *create* an object of that type would be an interesting trick).
> But `tuple_element` has got to resolve to a *type*. And ADL just doesn't
> exist for meta-functions.
>

In the case of structured binding, the Right Thing would have been to not
rely on tuple_element at all. They could easily have made

    auto [x,y] =3D t;

equivalent to

    auto __t =3D t;
    auto&& x =3D get<0>(__t);  // with compiler magic to make decltype(x)
appear as a non-reference type, of course
    auto&& y =3D get<1>(__t);

without any reference to tuple_element.  (And notice that the rewrite
doesn't explicitly use tuple_size, either. tuple_size is needed only to
generate annoying compiler diagnostics in the case that t "has" more than 2
elements. How to bind only the first K ordinates of a tuple and discard the
rest is a perennial topic of discussion on this mailing list.)


[...] This is also why I don't agree with the specific implementation,
>>> since non-member functions have overriding priority over members. By
>>> contrast, both `for` and structured binding give members priority.
>>>
>>
>> That's fair. Consider the specific implementation hereby amended to
>> prefer member x.swap(y) over non-member swap(x,y).
>>
>
> [...] Consider the code you just showed me. I pointed out a deficiency in
> it: the fact that it works the wrong way, relative to the hard-coded
> customization points. And that was written by an actual C++ expert, which
> means that it's very easy for a novice to get this idiom wrong. And a
> novice is far less likely to realize they got it wrong. After all, in 99%
> of the cases, it'll still work. It just has a subtle bug in it, which is
> worse in many respects than being straight-up broken.
>

I'd argue that if we had proper customization points (e.g. these
inline-variable-based ones), then the difference between "subtle bug" and
"perfectly correct" would become academic =E2=80=94 I'm inclined to go furt=
her and
say "would become nonsensical." The "subtle bug" you identified would cause
problems during execution if-and-only-if:

- The user provided x.swap(y) with functionality 1
- The user provided an ADL swap(x, y) with functionality 2, observably
different from functionality 1
- The user called std2::swap(x, y) expecting to receive functionality 1

I claim that bullet points #2 and #3 are deep into "well, what did you
expect to happen?"-land, even in C++03. When you provide two swap
functions, you'd better make darn sure that their behaviors are identical;
and even if by accident their behaviors are different, you'd better not
write code that *relies* on that bug!

If we had std2::swap today, there would be no reason for anyone to
implement ADL swap(x, y) ever again; not even to implement it in terms of
x.swap(y).  Forget having two swap functions with different behaviors;
there'd be no reason to provide two swap functions *period*.  You'd simply
implement your swap function as x.swap(y), and call it as std2::swap(x, y),
and that would be all.


Having all customization points work the same way is really important.
> Relying on everyone to use an idiom like this in exactly the same way is
> essentially begging to fail. Oh sure, the standard library can mandate th=
e
> behavior of its customization points. But users need to be able to build
> their own customization points, and to do so in a way that works just lik=
e
> standard library ones.
>

Just like the state of C++03 iterators (begin() and end()), right?  I claim
that users who need to implement their own iterators can in fact do so, and
users who need to implement their own customization points will in fact be
able to do so. Just as with iterators, the user's solution will probably
involve some cut-and-paste from the standard library. (Today we can't
cut-and-paste customization points from the standard library because the
standard library has no solution for customization points. But if we added
std2::swap, then it would have *a* solution.)

And that's assuming that users are clever enough to implement
> `__has_adl_swap` and `__has_swap_member_function` *correctly* in the
> first place. I'm no metaprogramming expert, but I have no idea how to eve=
n
> *begin* implementing the ADL check.
>

I think it's easy, as long as you don't care about swap functions that show
up in the *global* namespace (not in the ADL namespace in question) after
the inclusion of <std2_swap>. (It's unclear to me whether functions in the
global namespace ought to be considered "ADL" or not. Anyway, this is
another case of "well, what did you *expect* to happen?".)
https://wandbox.org/permlink/vrqWSFw7mI6xi6sY



> Just as Boost.Lambda helped prove that lambdas ought to be a language
> feature, I think the weaknesses of this idiom (which is the best
> customization interface we've been able to create thus far) helps show th=
at
> this ought to be a language feature too.
>

That's a fair analogy; but I still can't picture what kind of core language
feature would help here.  With lambdas it was pretty obvious what the core
feature was; the only bikeshedding was over the spelling of []. With
customization points, it's not real clear *what* we're trying to spell in
the first place.  A new call syntax?  A new way of doing name lookup?  A
new way of defining functions?

Here's an idea inspired by that "core language feature" starting point.
Here *customization_point* is a contextual keyword that means "Compiler,
please wrap this function's body in boilerplate so that it'll call
<firstarg>.<functionname>(<otherargs>) if possible; or delegate to the
<functionname> found by ADL if possible; or else fall back on this
function's body as the default implementation."  (The function's body might
reasonably be =3Ddelete'd.)

    namespace std3 {
        template<class T>
        auto swap(T& a, T& b) *customization_point* {
            auto temp =3D std::move(a);
            a =3D std::move(b);
            b =3D std::move(temp);
        }
    } // namespace std3

    std3::swap(i, j);  // implicitly attempts to call i.swap(j) instead, if
it exists

    using std3::swap;
    swap(m, n);  // plain old unqualified name lookup; but it might find
std3::swap,
         // in which case we implicitly attempt to call m.swap(n) instead,
and so on

Arthur

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0Kj%3D6CpZ0Ceoj-V7Przk1S7v8%3DEgN0VbDis6Em=
aaOkruA%40mail.gmail.com.

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

<div dir=3D"ltr">On Tue, May 2, 2017 at 9:13 PM, Nicol Bolas <span dir=3D"l=
tr">&lt;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@=
gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D=
"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, May 2, 2017 at =
11:16:31 PM UTC-4, Arthur O&#39;Dwyer wrote:<span class=3D"gmail-"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wid=
th:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br></div><d=
iv>FWIW: Structured binding actually searches for a whole mess of names, in=
cluding `tuple_size` and `tuple_element` (both of which it looks up <i><b>o=
nly</b></i> in namespace std). So IMO &quot;structured binding&quot; should=
 be an item on the ever-growing list of &quot;ill-advised places where a cu=
stomization-point feature was clearly needed but never actually designed,&q=
uot; and <b><i>not</i></b> on the list of &quot;nice things to copy the des=
ign of.&quot;</div></div></div></div></blockquote></span><div><br>To be hon=
est... how else <i>could</i> it work? Oh sure, you might have found some wa=
y to make `tuple_size` be a `constexpr` function or something (though how y=
ou pass a parameter of type `E` to allow ADL without actually having to <i>=
create</i> an object of that type would be an interesting trick). But `tupl=
e_element` has got to resolve to a <i>type</i>. And ADL just doesn&#39;t ex=
ist for meta-functions.<br></div></div></blockquote><div><br></div><div>In =
the case of structured binding, the Right Thing would have been to not rely=
 on <font face=3D"monospace, monospace">tuple_element</font> at all. They c=
ould easily have made</div><div><br></div><div><font face=3D"monospace, mon=
ospace">=C2=A0 =C2=A0 auto [x,y] =3D t;</font></div><div><br></div><div>equ=
ivalent to</div><div><br></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 auto __t =3D t;</font></div><div><font face=3D"monospace, monosp=
ace">=C2=A0 =C2=A0 auto&amp;&amp; x =3D get&lt;0&gt;(__t); =C2=A0// with co=
mpiler magic to make decltype(x) appear as a non-reference type, of course<=
/font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto&amp=
;&amp; y =3D get&lt;1&gt;(__t);</font></div><div><br></div><div>without any=
 reference to <font face=3D"monospace, monospace">tuple_element</font>. =C2=
=A0(And notice that the rewrite doesn&#39;t explicitly use <font face=3D"mo=
nospace, monospace">tuple_size</font>, either. <font face=3D"monospace, mon=
ospace">tuple_size</font> is needed only to generate annoying compiler diag=
nostics in the case that <font face=3D"monospace, monospace">t</font> &quot=
;has&quot; more than 2 elements. How to bind only the first K ordinates of =
a tuple and discard the rest is a perennial topic of discussion on this mai=
ling list.)</div><div><br></div><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-c=
olor:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D=
"ltr"><span class=3D"gmail-"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,2=
04);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-l=
eft-style:solid;padding-left:1ex"><div dir=3D"ltr"><div>[...] This is also =
why I don&#39;t agree with the specific implementation, since non-member fu=
nctions have overriding priority over members. By contrast, both `for` and =
structured binding give members priority.<br></div></div></blockquote><div>=
<br></div><div>That&#39;s fair. Consider the specific implementation hereby=
 amended to prefer member x.swap(y) over non-member swap(x,y).</div></div><=
/div></blockquote></span><div><br>[...] Consider the code you just showed m=
e. I pointed out a deficiency in it: the fact that it works the wrong way, =
relative to the hard-coded customization points. And that was written by an=
 actual C++ expert, which means that it&#39;s very easy for a novice to get=
 this idiom wrong. And a novice is far less likely to realize they got it w=
rong. After all, in 99% of the cases, it&#39;ll still work. It just has a s=
ubtle bug in it, which is worse in many respects than being straight-up bro=
ken.<br></div></div></blockquote><div><br></div><div>I&#39;d argue that if =
we had proper customization points (e.g. these inline-variable-based ones),=
 then the difference between &quot;subtle bug&quot; and &quot;perfectly cor=
rect&quot; would become academic =E2=80=94 I&#39;m inclined to go further a=
nd say &quot;would become nonsensical.&quot; The &quot;subtle bug&quot; you=
 identified would cause problems during execution if-and-only-if:</div><div=
><br></div><div>- The user provided=C2=A0<font face=3D"monospace, monospace=
">x.swap(y)</font>=C2=A0with functionality 1</div><div>- The user provided =
an ADL <font face=3D"monospace, monospace">swap(x, y)</font>=C2=A0with func=
tionality 2, observably different from functionality 1</div><div>- The user=
 called <font face=3D"monospace, monospace">std2::swap(x, y)</font> expecti=
ng to receive functionality 1</div><div><br></div><div>I claim that bullet =
points #2 and #3 are deep into &quot;well, what did you expect to happen?&q=
uot;-land, even in C++03. When you provide two swap functions, you&#39;d be=
tter make darn sure that their behaviors are identical; and even if by acci=
dent their behaviors are different, you&#39;d better not write code that <i=
>relies</i> on that bug!</div><div><br></div><div>If we had <font face=3D"m=
onospace, monospace">std2::swap</font> today, there would be no reason for =
anyone to implement ADL <font face=3D"monospace, monospace">swap(x, y)</fon=
t> ever again; not even to implement it in terms of <font face=3D"monospace=
, monospace">x.swap(y)</font>.=C2=A0 Forget having two swap functions with =
different behaviors; there&#39;d be no reason to provide two swap functions=
 <i><b>period</b></i>.=C2=A0 You&#39;d simply implement your swap function =
as=C2=A0<font face=3D"monospace, monospace">x.swap(y)</font>, and call it a=
s=C2=A0<font face=3D"monospace, monospace">std2::swap(x, y)</font>, and tha=
t would be all.</div><div><br></div><div><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-le=
ft-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div di=
r=3D"ltr"><div>Having all customization points work the same way is really =
important. Relying on everyone to use an idiom like this in exactly the sam=
e way is essentially begging to fail. Oh sure, the standard library can man=
date the behavior of its customization points. But users need to be able to=
 build their own customization points, and to do so in a way that works jus=
t like standard library ones.<br></div></div></blockquote><div><br></div><d=
iv>Just like the state of C++03 iterators (<font face=3D"monospace, monospa=
ce">begin()</font> and <font face=3D"monospace, monospace">end()</font>), r=
ight?=C2=A0 I claim that users who need to implement their own iterators ca=
n in fact do so, and users who need to implement their own customization po=
ints will in fact be able to do so. Just as with iterators, the user&#39;s =
solution will probably involve some cut-and-paste from the standard library=
.. (Today we can&#39;t cut-and-paste customization points from the standard =
library because the standard library has no solution for customization poin=
ts. But if we added <font face=3D"monospace, monospace">std2::swap</font>, =
then it would have <i>a</i> solution.)</div><div><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;b=
order-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"=
><div dir=3D"ltr"><div>And that&#39;s assuming that users are clever enough=
 to implement `__has_adl_swap` and `__has_swap_member_function` <i>correctl=
y</i> in the first place. I&#39;m no metaprogramming expert, but I have no =
idea how to even <i>begin</i> implementing the ADL check.<br></div></div></=
blockquote><div><br></div><div>I think it&#39;s easy, as long as you don&#3=
9;t care about swap functions that show up in the <i>global</i> namespace (=
not in the ADL namespace in question) after the inclusion of &lt;std2_swap&=
gt;. (It&#39;s unclear to me whether functions in the global namespace ough=
t to be considered &quot;ADL&quot; or not. Anyway, this is another case of =
&quot;well, what did you <i>expect</i> to happen?&quot;.)</div><div><a href=
=3D"https://wandbox.org/permlink/vrqWSFw7mI6xi6sY">https://wandbox.org/perm=
link/vrqWSFw7mI6xi6sY</a><br></div><div><br></div><div>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wid=
th:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>Just as Boost.Lambda helped prove that lambd=
as ought to be a language feature, I think the weaknesses of this idiom (wh=
ich is the best customization interface we&#39;ve been able to create thus =
far) helps show that this ought to be a language feature too.<br></div></di=
v></blockquote><div><br></div><div>That&#39;s a fair analogy; but I still c=
an&#39;t picture what kind of core language feature would help here.=C2=A0 =
With lambdas it was pretty obvious what the core feature was; the only bike=
shedding was over the spelling of <font face=3D"monospace, monospace">[]</f=
ont>. With customization points, it&#39;s not real clear <i>what</i> we&#39=
;re trying to spell in the first place.=C2=A0 A new call syntax?=C2=A0 A ne=
w way of doing name lookup?=C2=A0 A new way of defining functions?</div><di=
v><br></div><div>Here&#39;s an idea inspired by that &quot;core language fe=
ature&quot; starting point.=C2=A0 Here <font face=3D"monospace, monospace">=
<b>customization_point</b></font> is a contextual keyword that means &quot;=
Compiler, please wrap this function&#39;s body in boilerplate so that it&#3=
9;ll call <font face=3D"monospace, monospace">&lt;firstarg&gt;.&lt;function=
name&gt;(&lt;otherargs&gt;)</font> if possible; or delegate to the <font fa=
ce=3D"monospace, monospace">&lt;functionname&gt;</font> found by ADL if pos=
sible; or else fall back on this function&#39;s body as the default impleme=
ntation.&quot; =C2=A0(The function&#39;s body might reasonably be <font fac=
e=3D"monospace, monospace">=3Ddelete</font>&#39;d.)</div><div><br></div><di=
v><font face=3D"monospace, monospace">=C2=A0 =C2=A0 namespace std3 {</font>=
</div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
template&lt;class T&gt;</font></div><div><font face=3D"monospace, monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto swap(T&amp; a, T&amp; b) <b>customizatio=
n_point</b> {</font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 auto temp =3D std::move(a);</font></div>=
<div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 a =3D std::move(b);</font></div><div><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 b =3D std::move(temp);</fon=
t></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 }</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 } =
// namespace std3</font></div><div><font face=3D"monospace, monospace"><br>=
</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 std3::s=
wap(i, j); =C2=A0// implicitly attempts to call i.swap(j) instead, if it ex=
ists</font></div><div><font face=3D"monospace, monospace"><br></font></div>=
<div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 using std3::swap;</f=
ont></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 swap(m, n)=
; =C2=A0// plain old unqualified name lookup; but it might find std3::swap,=
</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0// in which case we implicitly attempt to call m.swap(n) inste=
ad, and so on</font></div><div><br></div><div>Arthur<br></div></div></div><=
/div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0Kj%3D6CpZ0Ceoj-V7Przk1S7v8%3DE=
gN0VbDis6EmaaOkruA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0Kj%3D6=
CpZ0Ceoj-V7Przk1S7v8%3DEgN0VbDis6EmaaOkruA%40mail.gmail.com</a>.<br />

--94eb2c195d90ea3550054e97c584--

.


Author: olaf@join.cc
Date: Wed, 3 May 2017 01:13:49 -0700 (PDT)
Raw View
------=_Part_1348_1849855896.1493799229605
Content-Type: multipart/alternative;
 boundary="----=_Part_1349_1308458586.1493799229606"

------=_Part_1349_1308458586.1493799229606
Content-Type: text/plain; charset=UTF-8

Op woensdag 3 mei 2017 04:08:12 UTC+2 schreef Arthur O'Dwyer:
>
> IMHO, the most elegant solution (basically Eric Niebler's proposal) would
> involve MASSIVE breakage of old code and is thus suited only for "std2".
>

Wouldn't it work as std::swap2?

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b125c1ef-c2aa-412b-8352-26039d3f7970%40isocpp.org.

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

<div dir=3D"ltr">Op woensdag 3 mei 2017 04:08:12 UTC+2 schreef Arthur O&#39=
;Dwyer:<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>I=
MHO, the most elegant solution (basically Eric Niebler&#39;s proposal) woul=
d involve MASSIVE breakage of old code and is thus suited only for &quot;st=
d2&quot;.</div></div></blockquote><div><br></div><div>Wouldn&#39;t it work =
as std::swap2?=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b125c1ef-c2aa-412b-8352-26039d3f7970%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b125c1ef-c2aa-412b-8352-26039d3f7970=
%40isocpp.org</a>.<br />

------=_Part_1349_1308458586.1493799229606--

------=_Part_1348_1849855896.1493799229605--

.


Author: Marc Mutz <marc.mutz@kdab.com>
Date: Wed, 3 May 2017 11:14:41 +0200
Raw View
On Wednesday 03 May 2017 10:13:49 olaf@join.cc wrote:
> Op woensdag 3 mei 2017 04:08:12 UTC+2 schreef Arthur O'Dwyer:
> > IMHO, the most elegant solution (basically Eric Niebler's proposal) would
> > involve MASSIVE breakage of old code and is thus suited only for "std2".
>
> Wouldn't it work as std::swap2?

Sorry for highjacking Olaf's reply. This is not about Olaf's answer.

While it's true that std::swap is the most-prominent example, it's also one
which really is trivial in many ways. Few are the types which these days of
move semantics _need_ a custom swap(). Unless you still need to support C++98
compilers, it's merely a questionable optimisation technique (the best you can
do it member-wise swapping, which apart from a little less memory used, is
hardly orders of magnitude faster than what the triple-move default
implementation does).

No, forget swap. The Swap Problem is not (just) about swap. Much more
interesting than swap() are those functions which are API enablers:

A class template representing angles _needs_ a sin() overload, and up pops the
question how to provide it: via ADL, even though most people will likely not
write

   using std::sin;
   return sin(a);

? Or as a specialisation of std::sin() (doen't work) or as an overload of
std::sin() (not allowed). Example: https://codereview.qt-project.org/191717
So, yeah, via ADL, and thus continues the embarrassment...


A non-std container should provide a version of LF v2's erase_if(). Even
though erase_if is only overloaded on types in namespace std, since it's
currently in namespace std::experimental, you still can't say

   erase_if(c, p);

ie. rely on ADL, but need to have another using declaration:

   using std::experimental::erase_if;
   erase_if(c, p);

This stuff usually gets a laugh from non-C++ experts already.
But note how this using declaration will fail to compile when LF v2 is not
supported, requiring adding preprocessor magic around it:

 #if defined(_cpp_lib_dunno_exact_name) && \
          __cpp_lib_dunno_exact_name >= 201411
   using std::experimental::erase_if;
 #endif
   erase_if(c, p);

Ok, all of this will be solved when erase_if moves into namespace std proper,
making this a bad example.

Let's look at STL algorithms:

A wonky container like QList can actually implement reversing as an out-of-
line function: https://codereview.qt-project.org/144071 It's not far-fetched
to want to specialise std::reverse() to call the member function, which would
require overloading std::reverse(). Or providing an ADL version, which,
however, requires every use of std::reverse() to say

   using std::reverse;
   reverse(b, e);

Here, we finally reached a case where no-one in the world writes code like
this.

As you can see, the issue is not at all restricted to swap(), begin(), size(),
data() and the very few other customisation points that are being discussed.
Do you seriously want to make a std::sin2, std::reverse2, ... for every single
function in namespace std?

So I wonder: What's the rationale for not allowing adding overloads under the
same conditions as allowing partial specialisations of class templates? If a
user messes up, how is it a worse mess with overloads than with class template
specialisations? What's so scary about it that you'd rather discuss _new
language features_ to enable customisation than to allow it by what C++
provides for ages, and even novices quickly grasp: overloads?

Thanks,
Marc

--
Marc Mutz <marc.mutz@kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts

.


Author: "T. C." <rs2740@gmail.com>
Date: Wed, 3 May 2017 03:16:24 -0700 (PDT)
Raw View
------=_Part_2660_1894173438.1493806585090
Content-Type: multipart/alternative;
 boundary="----=_Part_2661_478278708.1493806585090"

------=_Part_2661_478278708.1493806585090
Content-Type: text/plain; charset=UTF-8



On Wednesday, May 3, 2017 at 1:17:34 AM UTC-4, Arthur O'Dwyer wrote:
>
> On Tue, May 2, 2017 at 9:13 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> On Tuesday, May 2, 2017 at 11:16:31 PM UTC-4, Arthur O'Dwyer wrote:
>>>
>>>
>>> FWIW: Structured binding actually searches for a whole mess of names,
>>> including `tuple_size` and `tuple_element` (both of which it looks up
>>> *only* in namespace std). So IMO "structured binding" should be an item
>>> on the ever-growing list of "ill-advised places where a customization-point
>>> feature was clearly needed but never actually designed," and *not* on
>>> the list of "nice things to copy the design of."
>>>
>>
>> To be honest... how else *could* it work? Oh sure, you might have found
>> some way to make `tuple_size` be a `constexpr` function or something
>> (though how you pass a parameter of type `E` to allow ADL without actually
>> having to *create* an object of that type would be an interesting
>> trick). But `tuple_element` has got to resolve to a *type*. And ADL just
>> doesn't exist for meta-functions.
>>
>
> In the case of structured binding, the Right Thing would have been to not
> rely on tuple_element at all. They could easily have made
>
>     auto [x,y] = t;
>
> equivalent to
>
>     auto __t = t;
>     auto&& x = get<0>(__t);  // with compiler magic to make decltype(x)
> appear as a non-reference type, of course
>     auto&& y = get<1>(__t);
>
> without any reference to tuple_element.  (And notice that the rewrite
> doesn't explicitly use tuple_size, either. tuple_size is needed only to
> generate annoying compiler diagnostics in the case that t "has" more than
> 2 elements. How to bind only the first K ordinates of a tuple and discard
> the rest is a perennial topic of discussion on this mailing list.)
>

And that magic will fail for at least one of tuple<int&>, tuple<int&&> and
tuple<int>. It can't provide the right answer for all three. Care to
explain how that is the Right Thing?

BTW, AFAIK the hardcoded begin/end/get lookup rules in the language are
impossible to implement exactly in plain C++. The ADL part can be done by
SFINAEing on the well-formedness of an unqualified call where the only
candidate found by ordinary lookup is a nonviable candidate. The tricky
part is actually the class member lookup, which goes for the member
interpretation if there's a member with the right name regardless of its
kind, type, or accessibility. I don't know of a way to check that for final
and union types.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0c1c2586-5311-4a2e-bea1-09cdab2d9707%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Wednesday, May 3, 2017 at 1:17:34 AM UTC-4, Art=
hur O&#39;Dwyer 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">On Tue, May 2, 2017 at 9:13 PM, Nicol Bolas <span dir=3D"ltr">&lt;=
<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"7PB1_ecS=
BAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;ret=
urn true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck.=
...@gmail.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-=
width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;paddin=
g-left:1ex"><div dir=3D"ltr">On Tuesday, May 2, 2017 at 11:16:31 PM UTC-4, =
Arthur O&#39;Dwyer wrote:<span><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204=
,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div><div =
class=3D"gmail_quote"><div><br></div><div>FWIW: Structured binding actually=
 searches for a whole mess of names, including `tuple_size` and `tuple_elem=
ent` (both of which it looks up <i><b>only</b></i> in namespace std). So IM=
O &quot;structured binding&quot; should be an item on the ever-growing list=
 of &quot;ill-advised places where a customization-point feature was clearl=
y needed but never actually designed,&quot; and <b><i>not</i></b> on the li=
st of &quot;nice things to copy the design of.&quot;</div></div></div></div=
></blockquote></span><div><br>To be honest... how else <i>could</i> it work=
? Oh sure, you might have found some way to make `tuple_size` be a `constex=
pr` function or something (though how you pass a parameter of type `E` to a=
llow ADL without actually having to <i>create</i> an object of that type wo=
uld be an interesting trick). But `tuple_element` has got to resolve to a <=
i>type</i>. And ADL just doesn&#39;t exist for meta-functions.<br></div></d=
iv></blockquote><div><br></div><div>In the case of structured binding, the =
Right Thing would have been to not rely on <font face=3D"monospace, monospa=
ce">tuple_element</font> at all. They could easily have made</div><div><br>=
</div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto [x,y] =3D=
 t;</font></div><div><br></div><div>equivalent to</div><div><br></div><div>=
<font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto __t =3D t;</font></d=
iv><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto&amp;&amp; x =
=3D get&lt;0&gt;(__t); =C2=A0// with compiler magic to make decltype(x) app=
ear as a non-reference type, of course</font></div><div><font face=3D"monos=
pace, monospace">=C2=A0 =C2=A0 auto&amp;&amp; y =3D get&lt;1&gt;(__t);</fon=
t></div><div><br></div><div>without any reference to <font face=3D"monospac=
e, monospace">tuple_element</font>. =C2=A0(And notice that the rewrite does=
n&#39;t explicitly use <font face=3D"monospace, monospace">tuple_size</font=
>, either. <font face=3D"monospace, monospace">tuple_size</font> is needed =
only to generate annoying compiler diagnostics in the case that <font face=
=3D"monospace, monospace">t</font> &quot;has&quot; more than 2 elements. Ho=
w to bind only the first K ordinates of a tuple and discard the rest is a p=
erennial topic of discussion on this mailing list.)</div></div></div></div>=
</blockquote><div><br></div><div>And that magic will fail for at least one =
of tuple&lt;int&amp;&gt;, tuple&lt;int&amp;&amp;&gt; and tuple&lt;int&gt;. =
It can&#39;t provide the right answer for all three. Care to explain how th=
at is the Right Thing?</div><div><br></div><div>BTW, AFAIK the hardcoded be=
gin/end/get lookup rules in the language are impossible to implement exactl=
y in plain C++. The ADL part can be done by SFINAEing on the well-formednes=
s of an unqualified call where the only candidate found by ordinary lookup =
is a nonviable candidate. The tricky part is actually the class member look=
up, which goes for the member interpretation if there&#39;s a member with t=
he right name regardless of its kind, type, or accessibility. I don&#39;t k=
now of a way to check that for final and union types.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0c1c2586-5311-4a2e-bea1-09cdab2d9707%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0c1c2586-5311-4a2e-bea1-09cdab2d9707=
%40isocpp.org</a>.<br />

------=_Part_2661_478278708.1493806585090--

------=_Part_2660_1894173438.1493806585090--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Wed, 3 May 2017 03:47:16 -0700
Raw View
--f403045c18aa4039ba054e9c6171
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, May 3, 2017 at 3:16 AM, T. C. <rs2740@gmail.com> wrote:

> On Wednesday, May 3, 2017 at 1:17:34 AM UTC-4, Arthur O'Dwyer wrote:
>>
>> On Tue, May 2, 2017 at 9:13 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> On Tuesday, May 2, 2017 at 11:16:31 PM UTC-4, Arthur O'Dwyer wrote:
>>>>
>>>>
>>>> FWIW: Structured binding actually searches for a whole mess of names,
>>>> including `tuple_size` and `tuple_element` (both of which it looks up
>>>> *only* in namespace std). So IMO "structured binding" should be an
>>>> item on the ever-growing list of "ill-advised places where a
>>>> customization-point feature was clearly needed but never actually
>>>> designed," and *not* on the list of "nice things to copy the design
>>>> of."
>>>>
>>>
>>> To be honest... how else *could* it work? Oh sure, you might have found
>>> some way to make `tuple_size` be a `constexpr` function or something
>>> (though how you pass a parameter of type `E` to allow ADL without actua=
lly
>>> having to *create* an object of that type would be an interesting
>>> trick). But `tuple_element` has got to resolve to a *type*. And ADL
>>> just doesn't exist for meta-functions.
>>>
>>
>> In the case of structured binding, the Right Thing would have been to no=
t
>> rely on tuple_element at all. They could easily have made
>>
>>     auto [x,y] =3D t;
>>
>> equivalent to
>>
>>     auto __t =3D t;
>>     auto&& x =3D get<0>(__t);  // with compiler magic to make decltype(x=
)
>> appear as a non-reference type, of course
>>     auto&& y =3D get<1>(__t);
>>
>> without any reference to tuple_element.  (And notice that the rewrite
>> doesn't explicitly use tuple_size, either. tuple_size is needed only to
>> generate annoying compiler diagnostics in the case that t "has" more
>> than 2 elements. How to bind only the first K ordinates of a tuple and
>> discard the rest is a perennial topic of discussion on this mailing list=
..)
>>
>
> And that magic will fail for at least one of tuple<int&>, tuple<int&&> an=
d
> tuple<int>. It can't provide the right answer for all three. Care to
> explain how that is the Right Thing?
>

Hm. Today I have learned that "auto& [x,y] =3D t;" doesn't do what I though=
t
it did.
The "natural" thing for it to have done would have been to turn both x and =
y
into auto& (lvalue reference) types:

    auto& __t =3D t;
    auto& x =3D get<0>(__t);  // no compiler magic necessary
    auto& y =3D get<1>(__t);

But it turns out that it really does something ultra bizarre =E2=80=94 name=
ly, it
applies the compiler magic to *remove the referenceness of decltype(x)*
even though x does literally have reference semantics.

    std::tuple<int> t1(1);
    auto& [r1] =3D t1;
    static_assert(std::is_same_v<decltype(r1), int>);  // r1 is not a
reference...
    static_assert(!std::is_reference_v<decltype(r1)>);  // 100% not a
reference...
    r1 =3D 2;
    assert(t1 =3D=3D std::tuple(2));  // ...yet it has reference semantics!

https://wandbox.org/permlink/W09BZU7VGJZpUSbH

If it had done the thing I had thought it would do (preserve the
reference-ness of the declaration), then there wouldn't have been any
problem.


Re-reading your objection, I think you might have been talking about
something else anyway. I see how the current state of auto [x] versus auto&
[x] versus auto&& [x] is a bit screwy; but I don't see the problem you're
seeing with std::tuple<int> versus std::tuple<int&> versus
std::tuple<int&&>. In those three cases, std::get<0>(__t) will return a
value with the appropriate degree of (rvalue-)referenceness, and there
won't be any problem as far as I'm aware.

=E2=80=93Arthur

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0KQJmOzgAVLRUqf%2BFWqBsUZReFRhOznp8mkmQUR4=
-CSrg%40mail.gmail.com.

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

<div dir=3D"ltr">On Wed, May 3, 2017 at 3:16 AM, T. C. <span dir=3D"ltr">&l=
t;<a href=3D"mailto:rs2740@gmail.com" target=3D"_blank">rs2740@gmail.com</a=
>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quote=
"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid=
;padding-left:1ex"><div dir=3D"ltr">On Wednesday, May 3, 2017 at 1:17:34 AM=
 UTC-4, Arthur O&#39;Dwyer wrote:<span class=3D"gmail-"><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo=
rder-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">=
<div dir=3D"ltr">On Tue, May 2, 2017 at 9:13 PM, Nicol Bolas <span dir=3D"l=
tr">&lt;<a rel=3D"nofollow">jmck...@gmail.com</a>&gt;</span> wrote:<br><div=
><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,20=
4);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, M=
ay 2, 2017 at 11:16:31 PM UTC-4, Arthur O&#39;Dwyer wrote:<span><blockquote=
 class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:=
1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left=
:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br></div><div>=
FWIW: Structured binding actually searches for a whole mess of names, inclu=
ding `tuple_size` and `tuple_element` (both of which it looks up <i><b>only=
</b></i> in namespace std). So IMO &quot;structured binding&quot; should be=
 an item on the ever-growing list of &quot;ill-advised places where a custo=
mization-point feature was clearly needed but never actually designed,&quot=
; and <b><i>not</i></b> on the list of &quot;nice things to copy the design=
 of.&quot;</div></div></div></div></blockquote></span><div><br>To be honest=
.... how else <i>could</i> it work? Oh sure, you might have found some way t=
o make `tuple_size` be a `constexpr` function or something (though how you =
pass a parameter of type `E` to allow ADL without actually having to <i>cre=
ate</i> an object of that type would be an interesting trick). But `tuple_e=
lement` has got to resolve to a <i>type</i>. And ADL just doesn&#39;t exist=
 for meta-functions.<br></div></div></blockquote><div><br></div><div>In the=
 case of structured binding, the Right Thing would have been to not rely on=
 <font face=3D"monospace, monospace">tuple_element</font> at all. They coul=
d easily have made</div><div><br></div><div><font face=3D"monospace, monosp=
ace">=C2=A0 =C2=A0 auto [x,y] =3D t;</font></div><div><br></div><div>equiva=
lent to</div><div><br></div><div><font face=3D"monospace, monospace">=C2=A0=
 =C2=A0 auto __t =3D t;</font></div><div><font face=3D"monospace, monospace=
">=C2=A0 =C2=A0 auto&amp;&amp; x =3D get&lt;0&gt;(__t); =C2=A0// with compi=
ler magic to make decltype(x) appear as a non-reference type, of course</fo=
nt></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto&amp;&a=
mp; y =3D get&lt;1&gt;(__t);</font></div><div><br></div><div>without any re=
ference to <font face=3D"monospace, monospace">tuple_element</font>. =C2=A0=
(And notice that the rewrite doesn&#39;t explicitly use <font face=3D"monos=
pace, monospace">tuple_size</font>, either. <font face=3D"monospace, monosp=
ace">tuple_size</font> is needed only to generate annoying compiler diagnos=
tics in the case that <font face=3D"monospace, monospace">t</font> &quot;ha=
s&quot; more than 2 elements. How to bind only the first K ordinates of a t=
uple and discard the rest is a perennial topic of discussion on this mailin=
g list.)</div></div></div></div></blockquote><div><br></div></span><div>And=
 that magic will fail for at least one of tuple&lt;int&amp;&gt;, tuple&lt;i=
nt&amp;&amp;&gt; and tuple&lt;int&gt;. It can&#39;t provide the right answe=
r for all three. Care to explain how that is the Right Thing?</div></div></=
blockquote><div><br></div><div>Hm. Today I have learned that &quot;<font fa=
ce=3D"monospace, monospace">auto&amp; [x,y] =3D t;</font>&quot; doesn&#39;t=
 do what I thought it did.</div><div>The &quot;natural&quot; thing for it t=
o have done would have been to turn both=C2=A0<font face=3D"monospace, mono=
space">x</font> and <font face=3D"monospace, monospace">y</font> into <font=
 face=3D"monospace, monospace">auto&amp;</font> (lvalue reference) types:</=
div><div><br></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 a=
uto&amp; __t =3D t;</font></div><div><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 auto&amp; x =3D get&lt;0&gt;(__t); =C2=A0// no compiler magic=
 necessary</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=
=A0 auto&amp; y =3D get&lt;1&gt;(__t);</font></div><div><br></div><div>But =
it turns out that it really does something ultra bizarre =E2=80=94 namely, =
it applies the compiler magic to <i>remove the referenceness of <font face=
=3D"monospace, monospace">decltype(x)</font></i> even though <font face=3D"=
monospace, monospace">x</font> does literally have reference semantics.</di=
v><div><br></div><div><div><font face=3D"monospace, monospace">=C2=A0 =C2=
=A0 std::tuple&lt;int&gt; t1(1);</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 =C2=A0 auto&amp; [r1] =3D t1;<br></font></div><div><font =
face=3D"monospace, monospace">=C2=A0 =C2=A0 static_assert(std::is_same_v&lt=
;decltype(r1), int&gt;); =C2=A0// r1 is not a reference...<br></font></div>=
<div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 static_assert(!std::=
is_reference_v&lt;decltype(r1)&gt;); =C2=A0// 100% not a reference...</font=
></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 r1 =3D 2;</fo=
nt></div></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 asser=
t(t1 =3D=3D std::tuple(2)); =C2=A0// ...yet it has reference semantics!</fo=
nt></div><div><div><br></div></div><div><a href=3D"https://wandbox.org/perm=
link/W09BZU7VGJZpUSbH">https://wandbox.org/permlink/W09BZU7VGJZpUSbH</a><br=
></div><div><br></div><div>If it had done the thing I had thought it would =
do (preserve the reference-ness of the declaration), then there wouldn&#39;=
t have been any problem.</div><div><br></div><div><br></div><div>Re-reading=
 your objection, I think you might have been talking about something else a=
nyway. I see how the current state of auto [x] versus auto&amp; [x] versus =
auto&amp;&amp; [x] is a bit screwy; but I don&#39;t see the problem you&#39=
;re seeing with std::tuple&lt;int&gt; versus std::tuple&lt;int&amp;&gt; ver=
sus std::tuple&lt;int&amp;&amp;&gt;. In those three cases, std::get&lt;0&gt=
;(__t) will return a value with the appropriate degree of (rvalue-)referenc=
eness, and there won&#39;t be any problem as far as I&#39;m aware.</div><di=
v><br></div><div>=E2=80=93Arthur</div></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0KQJmOzgAVLRUqf%2BFWqBsUZReFRhO=
znp8mkmQUR4-CSrg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0KQJmOzgA=
VLRUqf%2BFWqBsUZReFRhOznp8mkmQUR4-CSrg%40mail.gmail.com</a>.<br />

--f403045c18aa4039ba054e9c6171--

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Wed, 3 May 2017 06:12:36 -0700 (PDT)
Raw View
------=_Part_1245_1937784796.1493817156370
Content-Type: multipart/alternative;
 boundary="----=_Part_1246_2031290327.1493817156370"

------=_Part_1246_2031290327.1493817156370
Content-Type: text/plain; charset=UTF-8


>
> That's a fair analogy; but I still can't picture what kind of core
> language feature would help here.  With lambdas it was pretty obvious what
> the core feature was; the only bikeshedding was over the spelling of [].
> With customization points, it's not real clear *what* we're trying to
> spell in the first place.  A new call syntax?  A new way of doing name
> lookup?  A new way of defining functions?
>
>
Reaching back into the archives, the original range-based for loop proposal
used concepts as customization points:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2778.htm, which
would invoke std::Range<_RangeT>::begin(__range) and
std::Range<_RangeT>::end(__range).

Or we could just have lifting lambdas and deal with it that way. Whatever
> happened to P0119, anyway?


See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0382r0.html

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/13f995f2-f92c-4a73-a8d5-b7dea6395d20%40isocpp.org.

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

<div dir=3D"ltr"><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 class=3D"gmail_quote"><div>That&#39;s a fair analogy; but I still =
can&#39;t picture what kind of core language feature would help here.=C2=A0=
 With lambdas it was pretty obvious what the core feature was; the only bik=
eshedding was over the spelling of <font face=3D"monospace, monospace">[]</=
font>. With customization points, it&#39;s not real clear <i>what</i> we&#3=
9;re trying to spell in the first place.=C2=A0 A new call syntax?=C2=A0 A n=
ew way of doing name lookup?=C2=A0 A new way of defining functions?<br></di=
v><div><br></div></div></div></blockquote><div><br></div><div>Reaching back=
 into the archives, the original range-based for loop proposal used concept=
s as customization points: http://www.open-std.org/jtc1/sc22/wg21/docs/pape=
rs/2008/n2778.htm, which would invoke=C2=A0<span style=3D"color: rgb(0, 0, =
0);"><font face=3D"courier new, monospace">std::Range&lt;_RangeT&gt;::begin=
(__range)</font> and=C2=A0</span><span style=3D"color: rgb(0, 0, 0);"><font=
 face=3D"courier new, monospace">std::Range&lt;_RangeT&gt;::end(__range)</f=
ont>.=C2=A0</span></div><div><span style=3D"color: rgb(0, 0, 0);"><br></spa=
n></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;">Or we cou=
ld just have lifting lambdas and deal with it that way. Whatever happened t=
o P0119, anyway?</blockquote><div><br></div><div>See: http://www.open-std.o=
rg/jtc1/sc22/wg21/docs/papers/2016/p0382r0.html</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/13f995f2-f92c-4a73-a8d5-b7dea6395d20%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/13f995f2-f92c-4a73-a8d5-b7dea6395d20=
%40isocpp.org</a>.<br />

------=_Part_1246_2031290327.1493817156370--

------=_Part_1245_1937784796.1493817156370--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 03 May 2017 06:43:35 -0700
Raw View
Em quarta-feira, 3 de maio de 2017, =C3=A0s 03:47:16 PDT, Arthur O'Dwyer es=
creveu:
> But it turns out that it really does something ultra bizarre =E2=80=94 na=
mely, it
> applies the compiler magic to *remove the referenceness of decltype(x)*
> even though x does literally have reference semantics.
>=20
>     std::tuple<int> t1(1);
>     auto& [r1] =3D t1;
>     static_assert(std::is_same_v<decltype(r1), int>);  // r1 is not a
> reference...
>     static_assert(!std::is_reference_v<decltype(r1)>);  // 100% not a
> reference...
>     r1 =3D 2;
>     assert(t1 =3D=3D std::tuple(2));  // ...yet it has reference semantic=
s!

It is quite surprising, but you have to understand what a structured bindin=
g=20
is.

 auto& [r1] =3D t1;

Does not create variable called t1 that references t1's first element.=20

Instead, it creates an unnamed variable that is a reference to t1. That=20
variable is a structure and it has r1 as its first element.

This is the only way you could do:

 struct S {
  int v : 31;
  int s : 1;
 } s;
 auto &[value, sign] =3D s;

This compiles.
--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1763858.k1t25K7h46%40tjmaciei-mobl1.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 3 May 2017 08:38:53 -0700 (PDT)
Raw View
------=_Part_10113_1361056190.1493825933483
Content-Type: multipart/alternative;
 boundary="----=_Part_10114_2145346102.1493825933483"

------=_Part_10114_2145346102.1493825933483
Content-Type: text/plain; charset=UTF-8

On Wednesday, May 3, 2017 at 9:12:36 AM UTC-4, Barry Revzin wrote:
>
> That's a fair analogy; but I still can't picture what kind of core
>> language feature would help here.  With lambdas it was pretty obvious what
>> the core feature was; the only bikeshedding was over the spelling of [].
>> With customization points, it's not real clear *what* we're trying to
>> spell in the first place.  A new call syntax?  A new way of doing name
>> lookup?  A new way of defining functions?
>>
>>
> Reaching back into the archives, the original range-based for loop
> proposal used concepts as customization points:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2778.htm, which
> would invoke std::Range<_RangeT>::begin(__range) and
> std::Range<_RangeT>::end(__range).
>
> Or we could just have lifting lambdas and deal with it that way. Whatever
>> happened to P0119, anyway?
>
>
> See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0382r0.html
>

I guess I was referring to the wrong proposal. The one I was thinking of
made `[]funcname` generate a lambda, rather than the implicit nonsense
P0119 was trying to do.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f6c5ccf7-3dca-45ac-b19c-e1d016238d6f%40isocpp.org.

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

<div dir=3D"ltr">On Wednesday, May 3, 2017 at 9:12:36 AM UTC-4, Barry Revzi=
n 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"><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 class=3D"gmail_quo=
te"><div>That&#39;s a fair analogy; but I still can&#39;t picture what kind=
 of core language feature would help here.=C2=A0 With lambdas it was pretty=
 obvious what the core feature was; the only bikeshedding was over the spel=
ling of <font face=3D"monospace, monospace">[]</font>. With customization p=
oints, it&#39;s not real clear <i>what</i> we&#39;re trying to spell in the=
 first place.=C2=A0 A new call syntax?=C2=A0 A new way of doing name lookup=
?=C2=A0 A new way of defining functions?<br></div><div><br></div></div></di=
v></blockquote><div><br></div><div>Reaching back into the archives, the ori=
ginal range-based for loop proposal used concepts as customization points: =
<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2778.ht=
m" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http:=
//www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg2=
1%2Fdocs%2Fpapers%2F2008%2Fn2778.htm\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQj=
CNHJaZ1pEw0FjDqyN5-WwiWaLD3pxg&#39;;return true;" onclick=3D"this.href=3D&#=
39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc=
22%2Fwg21%2Fdocs%2Fpapers%2F2008%2Fn2778.htm\x26sa\x3dD\x26sntz\x3d1\x26usg=
\x3dAFQjCNHJaZ1pEw0FjDqyN5-WwiWaLD3pxg&#39;;return true;">http://www.open-s=
td.org/jtc1/<wbr>sc22/wg21/docs/papers/2008/<wbr>n2778.htm</a>, which would=
 invoke=C2=A0<span style=3D"color:rgb(0,0,0)"><font face=3D"courier new, mo=
nospace">std::Range&lt;_RangeT&gt;::<wbr>begin(__range)</font> and=C2=A0</s=
pan><span style=3D"color:rgb(0,0,0)"><font face=3D"courier new, monospace">=
std::Range&lt;_RangeT&gt;::end(_<wbr>_range)</font>.=C2=A0</span></div><div=
><span style=3D"color:rgb(0,0,0)"><br></span></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,2=
04,204);padding-left:1ex">Or we could just have lifting lambdas and deal wi=
th it that way. Whatever happened to P0119, anyway?</blockquote><div><br></=
div><div>See: <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers=
/2016/p0382r0.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.=
href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2F=
jtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0382r0.html\x26sa\x3dD\x26sntz=
\x3d1\x26usg\x3dAFQjCNGeG7Tiko06g4FWV1UD6poAk9lcTA&#39;;return true;" oncli=
ck=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open=
-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0382r0.html\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGeG7Tiko06g4FWV1UD6poAk9lcTA&#39;;return t=
rue;">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2016/<wbr>p03=
82r0.html</a></div></div></blockquote><div><br>I guess I was referring to t=
he wrong proposal. The one I was thinking of made `[]funcname` generate a l=
ambda, rather than the implicit nonsense P0119 was trying to do.<br></div><=
/div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f6c5ccf7-3dca-45ac-b19c-e1d016238d6f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f6c5ccf7-3dca-45ac-b19c-e1d016238d6f=
%40isocpp.org</a>.<br />

------=_Part_10114_2145346102.1493825933483--

------=_Part_10113_1361056190.1493825933483--

.


Author: "T. C." <rs2740@gmail.com>
Date: Wed, 3 May 2017 08:48:41 -0700 (PDT)
Raw View
------=_Part_2966_519526161.1493826521649
Content-Type: multipart/alternative;
 boundary="----=_Part_2967_477001431.1493826521649"

------=_Part_2967_477001431.1493826521649
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Wednesday, May 3, 2017 at 6:47:19 AM UTC-4, Arthur O'Dwyer wrote:
>
> On Wed, May 3, 2017 at 3:16 AM, T. C. <rs2...@gmail.com <javascript:>>=20
> wrote:
>
>> On Wednesday, May 3, 2017 at 1:17:34 AM UTC-4, Arthur O'Dwyer wrote:
>>>
>>> On Tue, May 2, 2017 at 9:13 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>>>
>>>> On Tuesday, May 2, 2017 at 11:16:31 PM UTC-4, Arthur O'Dwyer wrote:
>>>>>
>>>>>
>>>>> FWIW: Structured binding actually searches for a whole mess of names,=
=20
>>>>> including `tuple_size` and `tuple_element` (both of which it looks up=
=20
>>>>> *only* in namespace std). So IMO "structured binding" should be an=20
>>>>> item on the ever-growing list of "ill-advised places where a=20
>>>>> customization-point feature was clearly needed but never actually=20
>>>>> designed," and *not* on the list of "nice things to copy the design=
=20
>>>>> of."
>>>>>
>>>>
>>>> To be honest... how else *could* it work? Oh sure, you might have=20
>>>> found some way to make `tuple_size` be a `constexpr` function or somet=
hing=20
>>>> (though how you pass a parameter of type `E` to allow ADL without actu=
ally=20
>>>> having to *create* an object of that type would be an interesting=20
>>>> trick). But `tuple_element` has got to resolve to a *type*. And ADL=20
>>>> just doesn't exist for meta-functions.
>>>>
>>>
>>> In the case of structured binding, the Right Thing would have been to=
=20
>>> not rely on tuple_element at all. They could easily have made
>>>
>>>     auto [x,y] =3D t;
>>>
>>> equivalent to
>>>
>>>     auto __t =3D t;
>>>     auto&& x =3D get<0>(__t);  // with compiler magic to make decltype(=
x)=20
>>> appear as a non-reference type, of course
>>>     auto&& y =3D get<1>(__t);
>>>
>>> without any reference to tuple_element.  (And notice that the rewrite=
=20
>>> doesn't explicitly use tuple_size, either. tuple_size is needed only to=
=20
>>> generate annoying compiler diagnostics in the case that t "has" more=20
>>> than 2 elements. How to bind only the first K ordinates of a tuple and=
=20
>>> discard the rest is a perennial topic of discussion on this mailing lis=
t.)
>>>
>>
>> And that magic will fail for at least one of tuple<int&>, tuple<int&&>=
=20
>> and tuple<int>. It can't provide the right answer for all three. Care to=
=20
>> explain how that is the Right Thing?
>>
>
> Hm. Today I have learned that "auto& [x,y] =3D t;" doesn't do what I=20
> thought it did.
> The "natural" thing for it to have done would have been to turn both x=20
> and y into auto& (lvalue reference) types:
>
>     auto& __t =3D t;
>     auto& x =3D get<0>(__t);  // no compiler magic necessary
>     auto& y =3D get<1>(__t);
>
> But it turns out that it really does something ultra bizarre =E2=80=94 na=
mely, it=20
> applies the compiler magic to *remove the referenceness of decltype(x)*=
=20
> even though x does literally have reference semantics.
>
>     std::tuple<int> t1(1);
>     auto& [r1] =3D t1;
>     static_assert(std::is_same_v<decltype(r1), int>);  // r1 is not a=20
> reference...
>     static_assert(!std::is_reference_v<decltype(r1)>);  // 100% not a=20
> reference...
>     r1 =3D 2;
>     assert(t1 =3D=3D std::tuple(2));  // ...yet it has reference semantic=
s!
>
> https://wandbox.org/permlink/W09BZU7VGJZpUSbH
>
> If it had done the thing I had thought it would do (preserve the=20
> reference-ness of the declaration), then there wouldn't have been any=20
> problem.
>
>
> Re-reading your objection, I think you might have been talking about=20
> something else anyway. I see how the current state of auto [x] versus aut=
o&=20
> [x] versus auto&& [x] is a bit screwy; but I don't see the problem you're=
=20
> seeing with std::tuple<int> versus std::tuple<int&> versus=20
> std::tuple<int&&>. In those three cases, std::get<0>(__t) will return a=
=20
> value with the appropriate degree of (rvalue-)referenceness, and there=20
> won't be any problem as far as I'm aware.
>
> =E2=80=93Arthur
>
>
You have auto&& x =3D get<0>(AS_RVALUE(__t)); x is either int& or int&&,=20
depending on __t's type. What kind of "magic" will let decltype(x) get to=
=20
int, int&, and int&&?

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/9dd480f8-18bf-4a16-a3ea-892c53607273%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Wednesday, May 3, 2017 at 6:47:19 AM UTC-4, Art=
hur O&#39;Dwyer 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">On Wed, May 3, 2017 at 3:16 AM, T. C. <span dir=3D"ltr">&lt;<a hre=
f=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"26C2qOYkBAAJ" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tr=
ue;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">rs2...@gmai=
l.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:=
1ex"><div dir=3D"ltr">On Wednesday, May 3, 2017 at 1:17:34 AM UTC-4, Arthur=
 O&#39;Dwyer wrote:<span><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);=
border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">On Tue, May 2, 2=
017 at 9:13 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a rel=3D"nofollow">jmck.=
...@gmail.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-=
width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;paddin=
g-left:1ex"><div dir=3D"ltr">On Tuesday, May 2, 2017 at 11:16:31 PM UTC-4, =
Arthur O&#39;Dwyer wrote:<span><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204=
,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div><div =
class=3D"gmail_quote"><div><br></div><div>FWIW: Structured binding actually=
 searches for a whole mess of names, including `tuple_size` and `tuple_elem=
ent` (both of which it looks up <i><b>only</b></i> in namespace std). So IM=
O &quot;structured binding&quot; should be an item on the ever-growing list=
 of &quot;ill-advised places where a customization-point feature was clearl=
y needed but never actually designed,&quot; and <b><i>not</i></b> on the li=
st of &quot;nice things to copy the design of.&quot;</div></div></div></div=
></blockquote></span><div><br>To be honest... how else <i>could</i> it work=
? Oh sure, you might have found some way to make `tuple_size` be a `constex=
pr` function or something (though how you pass a parameter of type `E` to a=
llow ADL without actually having to <i>create</i> an object of that type wo=
uld be an interesting trick). But `tuple_element` has got to resolve to a <=
i>type</i>. And ADL just doesn&#39;t exist for meta-functions.<br></div></d=
iv></blockquote><div><br></div><div>In the case of structured binding, the =
Right Thing would have been to not rely on <font face=3D"monospace, monospa=
ce">tuple_element</font> at all. They could easily have made</div><div><br>=
</div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto [x,y] =3D=
 t;</font></div><div><br></div><div>equivalent to</div><div><br></div><div>=
<font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto __t =3D t;</font></d=
iv><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto&amp;&amp; x =
=3D get&lt;0&gt;(__t); =C2=A0// with compiler magic to make decltype(x) app=
ear as a non-reference type, of course</font></div><div><font face=3D"monos=
pace, monospace">=C2=A0 =C2=A0 auto&amp;&amp; y =3D get&lt;1&gt;(__t);</fon=
t></div><div><br></div><div>without any reference to <font face=3D"monospac=
e, monospace">tuple_element</font>. =C2=A0(And notice that the rewrite does=
n&#39;t explicitly use <font face=3D"monospace, monospace">tuple_size</font=
>, either. <font face=3D"monospace, monospace">tuple_size</font> is needed =
only to generate annoying compiler diagnostics in the case that <font face=
=3D"monospace, monospace">t</font> &quot;has&quot; more than 2 elements. Ho=
w to bind only the first K ordinates of a tuple and discard the rest is a p=
erennial topic of discussion on this mailing list.)</div></div></div></div>=
</blockquote><div><br></div></span><div>And that magic will fail for at lea=
st one of tuple&lt;int&amp;&gt;, tuple&lt;int&amp;&amp;&gt; and tuple&lt;in=
t&gt;. It can&#39;t provide the right answer for all three. Care to explain=
 how that is the Right Thing?</div></div></blockquote><div><br></div><div>H=
m. Today I have learned that &quot;<font face=3D"monospace, monospace">auto=
&amp; [x,y] =3D t;</font>&quot; doesn&#39;t do what I thought it did.</div>=
<div>The &quot;natural&quot; thing for it to have done would have been to t=
urn both=C2=A0<font face=3D"monospace, monospace">x</font> and <font face=
=3D"monospace, monospace">y</font> into <font face=3D"monospace, monospace"=
>auto&amp;</font> (lvalue reference) types:</div><div><br></div><div><font =
face=3D"monospace, monospace">=C2=A0 =C2=A0 auto&amp; __t =3D t;</font></di=
v><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto&amp; x =3D ge=
t&lt;0&gt;(__t); =C2=A0// no compiler magic necessary</font></div><div><fon=
t face=3D"monospace, monospace">=C2=A0 =C2=A0 auto&amp; y =3D get&lt;1&gt;(=
__t);</font></div><div><br></div><div>But it turns out that it really does =
something ultra bizarre =E2=80=94 namely, it applies the compiler magic to =
<i>remove the referenceness of <font face=3D"monospace, monospace">decltype=
(x)</font></i> even though <font face=3D"monospace, monospace">x</font> doe=
s literally have reference semantics.</div><div><br></div><div><div><font f=
ace=3D"monospace, monospace">=C2=A0 =C2=A0 std::tuple&lt;int&gt; t1(1);</fo=
nt></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 auto&amp; [=
r1] =3D t1;<br></font></div><div><font face=3D"monospace, monospace">=C2=A0=
 =C2=A0 static_assert(std::is_same_v&lt;<wbr>decltype(r1), int&gt;); =C2=A0=
// r1 is not a reference...<br></font></div><div><font face=3D"monospace, m=
onospace">=C2=A0 =C2=A0 static_assert(!std::is_<wbr>reference_v&lt;decltype=
(r1)&gt;); =C2=A0// 100% not a reference...</font></div><div><font face=3D"=
monospace, monospace">=C2=A0 =C2=A0 r1 =3D 2;</font></div></div><div><font =
face=3D"monospace, monospace">=C2=A0 =C2=A0 assert(t1 =3D=3D std::tuple(2))=
; =C2=A0// ...yet it has reference semantics!</font></div><div><div><br></d=
iv></div><div><a href=3D"https://wandbox.org/permlink/W09BZU7VGJZpUSbH" tar=
get=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www=
..google.com/url?q\x3dhttps%3A%2F%2Fwandbox.org%2Fpermlink%2FW09BZU7VGJZpUSb=
H\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHmSbAfKYETx0ff2DqRGYI88DxnQQ&#39;=
;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3d=
https%3A%2F%2Fwandbox.org%2Fpermlink%2FW09BZU7VGJZpUSbH\x26sa\x3dD\x26sntz\=
x3d1\x26usg\x3dAFQjCNHmSbAfKYETx0ff2DqRGYI88DxnQQ&#39;;return true;">https:=
//wandbox.org/permlink/<wbr>W09BZU7VGJZpUSbH</a><br></div><div><br></div><d=
iv>If it had done the thing I had thought it would do (preserve the referen=
ce-ness of the declaration), then there wouldn&#39;t have been any problem.=
</div><div><br></div><div><br></div><div>Re-reading your objection, I think=
 you might have been talking about something else anyway. I see how the cur=
rent state of auto [x] versus auto&amp; [x] versus auto&amp;&amp; [x] is a =
bit screwy; but I don&#39;t see the problem you&#39;re seeing with std::tup=
le&lt;int&gt; versus std::tuple&lt;int&amp;&gt; versus std::tuple&lt;int&am=
p;&amp;&gt;. In those three cases, std::get&lt;0&gt;(__t) will return a val=
ue with the appropriate degree of (rvalue-)referenceness, and there won&#39=
;t be any problem as far as I&#39;m aware.</div><div><br></div><div>=E2=80=
=93Arthur</div></div><br></div></div></blockquote><div><br></div><div>You h=
ave auto&amp;&amp; x =3D get&lt;0&gt;(AS_RVALUE(__t)); x is either int&amp;=
 or int&amp;&amp;, depending on __t&#39;s type. What kind of &quot;magic&qu=
ot; will let decltype(x) get to int, int&amp;, and int&amp;&amp;?</div></di=
v>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9dd480f8-18bf-4a16-a3ea-892c53607273%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9dd480f8-18bf-4a16-a3ea-892c53607273=
%40isocpp.org</a>.<br />

------=_Part_2967_477001431.1493826521649--

------=_Part_2966_519526161.1493826521649--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 4 May 2017 02:54:14 +0200
Raw View
This is a multi-part message in MIME format.
--------------0322D65C87AD79B2B0125222
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 03/05/2017 =C3=A0 15:12, Barry Revzin a =C3=A9crit :
>
>     That's a fair analogy; but I still can't picture what kind of core
>     language feature would help here.  With lambdas it was pretty
>     obvious what the core feature was; the only bikeshedding was over
>     the spelling of []. With customization points, it's not real clear
>     /what/ we're trying to spell in the first place.  A new call
>     syntax?  A new way of doing name lookup?  A new way of defining
>     functions?
>
>
> Reaching back into the archives, the original range-based for loop=20
> proposal used concepts as customization points:=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2778.htm,=20
> which would invoke std::Range<_RangeT>::begin(__range) and=20
> std::Range<_RangeT>::end(__range).
>
Thanks for adding this old link. The calling interface should be even=20
more simple  std2::range::begin(aRange) and std2::range::end(aRange) but=20
not simpler: std2::begin(aRange) and std2::end(aRange).

IMO, the std2 customization mechanism as proposed for the Range TS=20
doesn't scale for the C++ standard library and the approach cannot be=20
used by the users to define his own customization points. The last could=20
be seen as not a problem for the standard C++, but people must solve=20
concrete problems and they copy the C++ library design as it should be=20
the correct one, but they cannot in this case.  See for example the=20
customization mechanism of Boost.Hana and many other generic libraries.=20
If they use ADL as customization point, they can not support C++=20
standard library types.

We will see more a more concepts very soon. In the same way we associate=20
a member function to a class, we should associate a customization point=20
to a concept and name it. There shouldn't be a confusion of which=20
customization point belongs to what concept. It is not the same=20
product_type::get than sum_type::get, container::size than memory::size.=20
begin/end is not something limited to ranges.  When I say name it I mean=20
that the user must name the concept and the function name when she want=20
to call it and that the customization is done explicitly using this=20
concept name as well. This is not the design used in on the C++ standard=20
up to C++17 and will not change for C++20 with the current direction.

We would need more a more customization points if we continue to do=20
generic programming and not only on the C++ standard library. Having all=20
these customization points in a flat namespace don't scale, the=20
customization points become pseudo keywords. We need to scope them. We=20
have namespaces to manage with scope, and the standard library is not=20
using them (the exceptions of chrono and filesystem are domain=20
namespaces which of course is a very good use of namespaces). I expected=20
to have a std2::ranges namespace in the future STD2 to signal that=20
anything there was talking about customization points of the the Range=20
concept and the algorithms that work with this concept. Instead, IIUC we=20
will have again a flat std2 namespace without structure. I know that=20
this will make the names longer, but we have other C++ features that=20
help us, as namespace aliases. Language that don't have namespaces rely=20
on prefixes to ensure a unique meaning for a customization point.  C++=20
is more powerful and we should use this power for the standard library.

I don't see the advantage of having implicit mappings that are based on=20
syntactical vraisemblance. Why a class defining begin() and end()=20
function members should become a Range if the functions don't support=20
the Range semantics. While sometimes it is possible to ensure almost all=20
the semantic concerns others it isn't so easy. At the end a syntactical=20
mapping has more liabilities than advantages as most of the short term=20
solutions.

I know that we want backward compatibility and any alternative=20
customization approach needs to address it. This doesn't mean that we=20
should base our future customization strategy on an approach ADL that=20
has a lot of problems, see [N1691].

I agree that we need a language feature to define customization points=20
and a way to customize them. Other languages have already do that with=20
success. C++ is a complex language and we don't want to add anything=20
that make it even more complex. I believe however that we really need to=20
solve this problem at the languages level. IMHO, C++0x addressed in part=20
this problematic but the C++ standard abandoned this direction and=20
people as Bjarne Stroustrup and many others don't want to consider any=20
proposal that has an explicit concept/customization points mapping. This=20
means that people are trying to solve the problem at the library level.=20
I believe that the proposed std2 customization mechanism has his merits=20
on the continuation of this direction. The approach solves already some=20
important problems, but the solution doesn't takes in account the=20
problems addressed in [N1691] and is more complex that the lambda user=20
is able to design. As Bjarne Stroustrup says, "Make simple thing simpler".

Sorry, but I don't have a language proposal. In the mean time I use an=20
alternative customization point mechanism (close to the one of=20
Boost.Hana) that is explicit in the calling side and explicit in the=20
customization side, but the customization solution is a little bit=20
cumbersome. I use it on some of my proposal as Nullable, Factories,=20
Product Type. I'm using the same approach also for other on going=20
proposal I'm working on, as e.g. for Sum Types, Ordinal types, Functors=20
or Monads. These proposals don't propose function object to represent=20
the user interface but this could be considered. IMHO, providing=20
function objects is orthogonal to the customization point approach and=20
the fact that the current STD2 approach requires the use of function=20
objects shouldn't be considered as a goal. As others have noted we have=20
some proposals on overloads sets that would make it very easy to provide=20
a function object associated to an overload set.

The current customization points could be adapted to this explicit=20
approach while preserving backward compatibility, as e.g. for Swappable,=20
Hashable and Range. I don't see these proposals as a final solution and=20
I hope these proposals could inspire some language solution(s) (some=20
kind of explicit namespace, partial template class specialization from=20
unrelated namespaces, traits, ...) or at least a better library solution.

Vicente

[N1691] Explicit Namespaces
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1691.html


--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3f13697d-a5d6-d802-68b6-291c79f0b041%40wanadoo.f=
r.

--------------0322D65C87AD79B2B0125222
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 03/05/2017 =C3=A0 15:12, Barry Revzin=
 a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:13f995f2-f92c-4a73-a8d5-b7dea6395d20@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <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 class=3D"gmail_quote">
              <div>That's a fair analogy; but I still can't picture what
                kind of core language feature would help here.=C2=A0 With
                lambdas it was pretty obvious what the core feature was;
                the only bikeshedding was over the spelling of <font
                  face=3D"monospace, monospace">[]</font>. With
                customization points, it's not real clear <i>what</i>
                we're trying to spell in the first place.=C2=A0 A new call
                syntax?=C2=A0 A new way of doing name lookup?=C2=A0 A new w=
ay of
                defining functions?<br>
              </div>
              <div><br>
              </div>
            </div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>Reaching back into the archives, the original range-based
          for loop proposal used concepts as customization points:
          <a class=3D"moz-txt-link-freetext" href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2008/n2778.htm">http://www.open-std.org/jtc1/s=
c22/wg21/docs/papers/2008/n2778.htm</a>,
          which would invoke=C2=A0<span style=3D"color: rgb(0, 0, 0);"><fon=
t
              face=3D"courier new, monospace">std::Range&lt;_RangeT&gt;::be=
gin(__range)</font>
            and=C2=A0</span><span style=3D"color: rgb(0, 0, 0);"><font
              face=3D"courier new, monospace">std::Range&lt;_RangeT&gt;::en=
d(__range)</font>.=C2=A0</span></div>
        <div><span style=3D"color: rgb(0, 0, 0);"><br>
          </span></div>
      </div>
    </blockquote>
    Thanks for adding this old link. The calling interface should be
    even more simple=C2=A0 std2::range::begin(aRange) and
    std2::range::end(aRange) but not simpler: std2::begin(aRange) and
    std2::end(aRange).<br>
    <br>
    IMO, the std2 customization mechanism as proposed for the Range TS
    doesn't scale for the C++ standard library and the approach cannot
    be used by the users to define his own customization points. The
    last could be seen as not a problem for the standard C++, but people
    must solve concrete problems and they copy the C++ library design as
    it should be the correct one, but they cannot in this case.=C2=A0 See f=
or
    example the customization mechanism of Boost.Hana and many other
    generic libraries. If they use ADL as customization point, they can
    not support C++ standard library types.<br>
    <br>
    We will see more a more concepts very soon. In the same way we
    associate a member function to a class, we should associate a
    customization point to a concept and name it. There shouldn't be a
    confusion of which customization point belongs to what concept. It
    is not the same product_type::get than sum_type::get,
    container::size than memory::size. begin/end is not something
    limited to ranges.=C2=A0 When I say name it I mean that the user must
    name the concept and the function name when she want to call it and
    that the customization is done explicitly using this concept name as
    well. This is not the design used in on the C++ standard up to C++17
    and will not change for C++20 with the current direction.<br>
    <br>
    We would need more a more customization points if we continue to do
    generic programming and not only on the C++ standard library. Having
    all these customization points in a flat namespace don't scale, the
    customization points become pseudo keywords. We need to scope them.
    We have namespaces to manage with scope, and the standard library is
    not using them (the exceptions of chrono and filesystem are domain
    namespaces which of course is a very good use of namespaces). I
    expected to have a std2::ranges namespace in the future STD2 to
    signal that anything there was talking about customization points of
    the the Range concept and the algorithms that work with this
    concept. Instead, IIUC we will have again a flat std2 namespace
    without structure. I know that this will make the names longer, but
    we have other C++ features that help us, as namespace aliases.
    Language that don't have namespaces rely on prefixes to ensure a
    unique meaning for a customization point.=C2=A0 C++ is more powerful an=
d
    we should use this power for the standard library.<br>
    <br>
    I don't see the advantage of having implicit mappings that are based
    on syntactical vraisemblance. Why a class defining begin() and end()
    function members should become a Range if the functions don't
    support the Range semantics. While sometimes it is possible to
    ensure almost all the semantic concerns others it isn't so easy. At
    the end a syntactical mapping has more liabilities than advantages
    as most of the short term solutions. <br>
    <br>
    I know that we want backward compatibility and any alternative
    customization approach needs to address it. This doesn't mean that
    we should base our future customization strategy on an approach ADL
    that has a lot of problems, see [N1691].<br>
    <br>
    I agree that we need a language feature to define customization
    points and a way to customize them. Other languages have already do
    that with success. C++ is a complex language and we don't want to
    add anything that make it even more complex. I believe however that
    we really need to solve this problem at the languages level. IMHO,
    C++0x addressed in part this problematic but the C++ standard
    abandoned this direction and people as Bjarne Stroustrup and many
    others don't want to consider any proposal that has an explicit
    concept/customization points mapping. This means that people are
    trying to solve the problem at the library level. I believe that the
    proposed std2 customization mechanism has his merits on the
    continuation of this direction. The approach solves already some
    important problems, but the solution doesn't takes in account the
    problems addressed in [N1691] and is more complex that the lambda
    user is able to design. As Bjarne Stroustrup says, "Make simple
    thing simpler".<br>
    <br>
    Sorry, but I don't have a language proposal. In the mean time I use
    an alternative customization point mechanism (close to the one of
    Boost.Hana) that is explicit in the calling side and explicit in the
    customization side, but the customization solution is a little bit
    cumbersome. I use it on some of my proposal as Nullable, Factories,
    Product Type. I'm using the same approach also for other on going
    proposal I'm working on, as e.g. for Sum Types, Ordinal types,
    Functors or Monads. These proposals don't propose function object to
    represent the user interface but this could be considered. IMHO,
    providing function objects is orthogonal to the customization point
    approach and the fact that the current STD2 approach requires the
    use of function objects shouldn't be considered as a goal. As others
    have noted we have some proposals on overloads sets that would make
    it very easy to provide a function object associated to an overload
    set.<br>
    <br>
    The current customization points could be adapted to this explicit
    approach while preserving backward compatibility, as e.g. for
    Swappable, Hashable and Range. I don't see these proposals as a
    final solution and I hope these proposals could inspire some
    language solution(s) (some kind of explicit namespace, partial
    template class specialization from unrelated namespaces, traits,
    ...) or at least a better library solution.<br>
    <br>
    Vicente<br>
    <br>
    [N1691] Explicit Namespaces <br>
    <a class=3D"moz-txt-link-freetext" href=3D"http://www.open-std.org/jtc1=
/sc22/wg21/docs/papers/2004/n1691.html">http://www.open-std.org/jtc1/sc22/w=
g21/docs/papers/2004/n1691.html</a><br>
    <br>
    <br>
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3f13697d-a5d6-d802-68b6-291c79f0b041%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3f13697d-a5d6-d802-68b6-291c79f0b041=
%40wanadoo.fr</a>.<br />

--------------0322D65C87AD79B2B0125222--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 5 May 2017 10:54:16 -0700 (PDT)
Raw View
------=_Part_856_1102333479.1494006856655
Content-Type: multipart/alternative;
 boundary="----=_Part_857_1400329662.1494006856655"

------=_Part_857_1400329662.1494006856655
Content-Type: text/plain; charset=UTF-8

The swap(), begin(), end(), size(), etc... is an embarrassment.

- Its ugly to adding these using declarations.
- Its crazy error prone. Too easy to forget a using declaration.
- These functions cannot be called in single expression contexts like
decltype().

Why can't we just make std::swap() do all of the magic dispatching
internally? Then the convention is people always call std::swap(),
std::begin(), etc..

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c76cb8b1-df82-48e7-a8dc-26f91f923cb6%40isocpp.org.

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

<div dir=3D"ltr">The swap(), begin(), end(), size(), etc... is an embarrass=
ment.<div><br></div><div>- Its ugly to adding these using declarations.<br>=
</div><div>- Its crazy error prone. Too easy to forget a using declaration.=
</div><div>- These functions cannot be called in single expression contexts=
 like decltype().</div><div><div><br></div><div>Why can&#39;t we just make =
std::swap() do all of the magic dispatching internally? Then the convention=
 is people always call std::swap(), std::begin(), etc..</div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c76cb8b1-df82-48e7-a8dc-26f91f923cb6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c76cb8b1-df82-48e7-a8dc-26f91f923cb6=
%40isocpp.org</a>.<br />

------=_Part_857_1400329662.1494006856655--

------=_Part_856_1102333479.1494006856655--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 5 May 2017 11:03:10 -0700 (PDT)
Raw View
------=_Part_1875_1225346998.1494007390092
Content-Type: multipart/alternative;
 boundary="----=_Part_1876_1353961168.1494007390092"

------=_Part_1876_1353961168.1494007390092
Content-Type: text/plain; charset=UTF-8

On Friday, May 5, 2017 at 1:54:16 PM UTC-4, Matthew Fioravante wrote:
>
> The swap(), begin(), end(), size(), etc... is an embarrassment.
>
> - Its ugly to adding these using declarations.
> - Its crazy error prone. Too easy to forget a using declaration.
> - These functions cannot be called in single expression contexts like
> decltype().
>
> Why can't we just make std::swap() do all of the magic dispatching
> internally? Then the convention is people always call std::swap(),
> std::begin(), etc..
>

Because it would be a backwards-incompatible change. It also wouldn't help
users create similar interfaces that have similar behavior.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a3814105-494c-4d85-bedc-b05f5d165a10%40isocpp.org.

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

<div dir=3D"ltr">On Friday, May 5, 2017 at 1:54:16 PM UTC-4, Matthew Fiorav=
ante 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">Th=
e swap(), begin(), end(), size(), etc... is an embarrassment.<div><br></div=
><div>- Its ugly to adding these using declarations.<br></div><div>- Its cr=
azy error prone. Too easy to forget a using declaration.</div><div>- These =
functions cannot be called in single expression contexts like decltype().</=
div><div><div><br></div><div>Why can&#39;t we just make std::swap() do all =
of the magic dispatching internally? Then the convention is people always c=
all std::swap(), std::begin(), etc..</div></div></div></blockquote><div><br=
>Because it would be a backwards-incompatible change. It also wouldn&#39;t =
help users create similar interfaces that have similar behavior. <br></div>=
</div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a3814105-494c-4d85-bedc-b05f5d165a10%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a3814105-494c-4d85-bedc-b05f5d165a10=
%40isocpp.org</a>.<br />

------=_Part_1876_1353961168.1494007390092--

------=_Part_1875_1225346998.1494007390092--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 5 May 2017 21:28:50 +0300
Raw View
On 5 May 2017 at 21:03, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Friday, May 5, 2017 at 1:54:16 PM UTC-4, Matthew Fioravante wrote:
>>
>> The swap(), begin(), end(), size(), etc... is an embarrassment.
>>
>> - Its ugly to adding these using declarations.
>> - Its crazy error prone. Too easy to forget a using declaration.
>> - These functions cannot be called in single expression contexts like
>> decltype().
>>
>> Why can't we just make std::swap() do all of the magic dispatching
>> internally? Then the convention is people always call std::swap(),
>> std::begin(), etc..
>
>
> Because it would be a backwards-incompatible change. It also wouldn't help
> users create similar interfaces that have similar behavior.


There have been suggestions to add an adl_swap that does all this
"magic dispatching" internally.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUZ5Ku4s%3DayZ8z502AtLqfZrNSaHudE%2BYWeeGy-s5weYow%40mail.gmail.com.

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 5 May 2017 11:29:02 -0700 (PDT)
Raw View
------=_Part_832_263340514.1494008942881
Content-Type: multipart/alternative;
 boundary="----=_Part_833_563837736.1494008942881"

------=_Part_833_563837736.1494008942881
Content-Type: text/plain; charset=UTF-8



On Friday, May 5, 2017 at 1:03:10 PM UTC-5, Nicol Bolas wrote:
>
> Because it would be a backwards-incompatible change.
>

C++ has broken backwards compatibility before. Right now if you call
std::swap() on your object, unless its in std you'll get a default move
based swap operation. Suppose that was all of the sudden silently changed
to actually call your type's swap() operation if it has one. How bad would
that be? How much code would it break?

I consider swap() special in the same vein as move and copy. We've added
rules to change how those are called/elided in the past knowing it could
break code. If you write a swap() its suppose to do swapping, if it does
something else you get what you deserve. "Optimizing" std::swap() to call
your types custom swap if it has one does not sound like a bad thing to me.

The fact that essential library primitives like swap() and begin() require
expert level knowledge to use correctly is a complete and utter failure.*
Really, its just ****ing stupid.* ADL is not the proper tool for this. I'd
argue ADL is only really useful for operator overloading. Unless you put
swap(), begin(), etc.. to the global :: namespace, ADL will never work.
That's a non-starter too as third party libraries wanting to define
"customization points" such as begin() certainly cannot just put stuff in
the global namespace.

With have virtual functions for runtime dispatch, and this broken crap
interface for compile time dispatch. This is a serious bug that needs to be
fixed.


> It also wouldn't help users create similar interfaces that have similar
> behavior.
>

That's a secondary concern. If I want to write foo::fooify() customization
point in libfoo, I can lookup a tutorial to get all of the dispatching
correct. I only need to do this once for all of the thousands if not
millions of times my users will just need to say
foo::fooify(fooable_thing);. If I'm writing my own customization points,
I'm already an expert C++ developer. Furthermore, we could also consider
adding helper utilities for this in the standard library, even if they have
to be macros.


--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a7e2efc2-bbee-40ed-963b-42339bf0e21c%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Friday, May 5, 2017 at 1:03:10 PM UTC-5, Nicol =
Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div>Because it would be a backwards-incompatible change.</div></div></block=
quote><div><br></div><div>C++ has broken backwards compatibility before. Ri=
ght now if you call std::swap() on your object, unless its in std you&#39;l=
l get a default move based swap operation. Suppose that was all of the sudd=
en silently changed to actually call your type&#39;s swap() operation if it=
 has one. How bad would that be? How much code would it break?</div><div><b=
r></div><div>I consider swap() special in the same vein as move and copy. W=
e&#39;ve added rules to change how those are called/elided in the past know=
ing it could break code. If you write a swap() its suppose to do swapping, =
if it does something else you get what you deserve. &quot;Optimizing&quot; =
std::swap() to call your types custom swap if it has one does not sound lik=
e a bad thing to me.</div><div><br></div><div>The fact that essential libra=
ry primitives like swap() and begin() require expert level knowledge to use=
 correctly is a complete and utter failure.<b> Really, its just ****ing stu=
pid.</b> ADL is not the proper tool for this. I&#39;d argue ADL is only rea=
lly useful for operator overloading. Unless you put swap(), begin(), etc.. =
to the global :: namespace, ADL will never work. That&#39;s a non-starter t=
oo as third party libraries wanting to define &quot;customization points&qu=
ot; such as begin() certainly cannot just put stuff in the global namespace=
..</div><div><br></div><div>With have virtual functions for runtime dispatch=
, and this broken crap interface for compile time dispatch. This is a serio=
us bug that needs to be fixed.</div><div>=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>It also wouldn&#39;t help user=
s create similar interfaces that have similar behavior. <br></div></div></b=
lockquote><div><br></div><div>That&#39;s a secondary concern. If I want to =
write foo::fooify() customization point in libfoo, I can lookup a tutorial =
to get all of the dispatching correct. I only need to do this once for all =
of the thousands if not millions of times my users will just need to say fo=
o::fooify(fooable_thing);. If I&#39;m writing my own customization points, =
I&#39;m already an expert C++ developer. Furthermore, we could also conside=
r adding helper utilities for this in the standard library, even if they ha=
ve to be macros.</div><div>=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a7e2efc2-bbee-40ed-963b-42339bf0e21c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a7e2efc2-bbee-40ed-963b-42339bf0e21c=
%40isocpp.org</a>.<br />

------=_Part_833_563837736.1494008942881--

------=_Part_832_263340514.1494008942881--

.


Author: Mathias Gaunard <mathias@gaunard.com>
Date: Fri, 5 May 2017 19:33:19 +0100
Raw View
--001a1137cb9aaabc90054ecb1f65
Content-Type: text/plain; charset=UTF-8

On 5 May 2017 at 18:54, Matthew Fioravante <fmatthew5876@gmail.com> wrote:

> The swap(), begin(), end(), size(), etc... is an embarrassment.
>
> - Its ugly to adding these using declarations.
> - Its crazy error prone. Too easy to forget a using declaration.
> - These functions cannot be called in single expression contexts like
> decltype().
>
> Why can't we just make std::swap() do all of the magic dispatching
> internally? Then the convention is people always call std::swap(),
> std::begin(), etc..
>

One man's embarassment is another man's good design.
ADL clearly expresses it is an extension point.

Having a function in std:: calling things in your namespace isn't as clean
as looking up the function in the associated namespaces.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALnjya9r3EupBRoVqY4b1Utbu7JEP%2BcwKqoT8dTZ8PLfimcuuA%40mail.gmail.com.

--001a1137cb9aaabc90054ecb1f65
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 5=
 May 2017 at 18:54, Matthew Fioravante <span dir=3D"ltr">&lt;<a href=3D"mai=
lto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.com</a>&gt=
;</span> wrote:<br><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"><div d=
ir=3D"ltr">The swap(), begin(), end(), size(), etc... is an embarrassment.<=
div><br></div><div>- Its ugly to adding these using declarations.<br></div>=
<div>- Its crazy error prone. Too easy to forget a using declaration.</div>=
<div>- These functions cannot be called in single expression contexts like =
decltype().</div><div><div><br></div><div>Why can&#39;t we just make std::s=
wap() do all of the magic dispatching internally? Then the convention is pe=
ople always call std::swap(), std::begin(), etc..</div></div></div></blockq=
uote><div><br></div>One man&#39;s embarassment is another man&#39;s good de=
sign.<br>ADL clearly expresses it is an extension point.<div><br></div><div=
>Having a function in std:: calling things in your namespace isn&#39;t as c=
lean as looking up the function in the associated namespaces.=C2=A0</div></=
div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALnjya9r3EupBRoVqY4b1Utbu7JEP%2BcwKq=
oT8dTZ8PLfimcuuA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALnjya9r3EupBR=
oVqY4b1Utbu7JEP%2BcwKqoT8dTZ8PLfimcuuA%40mail.gmail.com</a>.<br />

--001a1137cb9aaabc90054ecb1f65--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 5 May 2017 21:39:03 +0300
Raw View
On 5 May 2017 at 21:29, Matthew Fioravante <fmatthew5876@gmail.com> wrote:
>> Because it would be a backwards-incompatible change.
>
>
> C++ has broken backwards compatibility before. Right now if you call

That's not an open license to break compatibility whenever you feel like it.

> std::swap() on your object, unless its in std you'll get a default move
> based swap operation. Suppose that was all of the sudden silently changed to
> actually call your type's swap() operation if it has one. How bad would that
> be? How much code would it break?

That needs to be explored. Such a change can lead to program breakage
if std::swap starts
calling swaps that weren't meant for swapping, and I have no idea
whether such beasts exist.

> I consider swap() special in the same vein as move and copy. We've added
> rules to change how those are called/elided in the past knowing it could
> break code. If you write a swap() its suppose to do swapping, if it does
> something else you get what you deserve. "Optimizing" std::swap() to call

I don't deserve my working code to stop compiling just because you
have problems with
how std::swap is defined.

> The fact that essential library primitives like swap() and begin() require
> expert level knowledge to use correctly is a complete and utter failure.
> Really, its just ****ing stupid. ADL is not the proper tool for this. I'd

Well, we get very few bug reports about it, and even fewer proposals.
I know, most users
don't report bugs, but there's no indication that this is such a big problem.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUbbFF7mZn6urZqZsCPwMWvHnwqn_gmuA3DLwpMQ0pX%3D8w%40mail.gmail.com.

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 5 May 2017 12:03:36 -0700 (PDT)
Raw View
------=_Part_850_1452437173.1494011016820
Content-Type: multipart/alternative;
 boundary="----=_Part_851_345285709.1494011016820"

------=_Part_851_345285709.1494011016820
Content-Type: text/plain; charset=UTF-8



On Friday, May 5, 2017 at 1:39:05 PM UTC-5, Ville Voutilainen wrote:
>
> On 5 May 2017 at 21:29, Matthew Fioravante <fmatth...@gmail.com
> <javascript:>> wrote:
> >> Because it would be a backwards-incompatible change.
> >
> >
> > C++ has broken backwards compatibility before. Right now if you call
>
> That's not an open license to break compatibility whenever you feel like
> it.
>
> > std::swap() on your object, unless its in std you'll get a default move
> > based swap operation. Suppose that was all of the sudden silently
> changed to
> > actually call your type's swap() operation if it has one. How bad would
> that
> > be? How much code would it break?
>
> That needs to be explored. Such a change can lead to program breakage
> if std::swap starts
> calling swaps that weren't meant for swapping, and I have no idea
> whether such beasts exist.
>

It would have to be a case where someone explicitly calls std::swap()
already on their type and the type has a swap() method which is doing
something other than swap entirely. That already sounds like an extremely
rare (and poorly designed) unicorn to begin with.

Lets also not forget the standard convention of implementing swap() has
been around since the beginning of C++ and has been a standard practice
recommended in any C++ tutorial, book, or class for decades. I can't
imagine so many people really abuse swap() for something else.

Certainly it does need to be explored. I'm not suggesting we go and break
the world without a proper study. The problem is that a lot of times the
specter of breaking backwards compatibility even for an extremely rare and
improbable edge case shuts out the possibility of even discussing a change
entirely from the start.




> > I consider swap() special in the same vein as move and copy. We've added
> > rules to change how those are called/elided in the past knowing it could
> > break code. If you write a swap() its suppose to do swapping, if it does
> > something else you get what you deserve. "Optimizing" std::swap() to
> call
>
> I don't deserve my working code to stop compiling just because you
> have problems with
> how std::swap is defined.
>

I certainly doubt any of the code you personally have wrote, or anyone else
in this thread would be broken by such a change.

Its not the same as for example fixing min() and max(). That would be a
great change, but it almost certainly would break a lot of code and
therefore can never be fixed without an STL rewrite.


>
> > The fact that essential library primitives like swap() and begin()
> require
> > expert level knowledge to use correctly is a complete and utter failure.
> > Really, its just ****ing stupid. ADL is not the proper tool for this.
> I'd
>
> Well, we get very few bug reports about it, and even fewer proposals.
> I know, most users
> don't report bugs, but there's no indication that this is such a big
> problem.
>

Its an expert level problem. How many expert level users are really aware
of all of the caveats? How many of that subset actually file bugs, post in
this forum, or somehow otherwise contribute to standardization? How many
people just call x.begin() in their code (raising my own hand here) and
completely ignore this broken and complicated ADL business?

How many people have needed to do decltype(begin(x)) and then really saw
how terrible this API is?

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9539ea6c-14b4-41e7-99f0-6bb6cc4d947b%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Friday, May 5, 2017 at 1:39:05 PM UTC-5, Ville =
Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 5 May 201=
7 at 21:29, Matthew Fioravante &lt;<a href=3D"javascript:" target=3D"_blank=
" gdf-obfuscated-mailto=3D"l6lHNs7bBAAJ" rel=3D"nofollow" onmousedown=3D"th=
is.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;j=
avascript:&#39;;return true;">fmatth...@gmail.com</a>&gt; wrote:
<br>&gt;&gt; Because it would be a backwards-incompatible change.
<br>&gt;
<br>&gt;
<br>&gt; C++ has broken backwards compatibility before. Right now if you ca=
ll
<br>
<br>That&#39;s not an open license to break compatibility whenever you feel=
 like it.
<br>
<br>&gt; std::swap() on your object, unless its in std you&#39;ll get a def=
ault move
<br>&gt; based swap operation. Suppose that was all of the sudden silently =
changed to
<br>&gt; actually call your type&#39;s swap() operation if it has one. How =
bad would that
<br>&gt; be? How much code would it break?
<br>
<br>That needs to be explored. Such a change can lead to program breakage
<br>if std::swap starts
<br>calling swaps that weren&#39;t meant for swapping, and I have no idea
<br>whether such beasts exist.
<br></blockquote><div><br></div><div>It would have to be a case where someo=
ne explicitly calls std::swap() already on their type and the type has a sw=
ap() method which is doing something other than swap entirely. That already=
 sounds like an extremely rare (and poorly designed) unicorn to begin with.=
=C2=A0</div><div><br></div><div>Lets also not forget the standard conventio=
n of implementing swap() has been around since the beginning of C++ and has=
 been a standard practice recommended in any C++ tutorial, book, or class f=
or decades. I can&#39;t imagine so many people really abuse swap() for some=
thing else.</div><div><br></div><div>Certainly it does need to be explored.=
 I&#39;m not suggesting we go and break the world without a proper study. T=
he problem is that a lot of times the specter of breaking backwards compati=
bility even for an extremely rare and improbable edge case shuts out the po=
ssibility of even discussing a change entirely from the start.</div><div><b=
r></div><div><br></div><div><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;">
<br>&gt; I consider swap() special in the same vein as move and copy. We&#3=
9;ve added
<br>&gt; rules to change how those are called/elided in the past knowing it=
 could
<br>&gt; break code. If you write a swap() its suppose to do swapping, if i=
t does
<br>&gt; something else you get what you deserve. &quot;Optimizing&quot; st=
d::swap() to call
<br>
<br>I don&#39;t deserve my working code to stop compiling just because you
<br>have problems with
<br>how std::swap is defined.<br></blockquote><div><br></div><div>I certain=
ly doubt any of the code you personally have wrote, or anyone else in this =
thread would be broken by such a change.</div><div><br></div><div>Its not t=
he same as for example fixing min() and max(). That would be a great change=
, but it almost certainly would break a lot of code and therefore can never=
 be fixed without an STL rewrite.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">
<br>&gt; The fact that essential library primitives like swap() and begin()=
 require
<br>&gt; expert level knowledge to use correctly is a complete and utter fa=
ilure.
<br>&gt; Really, its just ****ing stupid. ADL is not the proper tool for th=
is. I&#39;d
<br>
<br>Well, we get very few bug reports about it, and even fewer proposals.
<br>I know, most users
<br>don&#39;t report bugs, but there&#39;s no indication that this is such =
a big problem.
<br></blockquote><div><br></div><div>Its an expert level problem. How many =
expert level users are really aware of all of the caveats? How many of that=
 subset actually file bugs, post in this forum, or somehow otherwise contri=
bute to standardization? How many people just call x.begin() in their code =
(raising my own hand here) and completely ignore this broken and complicate=
d ADL business?</div><div><br></div><div>How many people have needed to do =
decltype(begin(x)) and then really saw how terrible this API is?</div></div=
>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9539ea6c-14b4-41e7-99f0-6bb6cc4d947b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9539ea6c-14b4-41e7-99f0-6bb6cc4d947b=
%40isocpp.org</a>.<br />

------=_Part_851_345285709.1494011016820--

------=_Part_850_1452437173.1494011016820--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 5 May 2017 12:49:30 -0700 (PDT)
Raw View
------=_Part_1290_359541305.1494013771071
Content-Type: multipart/alternative;
 boundary="----=_Part_1291_761105099.1494013771072"

------=_Part_1291_761105099.1494013771072
Content-Type: text/plain; charset=UTF-8

On Friday, May 5, 2017 at 2:33:25 PM UTC-4, Mathias Gaunard wrote:
>
> On 5 May 2017 at 18:54, Matthew Fioravante <fmatth...@gmail.com
> <javascript:>> wrote:
>
>> The swap(), begin(), end(), size(), etc... is an embarrassment.
>>
>> - Its ugly to adding these using declarations.
>> - Its crazy error prone. Too easy to forget a using declaration.
>> - These functions cannot be called in single expression contexts like
>> decltype().
>>
>> Why can't we just make std::swap() do all of the magic dispatching
>> internally? Then the convention is people always call std::swap(),
>> std::begin(), etc..
>>
>
> One man's embarassment is another man's good design.
> ADL clearly expresses it is an extension point.
>

Except for things that can't be ADL'd, of course (ie: all fundamental
types). And for types which use a member function that has the desired
behavior, rather than implementing it in two places. Which is why `using
std::swap` is used before attempting to invoke ADL swap.

Having to do that for every ADL customization point is the problem.


> Having a function in std:: calling things in your namespace isn't as clean
> as looking up the function in the associated namespaces.
>

The idea is that `std::swap` would call the `swap` in your namespace via an
ADL call. But as a specific overload of the non-ADL `std::swap`  function.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/24714caa-e72b-452a-a12b-d9a94284cfbd%40isocpp.org.

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

<div dir=3D"ltr">On Friday, May 5, 2017 at 2:33:25 PM UTC-4, Mathias Gaunar=
d 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>=
<div class=3D"gmail_quote">On 5 May 2017 at 18:54, Matthew Fioravante <span=
 dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"KVwI837bBAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;">fmatth...@gmail.com</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr">The swap(), begin(), end(=
), size(), etc... is an embarrassment.<div><br></div><div>- Its ugly to add=
ing these using declarations.<br></div><div>- Its crazy error prone. Too ea=
sy to forget a using declaration.</div><div>- These functions cannot be cal=
led in single expression contexts like decltype().</div><div><div><br></div=
><div>Why can&#39;t we just make std::swap() do all of the magic dispatchin=
g internally? Then the convention is people always call std::swap(), std::b=
egin(), etc..</div></div></div></blockquote><div><br></div>One man&#39;s em=
barassment is another man&#39;s good design.<br>ADL clearly expresses it is=
 an extension point.</div></div></div></blockquote><div><br>Except for thin=
gs that can&#39;t be ADL&#39;d, of course (ie: all fundamental types). And =
for types which use a member function that has the desired behavior, rather=
 than implementing it in two places. Which is why `using std::swap` is used=
 before attempting to invoke ADL swap.<br><br>Having to do that for every A=
DL customization point is the problem.<br>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><d=
iv></div><div>Having a function in std:: calling things in your namespace i=
sn&#39;t as clean as looking up the function in the associated namespaces.=
=C2=A0</div></div></div></div></blockquote><div><br>The idea is that `std::=
swap` would call the `swap` in your namespace via an ADL call. But as a spe=
cific overload of the non-ADL `std::swap`=C2=A0 function.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/24714caa-e72b-452a-a12b-d9a94284cfbd%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/24714caa-e72b-452a-a12b-d9a94284cfbd=
%40isocpp.org</a>.<br />

------=_Part_1291_761105099.1494013771072--

------=_Part_1290_359541305.1494013771071--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 5 May 2017 12:58:12 -0700 (PDT)
Raw View
------=_Part_1406_1375510774.1494014292953
Content-Type: multipart/alternative;
 boundary="----=_Part_1407_751187339.1494014292953"

------=_Part_1407_751187339.1494014292953
Content-Type: text/plain; charset=UTF-8

On Friday, May 5, 2017 at 2:29:03 PM UTC-4, Matthew Fioravante wrote:
>
> On Friday, May 5, 2017 at 1:03:10 PM UTC-5, Nicol Bolas wrote:
>>
>> Because it would be a backwards-incompatible change.
>>
>
> C++ has broken backwards compatibility before. Right now if you call
> std::swap() on your object, unless its in std you'll get a default move
> based swap operation. Suppose that was all of the sudden silently changed
> to actually call your type's swap() operation if it has one. How bad would
> that be? How much code would it break?
>
> I consider swap() special in the same vein as move and copy. We've added
> rules to change how those are called/elided in the past knowing it could
> break code. If you write a swap() its suppose to do swapping, if it does
> something else you get what you deserve. "Optimizing" std::swap() to call
> your types custom swap if it has one does not sound like a bad thing to me.
>
> The fact that essential library primitives like swap() and begin() require
> expert level knowledge to use correctly is a complete and utter failure.*
> Really, its just ****ing stupid.* ADL is not the proper tool for this.
> I'd argue ADL is only really useful for operator overloading. Unless you
> put swap(), begin(), etc.. to the global :: namespace, ADL will never work.
> That's a non-starter too as third party libraries wanting to define
> "customization points" such as begin() certainly cannot just put stuff in
> the global namespace.
>
> With have virtual functions for runtime dispatch, and this broken crap
> interface for compile time dispatch. This is a serious bug that needs to be
> fixed.
>

I don't disagree on the importance of customization points. I don't
disagree with the need to have them work.

That alone however *cannot* justify doing it in a backwards-incompatible
way.

It also wouldn't help users create similar interfaces that have similar
>> behavior.
>>
>
> That's a secondary concern.
>

I strongly disagree. It's like saying that we need to have ranges in the
standard library, but it's a secondary concern to provide tools to help
people write standard library compatible ranges. What good is it to have
standard idioms if writing idiom-compatible constructs is so complex/arcane
that users can not reasonably be expected to define them on their own?

Writing a standard library compatible range should not be hard. Writing a
standard library compatible customization point should also not be hard.
This should be a primary concern of any solution to this problem. Once we
standardize the concept of "customization point", people will and should
want to do it in a way that is compatible with the standard library. If we
make that simple, then we allow them to do so.

If we make the idiom complex or arcane, all we do is create dozens of
headaches down the road.


> If I want to write foo::fooify() customization point in libfoo, I can
> lookup a tutorial to get all of the dispatching correct. I only need to do
> this once for all of the thousands if not millions of times my users will
> just need to say foo::fooify(fooable_thing);. If I'm writing my own
> customization points, I'm already an expert C++ developer.
>

That kind of thinking is what gets us `std::enable_if`. "If I want to do
some SFINAE-style stuff, then I'm already an expert C++ developer".

Utter nonsense. By adding appropriate things to the language, we give
novices the power to do the things that experts do. We take arcane idioms
and bring them to the masses.

When we get concepts, you'll see the number of people using SFINAE increase
dramatically. Why? Because it makes it a real part of the language, not
some arcane hack. Users have needs that SFINAE could solve, but they don't
use it because it's needlessly difficult and over-complicated. The same
goes here. Creating a customization points should not be something that
requires being an expert C++ developer. Users want to be able to do these
things, but as of yet, there is no good, simple solution for it.

Furthermore, we could also consider adding helper utilities for this in the
> standard library, even if they have to be macros.
>

Yes, don't bother with a nice, neat language feature. It's much better to
do this sort of stuff as a macro.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/75ea01c3-e829-4ba6-9311-189748f73354%40isocpp.org.

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

<div dir=3D"ltr">On Friday, May 5, 2017 at 2:29:03 PM UTC-4, Matthew Fiorav=
ante 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">On=
 Friday, May 5, 2017 at 1:03:10 PM UTC-5, Nicol Bolas wrote:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div>Because it would be a backwa=
rds-incompatible change.</div></div></blockquote><div><br></div><div>C++ ha=
s broken backwards compatibility before. Right now if you call std::swap() =
on your object, unless its in std you&#39;ll get a default move based swap =
operation. Suppose that was all of the sudden silently changed to actually =
call your type&#39;s swap() operation if it has one. How bad would that be?=
 How much code would it break?</div><div><br></div><div>I consider swap() s=
pecial in the same vein as move and copy. We&#39;ve added rules to change h=
ow those are called/elided in the past knowing it could break code. If you =
write a swap() its suppose to do swapping, if it does something else you ge=
t what you deserve. &quot;Optimizing&quot; std::swap() to call your types c=
ustom swap if it has one does not sound like a bad thing to me.</div><div><=
br></div><div>The fact that essential library primitives like swap() and be=
gin() require expert level knowledge to use correctly is a complete and utt=
er failure.<b> Really, its just ****ing stupid.</b> ADL is not the proper t=
ool for this. I&#39;d argue ADL is only really useful for operator overload=
ing. Unless you put swap(), begin(), etc.. to the global :: namespace, ADL =
will never work. That&#39;s a non-starter too as third party libraries want=
ing to define &quot;customization points&quot; such as begin() certainly ca=
nnot just put stuff in the global namespace.</div><div><br></div><div>With =
have virtual functions for runtime dispatch, and this broken crap interface=
 for compile time dispatch. This is a serious bug that needs to be fixed.</=
div></div></blockquote><div><br>I don&#39;t disagree on the importance of c=
ustomization points. I don&#39;t disagree with the need to have them work.<=
br><br>That alone however <i>cannot</i> justify doing it in a backwards-inc=
ompatible way.<br><br></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"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>It also wouldn&#39;t help users create similar interfaces that have simil=
ar behavior. <br></div></div></blockquote><div><br></div><div>That&#39;s a =
secondary concern.</div></div></blockquote><div><br>I strongly disagree. It=
&#39;s like saying that we need to have ranges in the standard library, but=
 it&#39;s a secondary concern to provide tools to help people write standar=
d library compatible ranges. What good is it to have standard idioms if wri=
ting idiom-compatible constructs is so complex/arcane that users can not re=
asonably be expected to define them on their own?<br><br>Writing a standard=
 library compatible range should not be hard. Writing a standard library co=
mpatible customization point should also not be hard. This should be a prim=
ary concern of any solution to this problem. Once we standardize the concep=
t of &quot;customization point&quot;, people will and should want to do it =
in a way that is compatible with the standard library. If we make that simp=
le, then we allow them to do so.<br><br>If we make the idiom complex or arc=
ane, all we do is create dozens of headaches down the road.<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>If I wan=
t to write foo::fooify() customization point in libfoo, I can lookup a tuto=
rial to get all of the dispatching correct. I only need to do this once for=
 all of the thousands if not millions of times my users will just need to s=
ay foo::fooify(fooable_thing);. If I&#39;m writing my own customization poi=
nts, I&#39;m already an expert C++ developer.</div></div></blockquote><div>=
<br>That kind of thinking is what gets us `std::enable_if`. &quot;If I want=
 to do some SFINAE-style stuff, then I&#39;m already an expert C++ develope=
r&quot;.<br><br>Utter nonsense. By adding appropriate things to the languag=
e, we give novices the power to do the things that experts do. We take arca=
ne idioms and bring them to the masses.<br><br>When we get concepts, you&#3=
9;ll see the number of people using SFINAE increase dramatically. Why? Beca=
use it makes it a real part of the language, not some arcane hack. Users ha=
ve needs that SFINAE could solve, but they don&#39;t use it because it&#39;=
s needlessly difficult and over-complicated. The same goes here. Creating a=
 customization points should not be something that requires being an expert=
 C++ developer. Users want to be able to do these things, but as of yet, th=
ere is no good, simple solution for it.<br><br></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>Furthermore, we could also con=
sider adding helper utilities for this in the standard library, even if the=
y have to be macros. <br></div></div></blockquote><div><br>Yes, don&#39;t b=
other with a nice, neat language feature. It&#39;s much better to do this s=
ort of stuff as a macro. <br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/75ea01c3-e829-4ba6-9311-189748f73354%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/75ea01c3-e829-4ba6-9311-189748f73354=
%40isocpp.org</a>.<br />

------=_Part_1407_751187339.1494014292953--

------=_Part_1406_1375510774.1494014292953--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 5 May 2017 13:40:43 -0700 (PDT)
Raw View
------=_Part_936_621799994.1494016843780
Content-Type: multipart/alternative;
 boundary="----=_Part_937_1688239810.1494016843780"

------=_Part_937_1688239810.1494016843780
Content-Type: text/plain; charset=UTF-8



On Friday, May 5, 2017 at 2:58:13 PM UTC-5, Nicol Bolas wrote:
>
> On Friday, May 5, 2017 at 2:29:03 PM UTC-4, Matthew Fioravante wrote:
>>
>> On Friday, May 5, 2017 at 1:03:10 PM UTC-5, Nicol Bolas wrote:
>>>
>>> Because it would be a backwards-incompatible change.
>>>
>>
>> C++ has broken backwards compatibility before. Right now if you call
>> std::swap() on your object, unless its in std you'll get a default move
>> based swap operation. Suppose that was all of the sudden silently changed
>> to actually call your type's swap() operation if it has one. How bad would
>> that be? How much code would it break?
>>
>> I consider swap() special in the same vein as move and copy. We've added
>> rules to change how those are called/elided in the past knowing it could
>> break code. If you write a swap() its suppose to do swapping, if it does
>> something else you get what you deserve. "Optimizing" std::swap() to call
>> your types custom swap if it has one does not sound like a bad thing to me.
>>
>> The fact that essential library primitives like swap() and begin()
>> require expert level knowledge to use correctly is a complete and utter
>> failure.* Really, its just ****ing stupid.* ADL is not the proper tool
>> for this. I'd argue ADL is only really useful for operator overloading.
>> Unless you put swap(), begin(), etc.. to the global :: namespace, ADL will
>> never work. That's a non-starter too as third party libraries wanting to
>> define "customization points" such as begin() certainly cannot just put
>> stuff in the global namespace.
>>
>> With have virtual functions for runtime dispatch, and this broken crap
>> interface for compile time dispatch. This is a serious bug that needs to be
>> fixed.
>>
>
> I don't disagree on the importance of customization points. I don't
> disagree with the need to have them work.
>
> That alone however *cannot* justify doing it in a backwards-incompatible
> way.
>
> It also wouldn't help users create similar interfaces that have similar
>>> behavior.
>>>
>>
>> That's a secondary concern.
>>
>
> I strongly disagree. It's like saying that we need to have ranges in the
> standard library, but it's a secondary concern to provide tools to help
> people write standard library compatible ranges. What good is it to have
> standard idioms if writing idiom-compatible constructs is so complex/arcane
> that users can not reasonably be expected to define them on their own?
>
> Writing a standard library compatible range should not be hard. Writing a
> standard library compatible customization point should also not be hard.
> This should be a primary concern of any solution to this problem. Once we
> standardize the concept of "customization point", people will and should
> want to do it in a way that is compatible with the standard library. If we
> make that simple, then we allow them to do so.
>
> If we make the idiom complex or arcane, all we do is create dozens of
> headaches down the road.
>

So then add the tools to help create these things. I never said we
shouldn't. However when making engineering trade-offs in the interface, its
better to design something optimized for the common case (calling a
customization point) over the rare case (writing the default dispatch
driver for a customization point library).


>
>
>> If I want to write foo::fooify() customization point in libfoo, I can
>> lookup a tutorial to get all of the dispatching correct. I only need to do
>> this once for all of the thousands if not millions of times my users will
>> just need to say foo::fooify(fooable_thing);. If I'm writing my own
>> customization points, I'm already an expert C++ developer.
>>
>
> That kind of thinking is what gets us `std::enable_if`. "If I want to do
> some SFINAE-style stuff, then I'm already an expert C++ developer".
>

I don't agree with this comparison. Hacking overload resolution with
enable_if is something we do way more often than creating new customization
points.

The use case here is not "I want to do SFINAE stuff" (expert only
implementation specific gibberish), its "I want write a math function which
only operates on any kind of `real number' type" (basic core idea).

Before we go ahead and add language features, ugly less invasive things
like this are a good start to get experience. Everybody hates enable_if for
good reason but before concepts that's all we had to solve a real need. The
standard library 10 years from now is not going to be any worse off for the
existence of an old enable_if template now collecting dust unused in the
new conceptified regime.



> Utter nonsense. By adding appropriate things to the language, we give
> novices the power to do the things that experts do. We take arcane idioms
> and bring them to the masses.
>
> When we get concepts, you'll see the number of people using SFINAE
> increase dramatically. Why? Because it makes it a real part of the
> language, not some arcane hack. Users have needs that SFINAE could solve,
> but they don't use it because it's needlessly difficult and
> over-complicated. The same goes here. Creating a customization points
> should not be something that requires being an expert C++ developer. Users
> want to be able to do these things, but as of yet, there is no good, simple
> solution for it.
>
> Furthermore, we could also consider adding helper utilities for this in
>> the standard library, even if they have to be macros.
>>
>
> Yes, don't bother with a nice, neat language feature. It's much better to
> do this sort of stuff as a macro.
>

Ok so invent a new language feature then. I'd be plenty happy with that
too. I don't think you can do this with templates as they are currently
which is why a macro was suggested. A language feature would need to be
more general purpose. I'm not sure it would ever fly to create a core
language feature solely for the purpose of writing customization points.

I'm not at all married to using std::swap() to solve the problem. If
someone has a better solution I'll be the first one to jump on board.
Whatever the solution is, this using std::swap; swap(); nonsense has got to
go.

It also needs to be solved not just for swap(), but for all customization
points including begin(), end(), cbegin(), cend(), rbegin(), rend(),
size(), data(), etc.. As an added bonus, this should also mean we can all
stop doing the brainless and bug friendly work of writing cbegin(), cend(),
rbegin(), rend(), rbegin() const, rend() const, crbegin(), crend() for all
of our custom container classes. Instead just relying on the default
adapters generated by the std:: default versions adapting begin(), begin()
const, end(), and end() const.



Lets not also forget we have concepts on the way. Once concepts are out in
the wild this ADL problem is going to become a much bigger issue fast. Its
was one of the main use cases driving unified function call syntax. Do we
want to wait until the bug reports and complaints after concepts or should
we not try to attack this issue now?

If I want to make an Iterable concept, I'd like to just say that it
begin(x) and end(x) are valid expressions which return Iterator concepts.
Why the hell do I need to deal with these using declaration gymnastics? How
do I carefully add them without polluting the entire scope? I still haven't
review the concepts proposal in detail. Can I even put a using declaration
inside a concept expression?

For homework, try to implement the following from scratch. Do not cheat
with type_traits, concepts, or any other std:: machinery that already
solves the problem. Do not pollute the enclosing scope with using
declarations.

* Given a type T, write a noexcept() expression which is true if the swap()
expression for an object of type T would be noexcept.
* Given a type T, write a decltype() expression to get the type resulting
from a begin() expression called on an object of type T.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/68381f91-4180-429c-8f52-de00bd725c60%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Friday, May 5, 2017 at 2:58:13 PM UTC-5, Nicol =
Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">O=
n Friday, May 5, 2017 at 2:29:03 PM UTC-4, Matthew Fioravante wrote:<blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Friday, May 5, 2017 at=
 1:03:10 PM UTC-5, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div>Because it would be a backwards-incompatible change=
..</div></div></blockquote><div><br></div><div>C++ has broken backwards comp=
atibility before. Right now if you call std::swap() on your object, unless =
its in std you&#39;ll get a default move based swap operation. Suppose that=
 was all of the sudden silently changed to actually call your type&#39;s sw=
ap() operation if it has one. How bad would that be? How much code would it=
 break?</div><div><br></div><div>I consider swap() special in the same vein=
 as move and copy. We&#39;ve added rules to change how those are called/eli=
ded in the past knowing it could break code. If you write a swap() its supp=
ose to do swapping, if it does something else you get what you deserve. &qu=
ot;Optimizing&quot; std::swap() to call your types custom swap if it has on=
e does not sound like a bad thing to me.</div><div><br></div><div>The fact =
that essential library primitives like swap() and begin() require expert le=
vel knowledge to use correctly is a complete and utter failure.<b> Really, =
its just ****ing stupid.</b> ADL is not the proper tool for this. I&#39;d a=
rgue ADL is only really useful for operator overloading. Unless you put swa=
p(), begin(), etc.. to the global :: namespace, ADL will never work. That&#=
39;s a non-starter too as third party libraries wanting to define &quot;cus=
tomization points&quot; such as begin() certainly cannot just put stuff in =
the global namespace.</div><div><br></div><div>With have virtual functions =
for runtime dispatch, and this broken crap interface for compile time dispa=
tch. This is a serious bug that needs to be fixed.</div></div></blockquote>=
<div><br>I don&#39;t disagree on the importance of customization points. I =
don&#39;t disagree with the need to have them work.<br><br>That alone howev=
er <i>cannot</i> justify doing it in a backwards-incompatible way.<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"><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"><div>It also wouldn&#39;t help =
users create similar interfaces that have similar behavior. <br></div></div=
></blockquote><div><br></div><div>That&#39;s a secondary concern.</div></di=
v></blockquote><div><br>I strongly disagree. It&#39;s like saying that we n=
eed to have ranges in the standard library, but it&#39;s a secondary concer=
n to provide tools to help people write standard library compatible ranges.=
 What good is it to have standard idioms if writing idiom-compatible constr=
ucts is so complex/arcane that users can not reasonably be expected to defi=
ne them on their own?<br><br>Writing a standard library compatible range sh=
ould not be hard. Writing a standard library compatible customization point=
 should also not be hard. This should be a primary concern of any solution =
to this problem. Once we standardize the concept of &quot;customization poi=
nt&quot;, people will and should want to do it in a way that is compatible =
with the standard library. If we make that simple, then we allow them to do=
 so.<br><br>If we make the idiom complex or arcane, all we do is create doz=
ens of headaches down the road.<br></div></div></blockquote><div><br></div>=
<div>So then add the tools to help create these things. I never said we sho=
uldn&#39;t. However when making engineering trade-offs in the interface, it=
s better to design something optimized for the common case (calling a custo=
mization point) over the rare case (writing the default dispatch driver for=
 a customization point library).</div><div>=C2=A0</div><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>=C2=A0</div><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>If I want to write foo::fooif=
y() customization point in libfoo, I can lookup a tutorial to get all of th=
e dispatching correct. I only need to do this once for all of the thousands=
 if not millions of times my users will just need to say foo::fooify(fooabl=
e_thing);. If I&#39;m writing my own customization points, I&#39;m already =
an expert C++ developer.</div></div></blockquote><div><br>That kind of thin=
king is what gets us `std::enable_if`. &quot;If I want to do some SFINAE-st=
yle stuff, then I&#39;m already an expert C++ developer&quot;.<br></div></d=
iv></blockquote><div><br></div><div>I don&#39;t agree with this comparison.=
 Hacking overload resolution with enable_if is something we do way more oft=
en than creating new customization points.</div><div><br></div><div>The use=
 case here is not &quot;I want to do SFINAE stuff&quot; (expert only implem=
entation specific gibberish), its &quot;I want write a math function which =
only operates on any kind of `real number&#39; type&quot; (basic core idea)=
..</div><div><br>Before we go ahead and add language features, ugly less inv=
asive things like this are a good start to get experience. Everybody hates =
enable_if for good reason but before concepts that&#39;s all we had to solv=
e a real need. The standard library 10 years from now is not going to be an=
y worse off for the existence of an old enable_if template now collecting d=
ust unused in the new conceptified regime.</div><div><br></div><div><br></d=
iv><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><br>U=
tter nonsense. By adding appropriate things to the language, we give novice=
s the power to do the things that experts do. We take arcane idioms and bri=
ng them to the masses.<br><br>When we get concepts, you&#39;ll see the numb=
er of people using SFINAE increase dramatically. Why? Because it makes it a=
 real part of the language, not some arcane hack. Users have needs that SFI=
NAE could solve, but they don&#39;t use it because it&#39;s needlessly diff=
icult and over-complicated. The same goes here. Creating a customization po=
ints should not be something that requires being an expert C++ developer. U=
sers want to be able to do these things, but as of yet, there is no good, s=
imple solution for it.<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>Furthermore, we could also consider adding helper ut=
ilities for this in the standard library, even if they have to be macros. <=
br></div></div></blockquote><div><br>Yes, don&#39;t bother with a nice, nea=
t language feature. It&#39;s much better to do this sort of stuff as a macr=
o. <br></div></div></blockquote><div><br></div><div>Ok so invent a new lang=
uage feature then. I&#39;d be plenty happy with that too. I don&#39;t think=
 you can do this with templates as they are currently which is why a macro =
was suggested. A language feature would need to be more general purpose. I&=
#39;m not sure it would ever fly to create a core language feature solely f=
or the purpose of writing customization points.</div><div><br></div><div>I&=
#39;m not at all married to using std::swap() to solve the problem. If some=
one has a better solution I&#39;ll be the first one to jump on board. Whate=
ver the solution is, this using std::swap; swap(); nonsense has got to go.<=
/div><div><br></div><div>It also needs to be solved not just for swap(), bu=
t for all customization points including begin(), end(), cbegin(), cend(), =
rbegin(), rend(), size(), data(), etc.. As an added bonus, this should also=
 mean we can all stop doing the brainless and bug friendly work of writing =
cbegin(), cend(), rbegin(), rend(), rbegin() const, rend() const, crbegin()=
, crend() for all of our custom container classes. Instead just relying on =
the default adapters generated by the std:: default versions adapting begin=
(), begin() const, end(), and end() const.</div><div><br></div><div><br></d=
iv><div><br></div>Lets not also forget we have concepts on the way. Once co=
ncepts are out in the wild this ADL problem is going to become a much bigge=
r issue fast. Its was one of the main use cases driving unified function ca=
ll syntax. Do we want to wait until the bug reports and complaints after co=
ncepts or should we not try to attack this issue now?<div><br></div><div>If=
 I want to make an Iterable concept, I&#39;d like to just say that it begin=
(x) and end(x) are valid expressions which return Iterator concepts. Why th=
e hell do I need to deal with these using declaration gymnastics? How do I =
carefully add them without polluting the entire scope? I still haven&#39;t =
review the concepts proposal in detail. Can I even put a using declaration =
inside a concept expression?</div><div><br></div><div>For homework, try to =
implement the following from scratch. Do not cheat with type_traits, concep=
ts, or any other std:: machinery that already solves the problem. Do not po=
llute the enclosing scope with using declarations.</div><div><br></div><div=
>* Given a type T, write a noexcept() expression which is true if the swap(=
) expression for an object of type T would be noexcept.</div><div>* Given a=
 type T, write a decltype() expression to get the type resulting from a beg=
in() expression called on an object of type T.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/68381f91-4180-429c-8f52-de00bd725c60%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/68381f91-4180-429c-8f52-de00bd725c60=
%40isocpp.org</a>.<br />

------=_Part_937_1688239810.1494016843780--

------=_Part_936_621799994.1494016843780--

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Fri, 5 May 2017 21:48:33 -0400
Raw View
--Apple-Mail=_C1653AE1-1C7D-4167-9533-9454103C736A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8

On May 5, 2017, at 2:29 PM, Matthew Fioravante <fmatthew5876@gmail.com> wro=
te:
>=20
> Right now if you call std::swap() on your object, unless its in std you'l=
l get a default move based swap operation. Suppose that was all of the sudd=
en silently changed to actually call your type's swap() operation if it has=
 one. How bad would that be? How much code would it break?

I=E2=80=99ve seen this code in the wild:

struct A
{
    void swap(A& a)
    {
        std::swap(*this, a);
    }
};

I=E2=80=99m not claiming it is good code.  Just that it exists.  How freque=
nt, I=E2=80=99m not sure.  But more than none.

If we have std::swap call A=E2=80=99s swap, this A silently gets infinite r=
ecursion.

Howard

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/E859BC5E-2BFA-47BF-9B0E-45D95E380838%40gmail.com=
..

--Apple-Mail=_C1653AE1-1C7D-4167-9533-9454103C736A
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename=signature.asc
Content-Type: application/pgp-signature;
 name=signature.asc
Content-Description: Message signed with OpenPGP

-----BEGIN PGP SIGNATURE-----

iQIcBAEBCAAGBQJZDStyAAoJEGbcHCxKqhWC+hQP/2w19p0I2himekTgjnUVVQ+X
zZ7qCW3Ud0qcXEAggI2uxJG3rtMu+XVegQKYsRf+4vlJnZ7FtoVBM2deTPDu+Xcw
17Il2/Vs+nbxeXtnK0PuS/4SBlf/UR2pjExc0Qgxct85ZRtOljqKmOGeTxVCfJR8
JIw1NZ6OMNta8D+azuYlsNteL9YmESndZ4v8BgOLqfmhec8wdiGcQ2gefByoxe8i
heAjSQBbEGm9GMmEay/YcM8rBQ3xmPYF53FT7nw10rvMh5iqTsGSREPH4N3qMOmf
po14Yux0KOo9lC0U/DbfJpbT4Wzb8WASGc33wrP8iyVC3zzX4KaFax36jA/9xtKC
y1lFU6RbgXeWtluA7b4UD6XxNw4HH3FHpL63BNmLwVUQ/27N+vNZX2t43DIcxVQA
9OZ9pn9WsPtOVeHjDp27xtdOQ9zZrKmYM8L8AFd1x9sYBFw5ZB144SP9Fi9GQQJM
S89b8dSPuolwlipA3Cn5ZLlKYWYk2cjzoWpFyaE6029vBPnIPA9h46FWM5UW7aOu
+TvCas9Oin1rriKrN5/ui3NhsneriP17YlRd5GWD9+7SLdfSxCSKJp78ag2PFOGY
9pnmDwYGhInmjNi6feAzIE9uAgmkU4xfvutLJuO0M9pShhdx1rX6AgFUsRljYzeA
nqLuGs2hgVsJJrEd4HqY
=bGrt
-----END PGP SIGNATURE-----

--Apple-Mail=_C1653AE1-1C7D-4167-9533-9454103C736A--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Fri, 5 May 2017 20:07:33 -0700
Raw View
--94eb2c195d90b97904054ed24e2f
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wed, May 3, 2017 at 2:14 AM, Marc Mutz <marc.mutz@kdab.com> wrote:

>
> While it's true that std::swap is the most-prominent example, it's also o=
ne
> which really is trivial in many ways. [...] Much more
> interesting than swap() are those functions which are API enablers:
>
> A class template representing angles _needs_ a sin() overload, and up pop=
s
> the
> question how to provide it: via ADL, even though most people will likely
> not
> write
>
>    using std::sin;
>    return sin(a);
>
> ? Or as a specialisation of std::sin() (doen't work) or as an overload of
> std::sin() (not allowed). Example: https://codereview.qt-project.
> org/191717
> So, yeah, via ADL, and thus continues the embarrassment...
>
> A non-std container should provide a version of LF v2's erase_if(). Even
> though erase_if is only overloaded on types in namespace std, since it's
> currently in namespace std::experimental, you still can't say
>
>    erase_if(c, p);
>
> ie. rely on ADL, but need to have another using declaration:
>
>    using std::experimental::erase_if;
>    erase_if(c, p);
>
> This stuff usually gets a laugh from non-C++ experts already.
> But note how this using declaration will fail to compile when LF v2 is no=
t
> supported, requiring adding preprocessor magic around it:
>
>  #if defined(_cpp_lib_dunno_exact_name) && \
>           __cpp_lib_dunno_exact_name >=3D 201411
>    using std::experimental::erase_if;
>  #endif
>    erase_if(c, p);
>
> Ok, all of this will be solved when erase_if moves into namespace std
> proper,
> making this a bad example.
>
> Let's look at STL algorithms:
>
> A wonky container like QList can actually implement reversing as an out-o=
f-
> line function: https://codereview.qt-project.org/144071 It's not
> far-fetched
> to want to specialise std::reverse() to call the member function, which
> would
> require overloading std::reverse(). Or providing an ADL version, which,
> however, requires every use of std::reverse() to say
>
>    using std::reverse;
>    reverse(b, e);
>
> Here, we finally reached a case where no-one in the world writes code lik=
e
> this.
>
> As you can see, the issue is not at all restricted to swap(), begin(),
> size(),
> data() and the very few other customisation points that are being
> discussed.
>

This is a very thoughtful description of a real problem that I had not been
considering, and I'm sorry it seems to have gotten minorly buried in this
thread.

I like your examples of std::sin() and std::reverse() as "customization
points."  You're correct that I would not propose trying to use
Niebler-style "customization point" lambdas for those.  One takeaway point
here is that the set of possible customization points in C++ is an open
set, not a closed set.

The std::reverse example is particularly interesting to me. Consider this
implementation of std::reverse, and then this implementation of std::rotate=
:

    template<class It>
    void reverse(It first, It last)
    {
        while (first !=3D last) {
            --last;
            if (first =3D=3D last) break;
            using std::swap;
            swap(*first, *last);
            ++first;
        }
    }

    template<class It>
    It rotate(It a, It mid, It b)
    {
        auto result =3D a + (b - mid);
        std::reverse(a, b);
        std::reverse(a, result);
        std::reverse(result, b);
        return result;
    }

The implementation of std::reverse goes out of its way to respect the
"customization-point-ness" of swap, but the implementation of std::rotate
does *not* go out of its way to respect the "customization-point-ness" of
reverse.  So, if your particular data type has a speedy reverse,
std::rotate will be inefficient.

Now, the Standard might reasonably say that this state of affairs is fine.
std::rotate isn't supposed to delegate to your speedy reverse; it's not
even guaranteed to call std::reverse (and in fact libstdc++ calls something
named __reverse, and libc++ doesn't use swap at all
<https://wandbox.org/permlink/59FAnIX3rWsY5xuw> in most cases).  It's just
supposed to rotate the given range by some unspecified means, and if you
want a rotate function that *will* use your fast reverse, you'll just have
to write it yourself.  This argument is fine, as far as it goes.

But the Standard Library isn't all libraries. IMHO it would be reasonable
for some library designer out there to say, "My numerics library is generic
enough to work with all numeric datatypes; if it ever calls sin(), or log()=
,
or max(), or sort(), or any function, it'll do it in a way that you can
customize."  And then that designer will need a solution for how to call *a=
ny
arbitrary function* while respecting ADL.  C++03 has a solution for that,
but it's clunky, and as Matthew Fioravante pointed out, the C++03 solution
doesn't play well with decltype(swap(a,b)) or noexcept(noexcept(swap(a,b)))=
..

That is, one might say that the chief failing of the C++03 solution "using
std::swap; swap(a,b)" is that it has failed to keep up with the syntactic
changes in C++11.  If it weren't for that, it would still be *okay*, if
never excellent.

my $.02,
=E2=80=93Arthur

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0K7_xwz_zB%2Bo7NaB-TWjadEFqiUKOihigGZy_DOx=
g7BgQ%40mail.gmail.com.

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

<div dir=3D"ltr">On Wed, May 3, 2017 at 2:14 AM, Marc Mutz <span dir=3D"ltr=
">&lt;<a href=3D"mailto:marc.mutz@kdab.com" target=3D"_blank">marc.mutz@kda=
b.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gma=
il_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-sty=
le:solid;padding-left:1ex"><br>
While it&#39;s true that std::swap is the most-prominent example, it&#39;s =
also one<br>
which really is trivial in many ways. [...]=C2=A0Much more<br>
interesting than swap() are those functions which are API enablers:<br>
<br>
A class template representing angles _needs_ a sin() overload, and up pops =
the<br>
question how to provide it: via ADL, even though most people will likely no=
t<br>
write<br>
<br>
=C2=A0 =C2=A0using std::sin;<br>
=C2=A0 =C2=A0return sin(a);<br>
<br>
? Or as a specialisation of std::sin() (doen&#39;t work) or as an overload =
of<br>
std::sin() (not allowed). Example: <a href=3D"https://codereview.qt-project=
..org/191717" rel=3D"noreferrer" target=3D"_blank">https://codereview.qt-pro=
ject.<wbr>org/191717</a><br>
So, yeah, via ADL, and thus continues the embarrassment...<br>
<br>
A non-std container should provide a version of LF v2&#39;s erase_if(). Eve=
n<br>
though erase_if is only overloaded on types in namespace std, since it&#39;=
s<br>
currently in namespace std::experimental, you still can&#39;t say<br>
<br>
=C2=A0 =C2=A0erase_if(c, p);<br>
<br>
ie. rely on ADL, but need to have another using declaration:<br>
<br>
=C2=A0 =C2=A0using std::experimental::erase_if;<br>
=C2=A0 =C2=A0erase_if(c, p);<br>
<br>
This stuff usually gets a laugh from non-C++ experts already.<br>
But note how this using declaration will fail to compile when LF v2 is not<=
br>
supported, requiring adding preprocessor magic around it:<br>
<br>
=C2=A0#if defined(_cpp_lib_dunno_exact_<wbr>name) &amp;&amp; \<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 __cpp_lib_dunno_exact_name &gt;=3D 20141=
1<br>
=C2=A0 =C2=A0using std::experimental::erase_if;<br>
=C2=A0#endif<br>
=C2=A0 =C2=A0erase_if(c, p);<br>
<br>
Ok, all of this will be solved when erase_if moves into namespace std prope=
r,<br>
making this a bad example.<br>
<br>
Let&#39;s look at STL algorithms:<br>
<br>
A wonky container like QList can actually implement reversing as an out-of-=
<br>
line function: <a href=3D"https://codereview.qt-project.org/144071" rel=3D"=
noreferrer" target=3D"_blank">https://codereview.qt-project.<wbr>org/144071=
</a> It&#39;s not far-fetched<br>
to want to specialise std::reverse() to call the member function, which wou=
ld<br>
require overloading std::reverse(). Or providing an ADL version, which,<br>
however, requires every use of std::reverse() to say<br>
<br>
=C2=A0 =C2=A0using std::reverse;<br>
=C2=A0 =C2=A0reverse(b, e);<br>
<br>
Here, we finally reached a case where no-one in the world writes code like<=
br>
this.<br>
<br>
As you can see, the issue is not at all restricted to swap(), begin(), size=
(),<br>
data() and the very few other customisation points that are being discussed=
..<br></blockquote><div><br></div><div>This is a very thoughtful description=
 of a real problem that I had not been considering, and I&#39;m sorry it se=
ems to have gotten minorly buried in this thread.</div><div><br></div><div>=
I like your examples of std::sin() and std::reverse() as &quot;customizatio=
n points.&quot; =C2=A0You&#39;re correct that I would not propose trying to=
 use Niebler-style &quot;customization point&quot; lambdas for those.=C2=A0=
 One takeaway point here is that the set of possible customization points i=
n C++ is an open set, not a closed set.</div><div><br></div><div>The std::r=
everse example is particularly interesting to me. Consider this implementat=
ion of std::reverse, and then this implementation of std::rotate:</div><div=
><br></div><div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 temp=
late&lt;class It&gt;</font></div><div><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 void reverse(It first, It last)</font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></div><div><font face=3D"mo=
nospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 while (first !=3D last) {</=
font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 --last;</font></div><div><font face=3D"monospace, mono=
space">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (first =3D=3D last) bre=
ak;</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 using std::swap;</font></div><div><font face=3D"mo=
nospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 swap(*first, =
*last);</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ++first;</font></div><div><font face=3D"monospa=
ce, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D=
"monospace, monospace">=C2=A0 =C2=A0 }</font></div></div><div><font face=3D=
"monospace, monospace"><br></font></div><div><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 template&lt;class It&gt;</font></div><div><font face=3D=
"monospace, monospace">=C2=A0 =C2=A0 It rotate(It a, It mid, It b)</font></=
div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></div><d=
iv><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto res=
ult =3D a + (b - mid);</font></div><div><font face=3D"monospace, monospace"=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::reverse(a, b);<br></font></div><div><font=
 face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::reverse(a, =
result);<br></font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 std::reverse(result, b);</font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return result;<br></f=
ont></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 }</font></=
div><div><br></div><div>The implementation of std::reverse goes out of its =
way to respect the &quot;customization-point-ness&quot; of <font face=3D"mo=
nospace, monospace">swap</font>, but the implementation of std::rotate does=
 <i>not</i> go out of its way to respect the &quot;customization-point-ness=
&quot; of <font face=3D"monospace, monospace">reverse</font>.=C2=A0 So, if =
your particular data type has a speedy <font face=3D"monospace, monospace">=
reverse</font>, std::rotate will be inefficient.</div><div><br></div><div>N=
ow, the Standard might reasonably say that this state of affairs is fine. s=
td::rotate isn&#39;t supposed to delegate to your speedy reverse; it&#39;s =
not even guaranteed to call std::reverse (and in fact libstdc++ calls somet=
hing named <font face=3D"monospace, monospace">__reverse</font>, and libc++=
 <a href=3D"https://wandbox.org/permlink/59FAnIX3rWsY5xuw">doesn&#39;t use =
<font face=3D"monospace, monospace">swap</font> at all</a> in most cases).=
=C2=A0 It&#39;s just supposed to rotate the given range by some unspecified=
 means, and if you want a rotate function that <i>will</i> use your fast <f=
ont face=3D"monospace, monospace">reverse</font>, you&#39;ll just have to w=
rite it yourself.=C2=A0 This argument is fine, as far as it goes.</div><div=
><br></div><div>But the Standard Library isn&#39;t all libraries. IMHO it w=
ould be reasonable for some library designer out there to say, &quot;My num=
erics library is generic enough to work with all numeric datatypes; if it e=
ver calls <font face=3D"monospace, monospace">sin()</font>, or <font face=
=3D"monospace, monospace">log()</font>, or <font face=3D"monospace, monospa=
ce">max()</font>, or <font face=3D"monospace, monospace">sort()</font>, or =
any function, it&#39;ll do it in a way that you can customize.&quot; =C2=A0=
And then that designer will need a solution for how to call <i>any arbitrar=
y function</i> while respecting ADL.=C2=A0 C++03 has a solution for that, b=
ut it&#39;s clunky, and as Matthew Fioravante pointed out, the C++03 soluti=
on doesn&#39;t play well with decltype(swap(a,b)) or noexcept(noexcept(swap=
(a,b))).</div><div><br></div><div>That is, one might say that the chief fai=
ling of the C++03 solution &quot;using std::swap; swap(a,b)&quot; is that i=
t has failed to keep up with the syntactic changes in C++11.=C2=A0 If it we=
ren&#39;t for that, it would still be <i>okay</i>, if never excellent.</div=
><div><br></div><div>my $.02,</div><div>=E2=80=93Arthur</div></div></div></=
div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0K7_xwz_zB%2Bo7NaB-TWjadEFqiUKO=
ihigGZy_DOxg7BgQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0K7_xwz_z=
B%2Bo7NaB-TWjadEFqiUKOihigGZy_DOxg7BgQ%40mail.gmail.com</a>.<br />

--94eb2c195d90b97904054ed24e2f--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 5 May 2017 23:52:20 -0700 (PDT)
Raw View
------=_Part_275_118754594.1494053540454
Content-Type: multipart/alternative;
 boundary="----=_Part_276_188349057.1494053540455"

------=_Part_276_188349057.1494053540455
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

One other deficiency of the using std::swap; swap(); idiom is that you lose=
=20
namespace scoping when invoking your customization points.


If I had liba::foo, and libb::foo separate customization points, I cannot=
=20
use them together in the same block of code without some very clumsy=20
scoping. Error prone and terribly ugly more complex code.

When I actually call it, I just say swap(x, y). I have an implicit=20
dependency on which swap was pulled in by a preceding using declaration.=20
Most of the time its on the preceding line, so its obvious. However if you=
=20
have a bunch of calls in the code, you'll want to organize the using=20
declarations and now thats one more thing to track when reading the code.


One compromise would be something like using namespace std::literals;

You might say something like:

using namespace std::custom;

Other libraries like libfoo can support using namespace foo::custom;

Then you automatically get swap(), and the others in your global namespace.=
=20
This makes ADL work at the expense of losing the capability of namespace=20
scoping in invoking customization point names. Fundamentally, this is the=
=20
only way ADL can work. You also still don't get some of the other examples=
=20
like reverse() or sin(). It all comes at a cost of this line of boilerplate=
=20
at the top of your source files and the decision that its always ok to have=
=20
these std symbols in your namespace.

I don't believe ADL at the callsite is up to the task. We either wrap its=
=20
deficiencies away with a standard name like std::swap, adl::swap, or=20
something else. Or somehow design yet another set of core language function=
=20
calling rules to somehow handle this case. The second option sounds=20
terrifying, especially with all the complicated rules the language already=
=20
has.

Unified call syntax was shot down. Right or wrong, it actually didn't solve=
=20
this problem either. UCS lets me not have to worry about saying swap(x, y)=
=20
vs x.swap(y). It still doesn't give me an automatic fallback to std::swap()=
=20
without a using declaration.

std::swap might be particularly scary. Howard Hinnant produced a great=20
counter example.

Another way out is to accept one of these swap operator proposals. Then we=
=20
can do it right with the swap operator from scratch. We completely sidestep=
=20
the swap() backwards compatibility issue and the ADL customization point=20
problem now only is limited to begin(), data(), size(), etc.. These=20
functions are an order of magnitude less dangerous than swap when it comes=
=20
to possibly breaking backwards compatibility.


On Friday, May 5, 2017 at 10:07:37 PM UTC-5, Arthur O'Dwyer wrote:
>
> On Wed, May 3, 2017 at 2:14 AM, Marc Mutz <marc...@kdab.com <javascript:>=
>=20
> wrote:
>
>>
>> While it's true that std::swap is the most-prominent example, it's also=
=20
>> one
>> which really is trivial in many ways. [...] Much more
>> interesting than swap() are those functions which are API enablers:
>>
>> A class template representing angles _needs_ a sin() overload, and up=20
>> pops the
>> question how to provide it: via ADL, even though most people will likely=
=20
>> not
>> write
>>
>>    using std::sin;
>>    return sin(a);
>>
>> ? Or as a specialisation of std::sin() (doen't work) or as an overload o=
f
>> std::sin() (not allowed). Example:=20
>> https://codereview.qt-project.org/191717
>> So, yeah, via ADL, and thus continues the embarrassment...
>>
>> A non-std container should provide a version of LF v2's erase_if(). Even
>> though erase_if is only overloaded on types in namespace std, since it's
>> currently in namespace std::experimental, you still can't say
>>
>>    erase_if(c, p);
>>
>> ie. rely on ADL, but need to have another using declaration:
>>
>>    using std::experimental::erase_if;
>>    erase_if(c, p);
>>
>> This stuff usually gets a laugh from non-C++ experts already.
>> But note how this using declaration will fail to compile when LF v2 is n=
ot
>> supported, requiring adding preprocessor magic around it:
>>
>>  #if defined(_cpp_lib_dunno_exact_name) && \
>>           __cpp_lib_dunno_exact_name >=3D 201411
>>    using std::experimental::erase_if;
>>  #endif
>>    erase_if(c, p);
>>
>> Ok, all of this will be solved when erase_if moves into namespace std=20
>> proper,
>> making this a bad example.
>>
>> Let's look at STL algorithms:
>>
>> A wonky container like QList can actually implement reversing as an=20
>> out-of-
>> line function: https://codereview.qt-project.org/144071 It's not=20
>> far-fetched
>> to want to specialise std::reverse() to call the member function, which=
=20
>> would
>> require overloading std::reverse(). Or providing an ADL version, which,
>> however, requires every use of std::reverse() to say
>>
>>    using std::reverse;
>>    reverse(b, e);
>>
>> Here, we finally reached a case where no-one in the world writes code li=
ke
>> this.
>>
>> As you can see, the issue is not at all restricted to swap(), begin(),=
=20
>> size(),
>> data() and the very few other customisation points that are being=20
>> discussed.
>>
>
> This is a very thoughtful description of a real problem that I had not=20
> been considering, and I'm sorry it seems to have gotten minorly buried in=
=20
> this thread.
>
> I like your examples of std::sin() and std::reverse() as "customization=
=20
> points."  You're correct that I would not propose trying to use=20
> Niebler-style "customization point" lambdas for those.  One takeaway poin=
t=20
> here is that the set of possible customization points in C++ is an open=
=20
> set, not a closed set.
>
> The std::reverse example is particularly interesting to me. Consider this=
=20
> implementation of std::reverse, and then this implementation of std::rota=
te:
>
>     template<class It>
>     void reverse(It first, It last)
>     {
>         while (first !=3D last) {
>             --last;
>             if (first =3D=3D last) break;
>             using std::swap;
>             swap(*first, *last);
>             ++first;
>         }
>     }
>
>     template<class It>
>     It rotate(It a, It mid, It b)
>     {
>         auto result =3D a + (b - mid);
>         std::reverse(a, b);
>         std::reverse(a, result);
>         std::reverse(result, b);
>         return result;
>     }
>
> The implementation of std::reverse goes out of its way to respect the=20
> "customization-point-ness" of swap, but the implementation of std::rotate=
=20
> does *not* go out of its way to respect the "customization-point-ness" of=
=20
> reverse.  So, if your particular data type has a speedy reverse,=20
> std::rotate will be inefficient.
>
> Now, the Standard might reasonably say that this state of affairs is fine=
..=20
> std::rotate isn't supposed to delegate to your speedy reverse; it's not=
=20
> even guaranteed to call std::reverse (and in fact libstdc++ calls somethi=
ng=20
> named __reverse, and libc++ doesn't use swap at all=20
> <https://wandbox.org/permlink/59FAnIX3rWsY5xuw> in most cases).  It's=20
> just supposed to rotate the given range by some unspecified means, and if=
=20
> you want a rotate function that *will* use your fast reverse, you'll just=
=20
> have to write it yourself.  This argument is fine, as far as it goes.
>
> But the Standard Library isn't all libraries. IMHO it would be reasonable=
=20
> for some library designer out there to say, "My numerics library is gener=
ic=20
> enough to work with all numeric datatypes; if it ever calls sin(), or=20
> log(), or max(), or sort(), or any function, it'll do it in a way that=20
> you can customize."  And then that designer will need a solution for how =
to=20
> call *any arbitrary function* while respecting ADL.  C++03 has a solution=
=20
> for that, but it's clunky, and as Matthew Fioravante pointed out, the C++=
03=20
> solution doesn't play well with decltype(swap(a,b)) or=20
> noexcept(noexcept(swap(a,b))).
>
> That is, one might say that the chief failing of the C++03 solution "usin=
g=20
> std::swap; swap(a,b)" is that it has failed to keep up with the syntactic=
=20
> changes in C++11.  If it weren't for that, it would still be *okay*, if=
=20
> never excellent.
>
> my $.02,
> =E2=80=93Arthur
>

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/6d8b6f86-a966-4450-9f9a-373e0a156963%40isocpp.or=
g.

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

<div dir=3D"ltr">One other deficiency of the using std::swap; swap(); idiom=
 is that you lose namespace scoping when invoking your customization points=
..<br><br><br>If I had liba::foo, and libb::foo separate customization point=
s, I cannot use them together in the same block of code without some very c=
lumsy scoping. Error prone and terribly ugly more complex code.<br><br>When=
 I actually call it, I just say swap(x, y). I have an implicit=20
dependency on which swap was pulled in by a preceding using declaration.
 Most of the time its on the preceding line, so its obvious. However if=20
you have a bunch of calls in the code, you&#39;ll want to organize the usin=
g
 declarations and now thats one more thing to track when reading the=20
code.<br><br><br>One compromise would be something like using namespace std=
::literals;<br><br>You might say something like:<br><br>using namespace std=
::custom;<br><br>Other libraries like libfoo can support using namespace fo=
o::custom;<br><br>Then you automatically get swap(), and the others in your=
 global namespace. This makes ADL work at the expense of losing the capabil=
ity of namespace scoping in invoking customization point names. Fundamental=
ly, this is the only way ADL can work. You also still don&#39;t get some of=
 the other examples like reverse() or sin(). It all comes at a cost of this=
 line of boilerplate at the top of your source files and the decision that =
its always ok to have these std symbols in your namespace.<br><br>I don&#39=
;t believe ADL at the callsite is up to the task. We either wrap its defici=
encies away with a standard name like std::swap, adl::swap, or something el=
se. Or somehow design yet another set of core language function calling rul=
es to somehow handle this case. The second option sounds terrifying, especi=
ally with all the complicated rules the language already has.<br><br>Unifie=
d call syntax was shot down. Right or wrong, it actually didn&#39;t solve t=
his problem either. UCS lets me not have to worry about saying swap(x, y) v=
s x.swap(y). It still doesn&#39;t give me an automatic fallback to std::swa=
p() without a using declaration.<br><br>std::swap might be particularly sca=
ry. Howard Hinnant produced a great counter example.<br><br>Another way out=
 is to accept one of these swap operator proposals. Then we can do it right=
 with the swap operator from scratch. We completely sidestep the swap() bac=
kwards compatibility issue and the ADL customization point problem now only=
 is limited to begin(), data(), size(), etc.. These functions are an order =
of magnitude less dangerous than swap when it comes to possibly breaking ba=
ckwards compatibility.<br><br><br>On Friday, May 5, 2017 at 10:07:37 PM UTC=
-5, Arthur O&#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr">On Wed, May 3, 2017 at 2:14 AM, Marc Mutz <span dir=3D"ltr"=
>&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"y2e=
FQo73BAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39=
;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">=
marc...@kdab.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote"><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pa=
dding-left:1ex"><br>
While it&#39;s true that std::swap is the most-prominent example, it&#39;s =
also one<br>
which really is trivial in many ways. [...]=C2=A0Much more<br>
interesting than swap() are those functions which are API enablers:<br>
<br>
A class template representing angles _needs_ a sin() overload, and up pops =
the<br>
question how to provide it: via ADL, even though most people will likely no=
t<br>
write<br>
<br>
=C2=A0 =C2=A0using std::sin;<br>
=C2=A0 =C2=A0return sin(a);<br>
<br>
? Or as a specialisation of std::sin() (doen&#39;t work) or as an overload =
of<br>
std::sin() (not allowed). Example: <a href=3D"https://codereview.qt-project=
..org/191717" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D=
&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fcodereview.qt-project.or=
g%2F191717\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFcQyPRLkCU_C2mYL0CpXTOU2=
HCoQ&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/=
url?q\x3dhttps%3A%2F%2Fcodereview.qt-project.org%2F191717\x26sa\x3dD\x26snt=
z\x3d1\x26usg\x3dAFQjCNFcQyPRLkCU_C2mYL0CpXTOU2HCoQ&#39;;return true;">http=
s://codereview.qt-project.<wbr>org/191717</a><br>
So, yeah, via ADL, and thus continues the embarrassment...<br>
<br>
A non-std container should provide a version of LF v2&#39;s erase_if(). Eve=
n<br>
though erase_if is only overloaded on types in namespace std, since it&#39;=
s<br>
currently in namespace std::experimental, you still can&#39;t say<br>
<br>
=C2=A0 =C2=A0erase_if(c, p);<br>
<br>
ie. rely on ADL, but need to have another using declaration:<br>
<br>
=C2=A0 =C2=A0using std::experimental::erase_if;<br>
=C2=A0 =C2=A0erase_if(c, p);<br>
<br>
This stuff usually gets a laugh from non-C++ experts already.<br>
But note how this using declaration will fail to compile when LF v2 is not<=
br>
supported, requiring adding preprocessor magic around it:<br>
<br>
=C2=A0#if defined(_cpp_lib_dunno_exact_<wbr>name) &amp;&amp; \<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 __cpp_lib_dunno_exact_name &gt;=3D 20141=
1<br>
=C2=A0 =C2=A0using std::experimental::erase_if;<br>
=C2=A0#endif<br>
=C2=A0 =C2=A0erase_if(c, p);<br>
<br>
Ok, all of this will be solved when erase_if moves into namespace std prope=
r,<br>
making this a bad example.<br>
<br>
Let&#39;s look at STL algorithms:<br>
<br>
A wonky container like QList can actually implement reversing as an out-of-=
<br>
line function: <a href=3D"https://codereview.qt-project.org/144071" rel=3D"=
nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;https://www.goo=
gle.com/url?q\x3dhttps%3A%2F%2Fcodereview.qt-project.org%2F144071\x26sa\x3d=
D\x26sntz\x3d1\x26usg\x3dAFQjCNG9duC-5Kr-kRxSjz0Ax3ucvyg2nQ&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F=
%2Fcodereview.qt-project.org%2F144071\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQ=
jCNG9duC-5Kr-kRxSjz0Ax3ucvyg2nQ&#39;;return true;">https://codereview.qt-pr=
oject.<wbr>org/144071</a> It&#39;s not far-fetched<br>
to want to specialise std::reverse() to call the member function, which wou=
ld<br>
require overloading std::reverse(). Or providing an ADL version, which,<br>
however, requires every use of std::reverse() to say<br>
<br>
=C2=A0 =C2=A0using std::reverse;<br>
=C2=A0 =C2=A0reverse(b, e);<br>
<br>
Here, we finally reached a case where no-one in the world writes code like<=
br>
this.<br>
<br>
As you can see, the issue is not at all restricted to swap(), begin(), size=
(),<br>
data() and the very few other customisation points that are being discussed=
..<br></blockquote><div><br></div><div>This is a very thoughtful description=
 of a real problem that I had not been considering, and I&#39;m sorry it se=
ems to have gotten minorly buried in this thread.</div><div><br></div><div>=
I like your examples of std::sin() and std::reverse() as &quot;customizatio=
n points.&quot; =C2=A0You&#39;re correct that I would not propose trying to=
 use Niebler-style &quot;customization point&quot; lambdas for those.=C2=A0=
 One takeaway point here is that the set of possible customization points i=
n C++ is an open set, not a closed set.</div><div><br></div><div>The std::r=
everse example is particularly interesting to me. Consider this implementat=
ion of std::reverse, and then this implementation of std::rotate:</div><div=
><br></div><div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 temp=
late&lt;class It&gt;</font></div><div><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 void reverse(It first, It last)</font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></div><div><font face=3D"mo=
nospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 while (first !=3D last) {</=
font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 --last;</font></div><div><font face=3D"monospace, mono=
space">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (first =3D=3D last) bre=
ak;</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 using std::swap;</font></div><div><font face=3D"mo=
nospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 swap(*first, =
*last);</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ++first;</font></div><div><font face=3D"monospa=
ce, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</font></div><div><font face=3D=
"monospace, monospace">=C2=A0 =C2=A0 }</font></div></div><div><font face=3D=
"monospace, monospace"><br></font></div><div><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 template&lt;class It&gt;</font></div><div><font face=3D=
"monospace, monospace">=C2=A0 =C2=A0 It rotate(It a, It mid, It b)</font></=
div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 {</font></div><d=
iv><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto res=
ult =3D a + (b - mid);</font></div><div><font face=3D"monospace, monospace"=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::reverse(a, b);<br></font></div><div><font=
 face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::reverse(a, =
result);<br></font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 std::reverse(result, b);</font></div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return result;<br></f=
ont></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 }</font></=
div><div><br></div><div>The implementation of std::reverse goes out of its =
way to respect the &quot;customization-point-ness&quot; of <font face=3D"mo=
nospace, monospace">swap</font>, but the implementation of std::rotate does=
 <i>not</i> go out of its way to respect the &quot;customization-point-ness=
&quot; of <font face=3D"monospace, monospace">reverse</font>.=C2=A0 So, if =
your particular data type has a speedy <font face=3D"monospace, monospace">=
reverse</font>, std::rotate will be inefficient.</div><div><br></div><div>N=
ow, the Standard might reasonably say that this state of affairs is fine. s=
td::rotate isn&#39;t supposed to delegate to your speedy reverse; it&#39;s =
not even guaranteed to call std::reverse (and in fact libstdc++ calls somet=
hing named <font face=3D"monospace, monospace">__reverse</font>, and libc++=
 <a href=3D"https://wandbox.org/permlink/59FAnIX3rWsY5xuw" target=3D"_blank=
" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.com/u=
rl?q\x3dhttps%3A%2F%2Fwandbox.org%2Fpermlink%2F59FAnIX3rWsY5xuw\x26sa\x3dD\=
x26sntz\x3d1\x26usg\x3dAFQjCNHgyMRrWdFlOSBuAjjE_EkhrL-LBw&#39;;return true;=
" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2=
Fwandbox.org%2Fpermlink%2F59FAnIX3rWsY5xuw\x26sa\x3dD\x26sntz\x3d1\x26usg\x=
3dAFQjCNHgyMRrWdFlOSBuAjjE_EkhrL-LBw&#39;;return true;">doesn&#39;t use <fo=
nt face=3D"monospace, monospace">swap</font> at all</a> in most cases).=C2=
=A0 It&#39;s just supposed to rotate the given range by some unspecified me=
ans, and if you want a rotate function that <i>will</i> use your fast <font=
 face=3D"monospace, monospace">reverse</font>, you&#39;ll just have to writ=
e it yourself.=C2=A0 This argument is fine, as far as it goes.</div><div><b=
r></div><div>But the Standard Library isn&#39;t all libraries. IMHO it woul=
d be reasonable for some library designer out there to say, &quot;My numeri=
cs library is generic enough to work with all numeric datatypes; if it ever=
 calls <font face=3D"monospace, monospace">sin()</font>, or <font face=3D"m=
onospace, monospace">log()</font>, or <font face=3D"monospace, monospace">m=
ax()</font>, or <font face=3D"monospace, monospace">sort()</font>, or any f=
unction, it&#39;ll do it in a way that you can customize.&quot; =C2=A0And t=
hen that designer will need a solution for how to call <i>any arbitrary fun=
ction</i> while respecting ADL.=C2=A0 C++03 has a solution for that, but it=
&#39;s clunky, and as Matthew Fioravante pointed out, the C++03 solution do=
esn&#39;t play well with decltype(swap(a,b)) or noexcept(noexcept(swap(a,b)=
)).</div><div><br></div><div>That is, one might say that the chief failing =
of the C++03 solution &quot;using std::swap; swap(a,b)&quot; is that it has=
 failed to keep up with the syntactic changes in C++11.=C2=A0 If it weren&#=
39;t for that, it would still be <i>okay</i>, if never excellent.</div><div=
><br></div><div>my $.02,</div><div>=E2=80=93Arthur</div></div></div></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/6d8b6f86-a966-4450-9f9a-373e0a156963%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6d8b6f86-a966-4450-9f9a-373e0a156963=
%40isocpp.org</a>.<br />

------=_Part_276_188349057.1494053540455--

------=_Part_275_118754594.1494053540454--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 6 May 2017 15:14:21 +0200
Raw View
Le 05/05/2017 =C3=A0 19:54, Matthew Fioravante a =C3=A9crit :
> The swap(), begin(), end(), size(), etc... is an embarrassment.
>
> - Its ugly to adding these using declarations.
> - Its crazy error prone. Too easy to forget a using declaration.
> - These functions cannot be called in single expression contexts like=20
> decltype().
>
> Why can't we just make std::swap() do all of the magic dispatching=20
> internally? Then the convention is people always call std::swap(),=20
> std::begin(), etc..
Would you agree to call them giving the specific concepts we are=20
customizing as e.g.

std::swappable::swap
std::range::begin
std::range::end
.....

?

The new interface should, of course,  ensure that it calls your=20
customization point.

This avoids the cyclic issue HH reported.

Vicente

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/657cfbb3-241e-e84e-5d46-01ef63526873%40wanadoo.f=
r.

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 6 May 2017 15:41:53 +0200
Raw View
Le 03/05/2017 =C3=A0 11:14, Marc Mutz a =C3=A9crit :
> On Wednesday 03 May 2017 10:13:49 olaf@join.cc wrote:
>> Op woensdag 3 mei 2017 04:08:12 UTC+2 schreef Arthur O'Dwyer:
>>> IMHO, the most elegant solution (basically Eric Niebler's proposal) wou=
ld
>>> involve MASSIVE breakage of old code and is thus suited only for "std2"=
..
>> Wouldn't it work as std::swap2?
> Sorry for highjacking Olaf's reply. This is not about Olaf's answer.
>
> While it's true that std::swap is the most-prominent example, it's also o=
ne
> which really is trivial in many ways. Few are the types which these days =
of
> move semantics _need_ a custom swap(). Unless you still need to support C=
++98
> compilers, it's merely a questionable optimisation technique (the best yo=
u can
> do it member-wise swapping, which apart from a little less memory used, i=
s
> hardly orders of magnitude faster than what the triple-move default
> implementation does).
>
> No, forget swap. The Swap Problem is not (just) about swap. Much more
> interesting than swap() are those functions which are API enablers:
Agreed.
> A class template representing angles _needs_ a sin() overload, and up pop=
s the
> question how to provide it: via ADL, even though most people will likely =
not
> write
>
>     using std::sin;
>     return sin(a);
>
> ? Or as a specialisation of std::sin() (doen't work) or as an overload of
> std::sin() (not allowed). Example: https://codereview.qt-project.org/1917=
17
> So, yeah, via ADL, and thus continues the embarrassment...
>
>
> A non-std container should provide a version of LF v2's erase_if(). Even
> though erase_if is only overloaded on types in namespace std, since it's
> currently in namespace std::experimental, you still can't say
>
>     erase_if(c, p);
>
> ie. rely on ADL, but need to have another using declaration:
>
>     using std::experimental::erase_if;
>     erase_if(c, p);
Would you accept to call

     std::container::erase_if(c,p);

or something like that?
> This stuff usually gets a laugh from non-C++ experts already.
> But note how this using declaration will fail to compile when LF v2 is no=
t
> supported, requiring adding preprocessor magic around it:
>
>   #if defined(_cpp_lib_dunno_exact_name) && \
>            __cpp_lib_dunno_exact_name >=3D 201411
>     using std::experimental::erase_if;
>   #endif
>     erase_if(c, p);
This is another issue.
> Ok, all of this will be solved when erase_if moves into namespace std pro=
per,
> making this a bad example.
>
> Let's look at STL algorithms:
>
> A wonky container like QList can actually implement reversing as an out-o=
f-
> line function: https://codereview.qt-project.org/144071 It's not far-fetc=
hed
> to want to specialise std::reverse() to call the member function, which w=
ould
> require overloading std::reverse(). Or providing an ADL version, which,
> however, requires every use of std::reverse() to say
>
>     using std::reverse;
>     reverse(b, e);
AFAIK, reverse is not a customization point. We will need a proposal for=20
that ;-)
> Here, we finally reached a case where no-one in the world writes code lik=
e
> this.
>
> As you can see, the issue is not at all restricted to swap(), begin(), si=
ze(),
> data() and the very few other customisation points that are being discuss=
ed.
> Do you seriously want to make a std::sin2, std::reverse2, ... for every s=
ingle
> function in namespace std?
I would prefer to associate them to the concept the customization is=20
associated to.
>
> So I wonder: What's the rationale for not allowing adding overloads under=
 the
> same conditions as allowing partial specialisations of class templates? I=
f a
> user messes up, how is it a worse mess with overloads than with class tem=
plate
> specialisations? What's so scary about it that you'd rather discuss _new
> language features_ to enable customisation than to allow it by what C++
> provides for ages, and even novices quickly grasp: overloads?
>
 From Range TS customization point N4381 we have athe following goals

"The goals of customization point design are as follows (for some=20
hypothetical future customization point cust):

     Code that calls cust either qualified as std::cust(a); or=20
unqualified as using std::cust; cust(a); should behave identically. In=20
particular, it should find any user-defined overloads in the argument=E2=80=
=99s=20
associated namespace(s).
     Code that calls cust as using std::cust; cust(a); should not bypass=20
any constraints defined on std::cust.
     Calls to the customization point should be optimally efficient by=20
any reasonably modern compiler.
     The solution should not introduce any potential violations of the=20
one-definition rule or excessive executable size bloat."

I don't agree with all this. I don't believe that calling cust

using std::cust;
cust(a);

is a must work, even if this is the way we do now.


I will replace the goals by

     Code that calls std::a_concept::cust(a); should end by calling the=20
user-defined customized point.
     User can not call cust by ADL, that is using std::a_concept::cust;=20
cust(a) should be incorrect.
     Calls to the customization point should be optimally efficient by=20
any reasonably modern compiler.
     The solution should not introduce any potential violations of the=20
one-definition rule or excessive executable size bloat.


Of course we cannot prevent the user to call cust(a) directly, except if=20
we add some feature that prevents that ([N1691] Explicit Namespaces).


So to answer to your comment.we want a single point that is able to=20
ensure some constraints (Method Pattern) and call to the specific=20
customized part. Adding overload in std will not satisfy these goal. I=20
believe the goals are desirable.


Vicente


--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/5080f7be-9182-a364-7d1f-8fdf9c9531cf%40wanadoo.f=
r.

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 6 May 2017 15:58:04 +0200
Raw View
This is a multi-part message in MIME format.
--------------318D72D9FF4C6722A579CE7B
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 05/05/2017 =C3=A0 22:40, Matthew Fioravante a =C3=A9crit :
>
>
> On Friday, May 5, 2017 at 2:58:13 PM UTC-5, Nicol Bolas wrote:
>
>     On Friday, May 5, 2017 at 2:29:03 PM UTC-4, Matthew Fioravante wrote:
>
>         On Friday, May 5, 2017 at 1:03:10 PM UTC-5, Nicol Bolas wrote:
>
>             Because it would be a backwards-incompatible change.
>
>
>         C++ has broken backwards compatibility before. Right now if
>         you call std::swap() on your object, unless its in std you'll
>         get a default move based swap operation. Suppose that was all
>         of the sudden silently changed to actually call your type's
>         swap() operation if it has one. How bad would that be? How
>         much code would it break?
>
>         I consider swap() special in the same vein as move and copy.
>         We've added rules to change how those are called/elided in the
>         past knowing it could break code. If you write a swap() its
>         suppose to do swapping, if it does something else you get what
>         you deserve. "Optimizing" std::swap() to call your types
>         custom swap if it has one does not sound like a bad thing to me.
>
>         The fact that essential library primitives like swap() and
>         begin() require expert level knowledge to use correctly is a
>         complete and utter failure.*Really, its just ****ing stupid.*
>         ADL is not the proper tool for this. I'd argue ADL is only
>         really useful for operator overloading. Unless you put swap(),
>         begin(), etc.. to the global :: namespace, ADL will never
>         work. That's a non-starter too as third party libraries
>         wanting to define "customization points" such as begin()
>         certainly cannot just put stuff in the global namespace.
>
>         With have virtual functions for runtime dispatch, and this
>         broken crap interface for compile time dispatch. This is a
>         serious bug that needs to be fixed.
>
>
>     I don't disagree on the importance of customization points. I
>     don't disagree with the need to have them work.
>
>     That alone however /cannot/ justify doing it in a
>     backwards-incompatible way.
>
>             It also wouldn't help users create similar interfaces that
>             have similar behavior.
>
>
>         That's a secondary concern.
>
>
>     I strongly disagree. It's like saying that we need to have ranges
>     in the standard library, but it's a secondary concern to provide
>     tools to help people write standard library compatible ranges.
>     What good is it to have standard idioms if writing
>     idiom-compatible constructs is so complex/arcane that users can
>     not reasonably be expected to define them on their own?
>
>     Writing a standard library compatible range should not be hard.
>     Writing a standard library compatible customization point should
>     also not be hard. This should be a primary concern of any solution
>     to this problem. Once we standardize the concept of "customization
>     point", people will and should want to do it in a way that is
>     compatible with the standard library. If we make that simple, then
>     we allow them to do so.
>
>     If we make the idiom complex or arcane, all we do is create dozens
>     of headaches down the road.
>
>
> So then add the tools to help create these things. I never said we=20
> shouldn't. However when making engineering trade-offs in the=20
> interface, its better to design something optimized for the common=20
> case (calling a customization point) over the rare case (writing the=20
> default dispatch driver for a customization point library).
I agree that calling the customization must be as simple as possible.=20
However customizing shouldn't be too complex neither. These are simple=20
things.
>
>         If I want to write foo::fooify() customization point in
>         libfoo, I can lookup a tutorial to get all of the dispatching
>         correct. I only need to do this once for all of the thousands
>         if not millions of times my users will just need to say
>         foo::fooify(fooable_thing);. If I'm writing my own
>         customization points, I'm already an expert C++ developer.
>
>
>     That kind of thinking is what gets us `std::enable_if`. "If I want
>     to do some SFINAE-style stuff, then I'm already an expert C++
>     developer".
>
>
> I don't agree with this comparison. Hacking overload resolution with=20
> enable_if is something we do way more often than creating new=20
> customization points.
>
> The use case here is not "I want to do SFINAE stuff" (expert only=20
> implementation specific gibberish), its "I want write a math function=20
> which only operates on any kind of `real number' type" (basic core idea).
Right. We want to associate a function to a RealNumber type. We need the=20
minimal set of functions that define this RealNumber concept. I call=20
those customization points. We could as well define algorithms that have=20
a default implementation that could become customization points as the=20
user can do better. So we need customization points with default=20
behavior. Maybe we have a very good implementation for some more=20
constrained RealNumber, and I would expect we are able to customize once=20
for all to all the types that satisfy the additional constraints.
>
> Before we go ahead and add language features, ugly less invasive=20
> things like this are a good start to get experience. Everybody hates=20
> enable_if for good reason but before concepts that's all we had to=20
> solve a real need. The standard library 10 years from now is not going=20
> to be any worse off for the existence of an old enable_if template now=20
> collecting dust unused in the new conceptified regime.
>
>
>
>     Utter nonsense. By adding appropriate things to the language, we
>     give novices the power to do the things that experts do. We take
>     arcane idioms and bring them to the masses.
>
>     When we get concepts, you'll see the number of people using SFINAE
>     increase dramatically. Why? Because it makes it a real part of the
>     language, not some arcane hack. Users have needs that SFINAE could
>     solve, but they don't use it because it's needlessly difficult and
>     over-complicated. The same goes here. Creating a customization
>     points should not be something that requires being an expert C++
>     developer. Users want to be able to do these things, but as of
>     yet, there is no good, simple solution for it.
>
>         Furthermore, we could also consider adding helper utilities
>         for this in the standard library, even if they have to be macros.
>
>
>     Yes, don't bother with a nice, neat language feature. It's much
>     better to do this sort of stuff as a macro.
>
>
> Ok so invent a new language feature then. I'd be plenty happy with=20
> that too.
It seems it is no so simple :)
> I don't think you can do this with templates as they are currently=20
> which is why a macro was suggested. A language feature would need to=20
> be more general purpose. I'm not sure it would ever fly to create a=20
> core language feature solely for the purpose of writing customization=20
> points.
>
> I'm not at all married to using std::swap() to solve the problem. If=20
> someone has a better solution I'll be the first one to jump on board.=20
> Whatever the solution is, this using std::swap; swap(); nonsense has=20
> got to go.
STD2 with Range TS, goes already in this direction. std2::swap will do=20
what you want. We are lucky we will use a new namespace.
>
> It also needs to be solved not just for swap(), but for all=20
> customization points including begin(), end(), cbegin(), cend(),=20
> rbegin(), rend(), size(), data(), etc..
This is also the case for these functions.
> As an added bonus, this should also mean we can all stop doing the=20
> brainless and bug friendly work of writing cbegin(), cend(), rbegin(),=20
> rend(), rbegin() const, rend() const, crbegin(), crend() for all of=20
> our custom container classes. Instead just relying on the default=20
> adapters generated by the std:: default versions adapting begin(),=20
> begin() const, end(), and end() const.
>
Yes, see above about defaulted customization points.
>
>
> Lets not also forget we have concepts on the way. Once concepts are=20
> out in the wild this ADL problem is going to become a much bigger=20
> issue fast. Its was one of the main use cases driving unified function=20
> call syntax. Do we want to wait until the bug reports and complaints=20
> after concepts or should we not try to attack this issue now?
I believe the problem should be solved asap. The main problem will be on=20
finding a consensual solution.
>
> If I want to make an Iterable concept, I'd like to just say that it=20
> begin(x) and end(x) are valid expressions which return Iterator=20
> concepts. Why the hell do I need to deal with these using declaration=20
> gymnastics? How do I carefully add them without polluting the entire=20
> scope? I still haven't review the concepts proposal in detail. Can I=20
> even put a using declaration inside a concept expression?
This makes customization points pseudo-keywords. We have namespace to=20
localize names. Why not start using them?

Vicente

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ca0803ca-1f88-4f88-5f39-77602741b758%40wanadoo.f=
r.

--------------318D72D9FF4C6722A579CE7B
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 05/05/2017 =C3=A0 22:40, Matthew
      Fioravante a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:68381f91-4180-429c-8f52-de00bd725c60@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr"><br>
        <br>
        On Friday, May 5, 2017 at 2:58:13 PM UTC-5, Nicol Bolas 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">On Friday, May 5, 2017 at 2:29:03 PM UTC-4,
            Matthew Fioravante 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">On Friday, May 5, 2017 at 1:03:10 PM UTC-5,
                Nicol Bolas 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>Because it would be a backwards-incompatible
                      change.</div>
                  </div>
                </blockquote>
                <div><br>
                </div>
                <div>C++ has broken backwards compatibility before.
                  Right now if you call std::swap() on your object,
                  unless its in std you'll get a default move based swap
                  operation. Suppose that was all of the sudden silently
                  changed to actually call your type's swap() operation
                  if it has one. How bad would that be? How much code
                  would it break?</div>
                <div><br>
                </div>
                <div>I consider swap() special in the same vein as move
                  and copy. We've added rules to change how those are
                  called/elided in the past knowing it could break code.
                  If you write a swap() its suppose to do swapping, if
                  it does something else you get what you deserve.
                  "Optimizing" std::swap() to call your types custom
                  swap if it has one does not sound like a bad thing to
                  me.</div>
                <div><br>
                </div>
                <div>The fact that essential library primitives like
                  swap() and begin() require expert level knowledge to
                  use correctly is a complete and utter failure.<b>
                    Really, its just ****ing stupid.</b> ADL is not the
                  proper tool for this. I'd argue ADL is only really
                  useful for operator overloading. Unless you put
                  swap(), begin(), etc.. to the global :: namespace, ADL
                  will never work. That's a non-starter too as third
                  party libraries wanting to define "customization
                  points" such as begin() certainly cannot just put
                  stuff in the global namespace.</div>
                <div><br>
                </div>
                <div>With have virtual functions for runtime dispatch,
                  and this broken crap interface for compile time
                  dispatch. This is a serious bug that needs to be
                  fixed.</div>
              </div>
            </blockquote>
            <div><br>
              I don't disagree on the importance of customization
              points. I don't disagree with the need to have them work.<br>
              <br>
              That alone however <i>cannot</i> justify doing it in a
              backwards-incompatible way.<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">
                <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>It also wouldn't help users create similar
                      interfaces that have similar behavior. <br>
                    </div>
                  </div>
                </blockquote>
                <div><br>
                </div>
                <div>That's a secondary concern.</div>
              </div>
            </blockquote>
            <div><br>
              I strongly disagree. It's like saying that we need to have
              ranges in the standard library, but it's a secondary
              concern to provide tools to help people write standard
              library compatible ranges. What good is it to have
              standard idioms if writing idiom-compatible constructs is
              so complex/arcane that users can not reasonably be
              expected to define them on their own?<br>
              <br>
              Writing a standard library compatible range should not be
              hard. Writing a standard library compatible customization
              point should also not be hard. This should be a primary
              concern of any solution to this problem. Once we
              standardize the concept of "customization point", people
              will and should want to do it in a way that is compatible
              with the standard library. If we make that simple, then we
              allow them to do so.<br>
              <br>
              If we make the idiom complex or arcane, all we do is
              create dozens of headaches down the road.<br>
            </div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>So then add the tools to help create these things. I never
          said we shouldn't. However when making engineering trade-offs
          in the interface, its better to design something optimized for
          the common case (calling a customization point) over the rare
          case (writing the default dispatch driver for a customization
          point library).</div>
      </div>
    </blockquote>
    I agree that calling the customization must be as simple as
    possible. However customizing shouldn't be too complex neither.
    These are simple things.<br>
    <blockquote
      cite=3D"mid:68381f91-4180-429c-8f52-de00bd725c60@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>=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>=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 I want to write foo::fooify() customization
                  point in libfoo, I can lookup a tutorial to get all of
                  the dispatching correct. I only need to do this once
                  for all of the thousands if not millions of times my
                  users will just need to say
                  foo::fooify(fooable_thing);. If I'm writing my own
                  customization points, I'm already an expert C++
                  developer.</div>
              </div>
            </blockquote>
            <div><br>
              That kind of thinking is what gets us `std::enable_if`.
              "If I want to do some SFINAE-style stuff, then I'm already
              an expert C++ developer".<br>
            </div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>I don't agree with this comparison. Hacking overload
          resolution with enable_if is something we do way more often
          than creating new customization points.</div>
        <div><br>
        </div>
        <div>The use case here is not "I want to do SFINAE stuff"
          (expert only implementation specific gibberish), its "I want
          write a math function which only operates on any kind of `real
          number' type" (basic core idea).</div>
      </div>
    </blockquote>
    Right. We want to associate a function to a RealNumber type. We need
    the minimal set of functions that define this RealNumber concept. I
    call those customization points. We could as well define algorithms
    that have a default implementation that could become customization
    points as the user can do better. So we need customization points
    with default behavior. Maybe we have a very good implementation for
    some more constrained RealNumber, and I would expect we are able to
    customize once for all to all the types that satisfy the additional
    constraints.<br>
    <blockquote
      cite=3D"mid:68381f91-4180-429c-8f52-de00bd725c60@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
          Before we go ahead and add language features, ugly less
          invasive things like this are a good start to get experience.
          Everybody hates enable_if for good reason but before concepts
          that's all we had to solve a real need. The standard library
          10 years from now is not going to be any worse off for the
          existence of an old enable_if template now collecting dust
          unused in the new conceptified regime.</div>
        <div><br>
        </div>
        <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><br>
              Utter nonsense. By adding appropriate things to the
              language, we give novices the power to do the things that
              experts do. We take arcane idioms and bring them to the
              masses.<br>
              <br>
              When we get concepts, you'll see the number of people
              using SFINAE increase dramatically. Why? Because it makes
              it a real part of the language, not some arcane hack.
              Users have needs that SFINAE could solve, but they don't
              use it because it's needlessly difficult and
              over-complicated. The same goes here. Creating a
              customization points should not be something that requires
              being an expert C++ developer. Users want to be able to do
              these things, but as of yet, there is no good, simple
              solution for it.<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>Furthermore, we could also consider adding helper
                  utilities for this in the standard library, even if
                  they have to be macros. <br>
                </div>
              </div>
            </blockquote>
            <div><br>
              Yes, don't bother with a nice, neat language feature. It's
              much better to do this sort of stuff as a macro. <br>
            </div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>Ok so invent a new language feature then. I'd be plenty
          happy with that too. </div>
      </div>
    </blockquote>
    It seems it is no so simple :)<br>
    <blockquote
      cite=3D"mid:68381f91-4180-429c-8f52-de00bd725c60@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>I don't think you can do this with templates as they are
          currently which is why a macro was suggested. A language
          feature would need to be more general purpose. I'm not sure it
          would ever fly to create a core language feature solely for
          the purpose of writing customization points.</div>
        <div><br>
        </div>
        <div>I'm not at all married to using std::swap() to solve the
          problem. If someone has a better solution I'll be the first
          one to jump on board. Whatever the solution is, this using
          std::swap; swap(); nonsense has got to go.</div>
      </div>
    </blockquote>
    STD2 with Range TS, goes already in this direction. std2::swap will
    do what you want. We are lucky we will use a new namespace.<br>
    <blockquote
      cite=3D"mid:68381f91-4180-429c-8f52-de00bd725c60@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <div>It also needs to be solved not just for swap(), but for all
          customization points including begin(), end(), cbegin(),
          cend(), rbegin(), rend(), size(), data(), etc.. </div>
      </div>
    </blockquote>
    This is also the case for these functions.<br>
    <blockquote
      cite=3D"mid:68381f91-4180-429c-8f52-de00bd725c60@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div>As an added bonus, this should also mean we can all stop
          doing the brainless and bug friendly work of writing cbegin(),
          cend(), rbegin(), rend(), rbegin() const, rend() const,
          crbegin(), crend() for all of our custom container classes.
          Instead just relying on the default adapters generated by the
          std:: default versions adapting begin(), begin() const, end(),
          and end() const.</div>
        <div><br>
        </div>
      </div>
    </blockquote>
    Yes, see above about defaulted customization points.<br>
    <blockquote
      cite=3D"mid:68381f91-4180-429c-8f52-de00bd725c60@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <div><br>
        </div>
        Lets not also forget we have concepts on the way. Once concepts
        are out in the wild this ADL problem is going to become a much
        bigger issue fast. Its was one of the main use cases driving
        unified function call syntax. Do we want to wait until the bug
        reports and complaints after concepts or should we not try to
        attack this issue now?</div>
    </blockquote>
    I believe the problem should be solved asap. The main problem will
    be on finding a consensual solution.<br>
    <blockquote
      cite=3D"mid:68381f91-4180-429c-8f52-de00bd725c60@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <div>If I want to make an Iterable concept, I'd like to just say
          that it begin(x) and end(x) are valid expressions which return
          Iterator concepts. Why the hell do I need to deal with these
          using declaration gymnastics? How do I carefully add them
          without polluting the entire scope? I still haven't review the
          concepts proposal in detail. Can I even put a using
          declaration inside a concept expression?</div>
      </div>
    </blockquote>
    This makes customization points pseudo-keywords. We have namespace
    to localize names. Why not start using them?<br>
    <br>
    Vicente<br>
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ca0803ca-1f88-4f88-5f39-77602741b758%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ca0803ca-1f88-4f88-5f39-77602741b758=
%40wanadoo.fr</a>.<br />

--------------318D72D9FF4C6722A579CE7B--

.


Author: Marc Mutz <marc.mutz@kdab.com>
Date: Thu, 11 May 2017 11:40:05 +0200
Raw View
On Saturday 06 May 2017 15:41:53 Vicente J. Botet Escriba wrote:
> So to answer to your comment.we want a single point that is able to
> ensure some constraints (Method Pattern) and call to the specific
> customized part. Adding overload in std will not satisfy these goal. I
> believe the goals are desirable.

You are already allowed to "customise" a) every std class template (by full or
partial specialisation, which needs to mention a user type), b) every std
function template (by full specialisation, which needs to mention a user
type). And there's no central dispatch to enforce constraints there, either
(and $DEITY forbid someone starts to specialise std::allocator, or
std::is_pod, ...).

I can already specialise std::reverse for any concrete instantiation of QList,
by full specialisation. The embarrassment is that I can't do this for the
QList template itself (ie. all instantations of it).

So, from my POV of developer-in-the-trenches all that talk about customisation
points, associcated with concepts, is just hot air. The issue is why overloads
of std function (s|templates), which are the moral equivalent of partial class
template specialisation, are not allowed, and why some complex years-in-the-
future mythical language feature is needed, to artifically constrain something
that's already unconstrained.

Thanks,
Marc

--
Marc Mutz <marc.mutz@kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts

.


Author: Marc Mutz <marc.mutz@kdab.com>
Date: Thu, 11 May 2017 11:57:42 +0200
Raw View
On Friday 05 May 2017 21:49:30 Nicol Bolas wrote:
> > Having a function in std:: calling things in your namespace isn't as
> > clean  as looking up the function in the associated namespaces.
>
> The idea is that `std::swap` would call the `swap` in your namespace via
> an  ADL call. But as a specific overload of the non-ADL
> `std::swap`  function.

The idea is to allow users to overload std::swap, in namespace std (where
'swap' stands for every std function), provided the arguments mention user-
defined types.

As I wrote below in this thread, every std template is already a customisation
point. And used as such ever since Effective C++ came out, and that means
probably even earlier).

The embarrassement is not that I cannot specialise std::swap for my own types
(I can), the embarrassment is that I can't do it for my own class _templates_
(because of no partial function specialisation, this would need to overload
and this is forbidden).

I'd be fine if C++20 allowed to overload functions in namespace std, since as
soon as that is voted in, the present UB effectively becomes allowed (since no
implementation checks for it, anyway), and I can move my ADL swaps into
namespace std. This will not break users of the using-swap idiom. It will
break users that use unqualified swap() without using std::swap, but those
deserve to be broken.

Thanks,
Marc

--
Marc Mutz <marc.mutz@kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 11 May 2017 09:06:41 -0700 (PDT)
Raw View
------=_Part_295_1970201244.1494518801412
Content-Type: multipart/alternative;
 boundary="----=_Part_296_1173860143.1494518801412"

------=_Part_296_1173860143.1494518801412
Content-Type: text/plain; charset="UTF-8"

On Thursday, May 11, 2017 at 5:41:20 AM UTC-4, Marc Mutz wrote:
>
> On Saturday 06 May 2017 15:41:53 Vicente J. Botet Escriba wrote:
> > So to answer to your comment.we want a single point that is able to
> > ensure some constraints (Method Pattern) and call to the specific
> > customized part. Adding overload in std will not satisfy these goal. I
> > believe the goals are desirable.
>
> You are already allowed to "customise" a) every std class template (by
> full or
> partial specialisation, which needs to mention a user type), b) every std
> function template (by full specialisation, which needs to mention a user
> type). And there's no central dispatch to enforce constraints there,
> either
> (and $DEITY forbid someone starts to specialise std::allocator, or
> std::is_pod, ...).
>

Not everyone agrees that specialization should be allowed for function
templates either. P0551 (PDF)
<http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0551r0.pdf> makes
the case that this should be removed.

I can already specialise std::reverse for any concrete instantiation of
> QList,
> by full specialisation. The embarrassment is that I can't do this for the
> QList template itself (ie. all instantations of it).
>
> So, from my POV of developer-in-the-trenches all that talk about
> customisation
> points, associcated with concepts, is just hot air.


But that's not the general POV of "developer-in-the-trenches". That's the
POV of *your* development habits. Other developers don't necessarily do
that.

The issue is why overloads
> of std function (s|templates), which are the moral equivalent of partial
> class
> template specialisation, are not allowed, and why some complex
> years-in-the-
> future mythical language feature is needed, to artifically constrain
> something
> that's already unconstrained.
>

But you have to write these overloads. The whole point of customization
points is that it standardizes the interface *without* you being forced to
do something special. The `swap` customization point allows you to write
member `swap` or ADL `swap`, whichever is most appropriate for your type.
Your way requires writing member `swap` *and* overloading `std::swap`.

How is that an improvement? Oh sure, its easier on the *caller*, but it's
harder on the *writer*.

With a proper language feature, we can make it easier on everyone.

--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e919ad53-9ba7-4789-b514-e17fcdf04f54%40isocpp.org.

------=_Part_296_1173860143.1494518801412
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, May 11, 2017 at 5:41:20 AM UTC-4, Marc Mutz w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">On Saturday 06 May 2017 1=
5:41:53 Vicente J. Botet Escriba wrote:
<br>&gt; So to answer to your comment.we want a single point that is able t=
o=20
<br>&gt; ensure some constraints (Method Pattern) and call to the specific=
=20
<br>&gt; customized part. Adding overload in std will not satisfy these goa=
l. I=20
<br>&gt; believe the goals are desirable.
<br>
<br>You are already allowed to &quot;customise&quot; a) every std class tem=
plate (by full or=20
<br>partial specialisation, which needs to mention a user type), b) every s=
td=20
<br>function template (by full specialisation, which needs to mention a use=
r=20
<br>type). And there&#39;s no central dispatch to enforce constraints there=
, either=20
<br>(and $DEITY forbid someone starts to specialise std::allocator, or=20
<br>std::is_pod, ...).<br></blockquote><div><br>Not everyone agrees that sp=
ecialization should be allowed for function templates either. <a href=3D"ht=
tp://www.open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0551r0.pdf">P0551 (P=
DF)</a> makes the case that this should be removed.<br><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;">
I can already specialise std::reverse for any concrete instantiation of QLi=
st,=20
<br>by full specialisation. The embarrassment is that I can&#39;t do this f=
or the=20
<br>QList template itself (ie. all instantations of it).
<br>
<br>So, from my POV of developer-in-the-trenches all that talk about custom=
isation=20
<br>points, associcated with concepts, is just hot air.</blockquote><div><b=
r>But that&#39;s not the general POV of &quot;developer-in-the-trenches&quo=
t;. That&#39;s the POV of <i>your</i> development habits. Other developers =
don&#39;t necessarily do that.<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">The issue is why overloads=20
<br>of std function (s|templates), which are the moral equivalent of partia=
l class=20
<br>template specialisation, are not allowed, and why some complex years-in=
-the-
<br>future mythical language feature is needed, to artifically constrain so=
mething=20
<br>that&#39;s already unconstrained.<br></blockquote><div><br>But you have=
 to write these overloads. The whole point of customization points is that =
it standardizes the interface <i>without</i> you being forced to do somethi=
ng special. The `swap` customization point allows you to write member `swap=
` or ADL `swap`, whichever is most appropriate for your type. Your way requ=
ires writing member `swap` <i>and</i> overloading `std::swap`.<br><br>How i=
s that an improvement? Oh sure, its easier on the <i>caller</i>, but it&#39=
;s harder on the <i>writer</i>.<br><br>With a proper language feature, we c=
an make it easier on everyone.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e919ad53-9ba7-4789-b514-e17fcdf04f54%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e919ad53-9ba7-4789-b514-e17fcdf04f54=
%40isocpp.org</a>.<br />

------=_Part_296_1173860143.1494518801412--

------=_Part_295_1970201244.1494518801412--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 11 May 2017 21:37:01 +0200
Raw View
Le 11/05/2017 =C3=A0 11:40, Marc Mutz a =C3=A9crit :
> On Saturday 06 May 2017 15:41:53 Vicente J. Botet Escriba wrote:
>> So to answer to your comment.we want a single point that is able to
>> ensure some constraints (Method Pattern) and call to the specific
>> customized part. Adding overload in std will not satisfy these goal. I
>> believe the goals are desirable.
> You are already allowed to "customise" a) every std class template (by fu=
ll or
> partial specialisation, which needs to mention a user type), b) every std
> function template (by full specialisation, which needs to mention a user
> type).
I was aware that we can specialize some classes, but not all, and even=20
less the full specialize a std function. Could you point me to the=20
references?  Nevertheless this doesn't solve the customization points we=20
are talking of.
> And there's no central dispatch to enforce constraints there, either
> (and $DEITY forbid someone starts to specialise std::allocator, or
> std::is_pod, ...).
>
> I can already specialise std::reverse for any concrete instantiation of Q=
List,
> by full specialisation. The embarrassment is that I can't do this for the
> QList template itself (ie. all instantations of it).
I guess you are not happy then.
>
> So, from my POV of developer-in-the-trenches all that talk about customis=
ation
> points, associcated with concepts, is just hot air.
I will not talk about what developers think. I consider my self a=20
library developer and I don't agree with you here.
In generic programming we need customization points in one way or another.

>   The issue is why overloads
> of std function (s|templates), which are the moral equivalent of partial =
class
> template specialisation, are not allowed, and why some complex years-in-t=
he-
> future mythical language feature is needed, to artifically constrain some=
thing
> that's already unconstrained.
>
I believe someone has already responded to this question, but maybe it=20
was in another thread.

Vicente

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f8add216-a4e1-9a47-9d06-3378d5d48e01%40wanadoo.f=
r.

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 11 May 2017 22:02:36 +0200
Raw View
This is a multi-part message in MIME format.
--------------54503BD1C4F8DF21E600E4A9
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 11/05/2017 =C3=A0 18:06, Nicol Bolas a =C3=A9crit :
> On Thursday, May 11, 2017 at 5:41:20 AM UTC-4, Marc Mutz wrote:
>
>     On Saturday 06 May 2017 15:41:53 Vicente J. Botet Escriba wrote:
>     > So to answer to your comment.we want a single point that is able to
>     > ensure some constraints (Method Pattern) and call to the specific
>     > customized part. Adding overload in std will not satisfy these
>     goal. I
>     > believe the goals are desirable.
>
>     You are already allowed to "customise" a) every std class template
>     (by full or
>     partial specialisation, which needs to mention a user type), b)
>     every std
>     function template (by full specialisation, which needs to mention
>     a user
>     type). And there's no central dispatch to enforce constraints
>     there, either
>     (and $DEITY forbid someone starts to specialise std::allocator, or
>     std::is_pod, ...).
>
>
> Not everyone agrees that specialization should be allowed for function=20
> templates either. P0551 (PDF)=20
> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0551r0.pdf>=20
> makes the case that this should be removed.
Thanks for pointing out this link. I missed it completely.

Vicente


--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/a6bd5f65-0a97-2173-61a5-6dadad1bdc06%40wanadoo.f=
r.

--------------54503BD1C4F8DF21E600E4A9
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 11/05/2017 =C3=A0 18:06, Nicol Bolas =
a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:e919ad53-9ba7-4789-b514-e17fcdf04f54@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">On Thursday, May 11, 2017 at 5:41:20 AM UTC-4, Marc
        Mutz wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On
          Saturday 06 May 2017 15:41:53 Vicente J. Botet Escriba wrote:
          <br>
          &gt; So to answer to your comment.we want a single point that
          is able to <br>
          &gt; ensure some constraints (Method Pattern) and call to the
          specific <br>
          &gt; customized part. Adding overload in std will not satisfy
          these goal. I <br>
          &gt; believe the goals are desirable.
          <br>
          <br>
          You are already allowed to "customise" a) every std class
          template (by full or <br>
          partial specialisation, which needs to mention a user type),
          b) every std <br>
          function template (by full specialisation, which needs to
          mention a user <br>
          type). And there's no central dispatch to enforce constraints
          there, either <br>
          (and $DEITY forbid someone starts to specialise
          std::allocator, or <br>
          std::is_pod, ...).<br>
        </blockquote>
        <div><br>
          Not everyone agrees that specialization should be allowed for
          function templates either. <a moz-do-not-send=3D"true"
href=3D"http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0551r0.pdf=
">P0551
            (PDF)</a> makes the case that this should be removed.<br>
        </div>
      </div>
    </blockquote>
    Thanks for pointing out this link. I missed it completely.<br>
    <br>
    Vicente<br>
    <p><br>
    </p>
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a6bd5f65-0a97-2173-61a5-6dadad1bdc06%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a6bd5f65-0a97-2173-61a5-6dadad1bdc06=
%40wanadoo.fr</a>.<br />

--------------54503BD1C4F8DF21E600E4A9--

.