Topic: Musings on customization points, ADL, and the


Author: =?UTF-8?Q?Aar=C3=B3n_Bueno_Villares?= <abv150ci@gmail.com>
Date: Sat, 23 Sep 2017 14:54:12 -0700 (PDT)
Raw View
------=_Part_3762_331769939.1506203652548
Content-Type: multipart/alternative;
 boundary="----=_Part_3763_288949425.1506203652549"

------=_Part_3763_288949425.1506203652549
Content-Type: text/plain; charset="UTF-8"

I wrote a couple of days ago to Eric Niebler about the same issue, and he
tolds me that the risk "is not so big". My points were:

   - Namespaces were born to avoid name conflicts, and customization points
   takes alternative paths to remove them

There is some risk, yes, although I think it's small. The boost range
> library chose to call it's range-related customization points `range_begin`
> and `range_end` for this reason. I expect the number of genuine std-related
> customization points to be small. `swap`, `begin`, `end`, `size`,
> `iter_swap`, `iter_move` is the current list, I think. We can live with
> telling users not to define free functions called that. As for
> customization points defined by 3rd party libs, a solution like you suggest
> or like the one used by Boost would be worthwhile.


   - Standard customization points work like keywords to the language due
   to name conflicts

To a limited extent. Users are free to have functions begin and end that
> take more than one argument, for instance. But yes, for all intents and
> purposes, swap has been a keyword since C++98, and begin and end since ...
> TR1? I haven't heard cries of outrage, have you?


I'm far from being a C++ expert but in my understanding I agree that the
issue maybe is not big. Only by recommending 3rd party libraries to don't
use those names with that exact number of parameters would be enough, as
far as the number of customization points is kept short.

Anyway, the solution I purposed was just to add and extra parameter of
type, std::tag, for example, or std::customize inheriting from std::tag
(imitating the phylosophy of std::exception and its hierarchy), to make the
source namespace present as a last user's customization point parameter
(which will remove the need of "poison pills" too).

Besides, a standard tag hierarchy could open new possibilities, like adding
the concept check within the tags. That way, users, even learners, can test
in a very easy way if its types meet the requirements just by instantiating
the corresponding concept tag with its own type and see the generated
compiler errors, which can besides be used for making simpler to end users
write overloads by concepts instead of by type.

On Saturday, 23 September 2017 17:16:00 UTC+2, Nicol Bolas wrote:
>
> For the purposes of this conversation, a "customization point" refers to
> any mechanism used to add generic behavior to a type which didn't directly
> support it from outside of that type's definition.
>
> As C++ has grown, we have started to develop customization point idioms.
> And the standard has adopted several of them. The very first was
> `std::swap`, and every new customization point since then has used the
> particular idiom of `std::swap. That is:
>
> 1: The standard library defines a function called `std::swap`, which
> provides default behavior.
>
> 2: Users can customize the point for a type via adding an ADL variant.
>
> 3: Users invoke the customization point by declaring `using std::swap;`
> (to bring in the default behavior) followed by ADL-style `swap(...)`.
>
> Pretty much every customization point idiom ultimately relies on an
> ADL-based call. And that's the concern I want to deal with here: ADL calls.
>
> The big problem with ADL customization is that it is possible for multiple
> libraries to have conflicting customization points due to name conflicts.
> And C++'s normal mechanism for dealing with such conflicts, namespaces,
> can't save you, since ADL is designed to ignore namespaces.
>
> The Range TS uses a different idiom, based on a functor that you call.
> This idiom requires that you scope the call at the invocation site with the
> namespace. But for the actual customization, it still relies on ADL for
> out-of-class injection of functionality.
>
> The problem we ultimately have is that ADL doesn't know or care about
> whether a particular function was meant for the purpose you're using it
> for. After all, ADL was created to make operator overloading in namespaces
> actually work without having to qualify everything. The set of operator
> functions is limited, and the number of parameters that they take is
> usually fixed.
>
> ADL as the mechanism for injecting customization functions doesn't meet
> those criteria.
>
> While the Range TS customization mechanism is superior to the standard
> library mechanism, it still falls short on connecting a specific function
> declaration with a specific customization point. And as C++ gets bigger, we
> keep adding new customization points. The Range TS has over a dozen. They
> cover much of the API of `std::vector`. As we add more generic mechanisms,
> we add more customization points.
>
> It is disconcerting that we're building these generic mechanisms within
> what is effectively a single namespace.
>
> Now, I don't have a solution to this (except for a dedicated language
> feature that might solve it, but I don't even have a sketch of a design for
> that). But I do feel that this will increasingly become a problem as new
> customization points are added, both to the standard library and more
> importantly to user libraries. Indeed, the Range TS customization idiom is
> so effective at removing most of the flaws of the (rightfully maligned)
> standard library approach that widespread use of it could exacerbate the
> problem.
>
> Is this going to be a real problem going forward, or are these fears
> unfounded?
>

--
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/f8297436-9f27-49e6-ae55-635706acf89e%40isocpp.org.

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

<div dir=3D"ltr">I wrote a couple of days ago to Eric Niebler about the sam=
e issue, and he tolds me that the risk &quot;is not so big&quot;. My points=
 were:<div><ul><li>Namespaces were born to avoid name conflicts, and custom=
ization points takes alternative paths to remove them</li></ul><div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left:=
 1px solid rgb(204, 204, 204); padding-left: 1ex;"><span style=3D"font-fami=
ly: arial, sans-serif; font-size: 12.8px;">There is some risk, yes, althoug=
h I think it&#39;s small. The boost range library chose to call it&#39;s ra=
nge-related customization points `range_begin` and `range_end` for this rea=
son. I expect the number of genuine std-related customization points to be =
small. `swap`, `begin`, `end`, `size`, `iter_swap`, `iter_move` is the curr=
ent list, I think. We can live with telling users not to define free functi=
ons called that. As for customization points defined by 3rd party libs, a s=
olution like you suggest or like the one used by Boost would be worthwhile.=
</span></blockquote></div><ul><li>Standard customization points work like k=
eywords to the language due to name conflicts</li></ul><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;"><span style=3D"font-family: arial, sa=
ns-serif; font-size: 12.8px;">To a limited extent. Users are free to have f=
unctions begin and end that take more than one argument, for instance. But =
yes, for all intents and purposes, swap has been a keyword since C++98, and=
 begin and end since ... TR1? I haven&#39;t heard cries of outrage, have yo=
u?</span></blockquote></div><div><br></div><div>I&#39;m far from being a C+=
+ expert but in my understanding I agree that the issue maybe is not big. O=
nly by recommending 3rd party libraries to don&#39;t use those names with t=
hat exact number of parameters would be enough, as far as the number of cus=
tomization points is kept short.</div><div>=C2=A0</div><div>Anyway, the sol=
ution I purposed was just to add and extra parameter of type, std::tag, for=
 example, or std::customize inheriting from std::tag (imitating the phyloso=
phy of std::exception and its hierarchy), to make the source namespace pres=
ent as a last user&#39;s customization point parameter (which will remove t=
he need of &quot;poison pills&quot; too).</div><div><br></div><div>Besides,=
 a standard tag hierarchy could open new possibilities, like adding the con=
cept check within the tags. That way, users, even learners, can test in a v=
ery easy way if its types meet the requirements just by instantiating the c=
orresponding concept tag with its own type and see the generated compiler e=
rrors, which can besides be used for making simpler to end users write over=
loads by concepts instead of by type.</div><div><br></div><div>On Saturday,=
 23 September 2017 17:16:00 UTC+2, Nicol Bolas  wrote:<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">For the purposes of this conversat=
ion, a &quot;customization point&quot; refers to any mechanism used to add =
generic behavior to a type which didn&#39;t directly support it from outsid=
e of that type&#39;s definition.<br><br>As C++ has grown, we have started t=
o develop customization point idioms. And the standard has adopted several =
of them. The very first was `std::swap`, and every new customization point =
since then has used the particular idiom of `std::swap. That is:<br><br>1: =
The standard library defines a function called `std::swap`, which provides =
default behavior.<br><br>2: Users can customize the point for a type via ad=
ding an ADL variant.<br><br>3: Users invoke the customization point by decl=
aring `using std::swap;` (to bring in the default behavior) followed by ADL=
-style `swap(...)`.<br><br>Pretty much every customization point idiom ulti=
mately relies on an ADL-based call. And that&#39;s the concern I want to de=
al with here: ADL calls.<br><br>The big problem with ADL customization is t=
hat it is possible for multiple libraries to have conflicting customization=
 points due to name conflicts. And C++&#39;s normal mechanism for dealing w=
ith such conflicts, namespaces, can&#39;t save you, since ADL is designed t=
o ignore namespaces.<br><br>The Range TS uses a different idiom, based on a=
 functor that you call. This idiom requires that you scope the call at the =
invocation site with the namespace. But for the actual customization, it st=
ill relies on ADL for out-of-class injection of functionality.<br><br>The p=
roblem we ultimately have is that ADL doesn&#39;t know or care about whethe=
r a particular function was meant for the purpose you&#39;re using it for. =
After all, ADL was created to make operator overloading in namespaces actua=
lly work without having to qualify everything. The set of operator function=
s is limited, and the number of parameters that they take is usually fixed.=
<br><br>ADL as the mechanism for injecting customization functions doesn&#3=
9;t meet those criteria.<br><br>While the Range TS customization mechanism =
is superior to the standard library mechanism, it still falls short on conn=
ecting a specific function declaration with a specific customization point.=
 And as C++ gets bigger, we keep adding new customization points. The Range=
 TS has over a dozen. They cover much of the API of `std::vector`. As we ad=
d more generic mechanisms, we add more customization points.<br><br>It is d=
isconcerting that we&#39;re building these generic mechanisms within what i=
s effectively a single namespace.<br><br>Now, I don&#39;t have a solution t=
o this (except for a dedicated language feature that might solve it, but I =
don&#39;t even have a sketch of a design for that). But I do feel that this=
 will increasingly become a problem as new customization points are added, =
both to the standard library and more importantly to user libraries. Indeed=
, the Range TS customization idiom is so effective at removing most of the =
flaws of the (rightfully maligned) standard library approach that widesprea=
d use of it could exacerbate the problem.<br><br>Is this going to be a real=
 problem going forward, or are these fears unfounded?<br></div></blockquote=
></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/f8297436-9f27-49e6-ae55-635706acf89e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f8297436-9f27-49e6-ae55-635706acf89e=
%40isocpp.org</a>.<br />

------=_Part_3763_288949425.1506203652549--

------=_Part_3762_331769939.1506203652548--

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 24 Sep 2017 02:19:21 -0700 (PDT)
Raw View
------=_Part_4311_1590037433.1506244761673
Content-Type: multipart/alternative;
 boundary="----=_Part_4312_1939803881.1506244761673"

------=_Part_4312_1939803881.1506244761673
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Saturday, September 23, 2017 at 11:54:12 PM UTC+2, Aar=C3=B3n Bueno Vill=
ares=20
wrote:
>
>
> Anyway, the solution I purposed was just to add and extra parameter of=20
> type, std::tag, for example, or std::customize inheriting from std::tag=
=20
> (imitating the phylosophy of std::exception and its hierarchy), to make t=
he=20
> source namespace present as a last user's customization point parameter=
=20
> (which will remove the need of "poison pills" too).
>
> I think this is interesting solution, nobody will by mistaken using this=
=20
tag and name conflict will be fix by overloads:
namespace std
{

class customize_t {} customize;

template<typename T>
void swap(customize_t, T a, T b);

template<typename T>
void swap(T a, T b)
{
    swap(customize, a, b);
}


}

namespace My
{

class A;
void swap(A, A); //backward compatible version for C++03 code
void swap(std::customize_t, A a, A b); //new customization point

}


--=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/057ee7d2-f5e9-4255-9497-fbf8b64c55f5%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Saturday, September 23, 2017 at 11:54:12 PM UTC=
+2, Aar=C3=B3n Bueno Villares 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"><br><div>Anyway, the solution I purposed was just to=
 add and extra parameter of type, std::tag, for example, or std::customize =
inheriting from std::tag (imitating the phylosophy of std::exception and it=
s hierarchy), to make the source namespace present as a last user&#39;s cus=
tomization point parameter (which will remove the need of &quot;poison pill=
s&quot; too).</div><br></div></blockquote><div>I think this is interesting =
solution, nobody will by mistaken using this tag and name conflict will be =
fix by overloads:</div><div><div style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"=
styled-by-prettify">namespace</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> std<br></span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> customize_t </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> cus=
tomize</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">template</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> swap</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">customize_t</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> T a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> T b</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> swap</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T=
 a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> T b</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 swap</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">customize</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br><br></span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">namespace</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">My</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">class<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> A</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> swap</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">A</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> A</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #800;" class=3D"styled-by-prettify">//backward compatible =
version for C++03 code</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 swap</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">customize_t</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> A a</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> A b</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>//new customization point</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span></div></code></div><br><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/057ee7d2-f5e9-4255-9497-fbf8b64c55f5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/057ee7d2-f5e9-4255-9497-fbf8b64c55f5=
%40isocpp.org</a>.<br />

------=_Part_4312_1939803881.1506244761673--

------=_Part_4311_1590037433.1506244761673--

.