Topic: Extension methods with a restriction to make it viable


Author: Justin Bassett <jbassett271@gmail.com>
Date: Fri, 3 Aug 2018 23:25:31 -0700 (PDT)
Raw View
------=_Part_917_347098772.1533363931714
Content-Type: multipart/alternative;
 boundary="----=_Part_918_1793314765.1533363931715"

------=_Part_918_1793314765.1533363931715
Content-Type: text/plain; charset="UTF-8"

Seeing as the trailing version of UFCS will never happen (x.foo() meaning
foo(x)) due to the API compatibility nightmare it creates, I would like to
resurrect extension methods.

Extension methods are clearly very desired, seeing as it has been brought
up many times:

   - Have "extension methods" been proposed for C++1y? (or any previous
   standard)
   <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/17tP4GJbYaI/KkFBl6izfpAJ>
   - Extension methods for C++
   <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/A32ndecDoVA/pYARFXCLBAAJ>
   - extention methods or UFCS
   <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/fa42g-XAeD4/6ATqFHNQZUEJ>
    [sic]
   - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0079r0.pdf

The API compatibility problems arise by allowing extension methods to be
added by the user rather than restricting them to the library author. I
propose adding extension methods, but restricting them such that only the
library author can add them.


Currently, postfix function calls are restricted to member functions or
imitated via operator overloading like Ranges. Both of these solutions have
their problems:

   - Member functions apply only the the specific type. If I write
   `Foo::member_function()`, it can only be called on objects of type `Foo`,
   not of type `Bar`. If I want to be able to call it on `Bar`, I need to do a
   lot of work to make it scale to the other types in the library
   - Member functions can't be extended by users of the library. Using
   Ranges as an example, the user can't add `my_fancy_algorithm()` as a member
   function.

Concerning Ranges pipe operator:

   - It would be harder to produce good intellisense for | as contrasted
   with . , as there are more things to potentially consider.
   - Possible affect on compile times (not measured, this can also be
   completely wrong)
   - Each member of a chain has to be namespace qualified: myRange |
   ranges::transform(...) | ranges::accumulate(...) . Using declarations
   are not a viable solution; it's too much to require a using declaration for
   each function. Using directives are glob imports, so they come with all the
   problems of glob imports.
   - There's a wtf moment for someone unfamiliar with this usage of the
   bitwise or operator. Once taught to think about it as a unix pipe, one can
   be more comfortable with it, but personally I've never grown fond of it.

Note: I am using Ranges as an example, but that doesn't mean I think that
Ranges should be delayed. I just think it makes for good examples.

I much prefer reading myRange.transform(...).accumulate(...), but I
recognize that using member functions just doesn't work here. That's why I
claim that extension methods are a better solution.


With extension methods, I can write
myRange.transform(...).my_fancy_algorithm(...).accumulate(...) rather than myRange
| ranges::transform(...) | my_ns::my_fancy_algorithm(...) |
ranges::accumulate(...)

The biggest caveat of extension methods is that library authors lose
control over what can come after the . . As a preliminary proposal on a
restriction that restricts extension methods to library authors, let's
choose the restriction that extension methods must be findable via ADL.
Further, to avoid conflicts with free functions, let's consider all
..foo(...) functions (whether member or extension methods) separate from
free functions when performing overload resolution.

Arbitrary syntax (considering the "deducing this" proposal, this should
probably mimic the syntax decided for that):

namespace ns::ranges {

struct adl_tag {};

template <typename Range>
struct view {
    auto begin() const;
    auto end() const;
    // ...
};

// ...

template <typename T, typename F>
auto transform(T&& this self, F&& fn) {
    // ...
}

// ...

}

// Usage:

ns::ranges::view(myRange)
    .transform(...)
    .accumulate(...);

// Extending with my own algorithms:

namespace user {

template <typename Range>
struct my_view
    : private ns::ranges::adl_tag // allow ADL to look into ns::ranges
{
    // ...
};

template <typename T, typename F>
auto my_fancy_algorithm(T&& this self, F&& fn) {
    // ...
}

}

// Usage:

user::my_view(myRange)
    .transform(...)
    // Barring type erasure, we can still find my_fancy_algorithm since the
    // user::my_view type is encoded into the template type somewhere
    .my_fancy_algorithm(...)
    .accumulate(...);


Problems that have yet to be addressed:

   - In the definition of a class method, does this->foo(...) consider
   extension methods in overload resolution? Why or why not?
   - Outside of the definition of a class method, does foo.bar(...)
   consider both extension methods and member functions in overload
   resolution? Why or why not? (I think it should overload both; if the member
   function doesn't exist, it should be able to fall back on extension methods)
   - Should qualified function calls be allowed? That is, should I be able
   to write foo.std::ranges::transform(...)? This would be consistent with
   member functions; I can already write string.std::string::size(). If we
   allow this, should this be able to call extension methods from arbitrary
   namespaces, not just ones that can be found via ADL?
   - Is this a reasonable restriction level? If the library implementer
   does not put all the extension methods in their own namespace with a
   wrapper that brings them into context, it could get out of hand fast.
   Granted, this would be no different from using unqualified prefix function
   calls.

--
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/7ce23f53-d00e-45a0-a62b-c42060c5833d%40isocpp.org.

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

<div dir=3D"ltr">Seeing as the trailing version of UFCS will never happen (=
<font face=3D"courier new, monospace">x.foo()</font> meaning <font face=3D"=
courier new, monospace">foo(x)</font>) due to the API compatibility nightma=
re it creates, I would like to resurrect extension methods.<div><br></div><=
div>Extension methods are clearly very desired, seeing as it has been broug=
ht up many times:</div><div><ul><li><a href=3D"https://groups.google.com/a/=
isocpp.org/d/msg/std-proposals/17tP4GJbYaI/KkFBl6izfpAJ">Have &quot;extensi=
on methods&quot; been proposed for C++1y? (or any previous standard)</a><br=
></li><li><a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-propo=
sals/A32ndecDoVA/pYARFXCLBAAJ">Extension methods for C++</a><br></li><li><a=
 href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-proposals/fa42g-X=
AeD4/6ATqFHNQZUEJ">extention methods or UFCS</a>=C2=A0[sic]<br></li><li><a =
href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0079r0.pdf=
">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0079r0.pdf</a><b=
r></li></ul><div>The API compatibility problems arise by allowing extension=
 methods to be added by the user rather than restricting them to the librar=
y author. I propose adding extension methods, but restricting them such tha=
t only the library author can add them.</div></div><div><br><br></div><div>=
Currently, postfix function calls are restricted to member functions or imi=
tated via operator overloading like Ranges. Both of these solutions have th=
eir problems:</div><div><ul><li>Member functions apply only the the specifi=
c type. If I write `Foo::member_function()`, it can only be called on objec=
ts of type `Foo`, not of type `Bar`. If I want to be able to call it on `Ba=
r`, I need to do a lot of work to make it scale to the other types in the l=
ibrary</li><li>Member functions can&#39;t be extended by users of the libra=
ry. Using Ranges as an example, the user can&#39;t add `my_fancy_algorithm(=
)` as a member function.</li></ul><div>Concerning Ranges pipe operator:</di=
v></div><div><ul><li>It would be harder to produce good intellisense for=C2=
=A0<font face=3D"courier new, monospace">|</font> as contrasted with=C2=A0<=
font face=3D"courier new, monospace">.</font>=C2=A0, as there are more thin=
gs to potentially consider.</li><li>Possible affect on compile times (not m=
easured, this can also be completely wrong)</li><li>Each member of a chain =
has to be namespace qualified: <font face=3D"courier new, monospace">myRang=
e | ranges::transform(...) | ranges::accumulate(...)</font> . Using declara=
tions are not a viable solution; it&#39;s too much to require a using decla=
ration for each function. Using directives are glob imports, so they come w=
ith all the problems of glob imports.</li><li>There&#39;s a wtf moment for =
someone unfamiliar with this usage of the bitwise or operator. Once taught =
to think about it as a unix pipe, one can be more comfortable with it, but =
personally I&#39;ve never grown fond of it.</li></ul></div><div>Note: I am =
using Ranges as an example, but that doesn&#39;t mean I think that Ranges s=
hould be delayed. I just think it makes for good examples.<br></div><div><b=
r></div><div>I much prefer reading <font face=3D"courier new, monospace">my=
Range.transform(...).accumulate(...)</font><font face=3D"arial, sans-serif"=
>, but I recognize that using member functions just doesn&#39;t work here. =
That&#39;s why I claim that extension methods are a better solution.</font>=
</div><div><font face=3D"arial, sans-serif"><br></font></div><div><br></div=
><div>With extension methods, I can write <font face=3D"courier new, monosp=
ace">myRange.transform(...).my_fancy_algorithm(...).accumulate(...)</font> =
rather than=C2=A0<font face=3D"courier new, monospace">myRange | ranges::tr=
ansform(...) | my_ns::my_fancy_algorithm(...) | ranges::accumulate(...)</fo=
nt></div><div><font face=3D"courier new, monospace"><br></font></div><div><=
font face=3D"arial, sans-serif">The biggest caveat=C2=A0of extension method=
s is that library authors lose control over what can come after the </font>=
<font face=3D"courier new, monospace">.</font><font face=3D"arial, sans-ser=
if"> . As a preliminary proposal on a restriction that restricts extension =
methods to library authors, let&#39;s choose the restriction that extension=
 methods must be findable via ADL. Further, to avoid conflicts with free fu=
nctions, let&#39;s consider all </font><font face=3D"courier new, monospace=
">.foo(...)</font><font face=3D"arial, sans-serif"> functions (whether memb=
er or extension methods) separate from free functions when performing overl=
oad resolution.</font></div><div><font face=3D"arial, sans-serif"><br></fon=
t></div><div><font face=3D"arial, sans-serif">Arbitrary syntax (considering=
 the &quot;deducing this&quot; proposal, this should probably mimic the syn=
tax decided for that):</font></div><div><font face=3D"arial, sans-serif"><b=
r></font></div><div><div class=3D"prettyprint" style=3D"background-color: r=
gb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; b=
order-width: 1px; word-wrap: break-word; font-family: arial, sans-serif;"><=
code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">namespace</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> ns</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">ranges </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> adl_tag </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">temp=
late</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Range</span><span style=3D"color=
: #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;" cla=
ss=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> view </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">begin</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">end</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">const</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-p=
rettify">// ...</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// ...</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">template</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </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">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> F</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> transform</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">this</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">self</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> F</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&am=
p;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> fn=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #800;" 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><br></span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// ...</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"styled-=
by-prettify">// Usage:</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br><br>ns</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">ranges</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">view</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">myRange</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">transform</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(...)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">accumulate</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(...);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// Extending with my own algorithms:</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">namespace</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> user </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=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: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pr=
ettify">Range</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> my_view<br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">private</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> ns</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">ranges</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">adl_tag </span><span style=3D"color: #800;" =
class=3D"styled-by-prettify">// allow ADL to look into ns::ranges</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">// ...</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">template</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> my_fancy_algorithm</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">this</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">sel=
f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> fn</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// ...</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br><br></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><b=
r></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Usage=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>u=
ser</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">my_view</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">myRange</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">transform</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(...)</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify">// Barring type erasure, we can sti=
ll find my_fancy_algorithm since the</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;" class=3D"styled-by-prettify">//=C2=A0</span><span style=3D"color: rgb(=
136, 0, 0); font-family: arial, sans-serif;">user::my_view type is encoded=
=C2=A0</span><span style=3D"color: rgb(136, 0, 0); font-family: arial, sans=
-serif;">into the template type somewhere</span></div><div class=3D"subpret=
typrint"><span style=3D"color: #000;" class=3D"styled-by-prettify">=C2=A0 =
=C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">my_fancy_alg=
orithm</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(...=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">accumula=
te</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(...);</=
span></div></code></div></div><div><font face=3D"arial, sans-serif"><br></f=
ont></div><div><font face=3D"arial, sans-serif"><br></font></div><div><font=
 face=3D"arial, sans-serif">Problems that have yet to be addressed:</font><=
/div><div><ul><li><font face=3D"arial, sans-serif">In the definition of a c=
lass method, does </font><font face=3D"courier new, monospace">this-&gt;foo=
(...)</font><font face=3D"arial, sans-serif"> consider extension methods in=
 overload resolution? Why or why not?</font></li><li><font face=3D"arial, s=
ans-serif">Outside of the definition of a class method, does </font><font f=
ace=3D"courier new, monospace">foo.bar(...)</font><font face=3D"arial, sans=
-serif"> consider both extension methods and member functions in overload r=
esolution? Why or why not? (I think it should overload both; if the member =
function doesn&#39;t exist, it should be able to fall back on extension met=
hods)</font></li><li><font face=3D"arial, sans-serif">Should qualified func=
tion calls be allowed? That is, should I be able to write </font><font face=
=3D"courier new, monospace">foo.std::ranges::transform(...)</font><font fac=
e=3D"arial, sans-serif">? This would be consistent with member functions; I=
 can already write </font><font face=3D"courier new, monospace">string.std:=
:string::size()</font><font face=3D"arial, sans-serif">. If we allow this, =
should this be able to call extension methods from arbitrary namespaces, no=
t just ones that can be found via ADL?</font></li><li><font face=3D"arial, =
sans-serif">Is this a reasonable restriction level? If the library implemen=
ter does not put all the extension methods in their own namespace with a wr=
apper that brings them into context, it could get out of hand fast. Granted=
, this would be no different from using unqualified prefix function calls.<=
/font></li></ul></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/7ce23f53-d00e-45a0-a62b-c42060c5833d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7ce23f53-d00e-45a0-a62b-c42060c5833d=
%40isocpp.org</a>.<br />

------=_Part_918_1793314765.1533363931715--

------=_Part_917_347098772.1533363931714--

.


Author: =?UTF-8?B?R2HFoXBlciBBxb5tYW4=?= <gasper.azman@gmail.com>
Date: Sat, 4 Aug 2018 12:33:12 +0100
Raw View
--0000000000000868a505729a6a53
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi Justin,

I'm posting just to say I will address this as I come back from holiday, in
about a week and a half. It's a very interesting take - but needs more
careful consideration than I can afford right now.

Thanks for your mention!

Ga=C5=A1per

On Sat, Aug 4, 2018 at 7:25 AM, Justin Bassett <jbassett271@gmail.com>
wrote:

> Seeing as the trailing version of UFCS will never happen (x.foo() meaning
> foo(x)) due to the API compatibility nightmare it creates, I would like
> to resurrect extension methods.
>
> Extension methods are clearly very desired, seeing as it has been brought
> up many times:
>
>    - Have "extension methods" been proposed for C++1y? (or any previous
>    standard)
>    <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/17tP4GJbYa=
I/KkFBl6izfpAJ>
>    - Extension methods for C++
>    <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/A32ndecDoV=
A/pYARFXCLBAAJ>
>    - extention methods or UFCS
>    <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/fa42g-XAeD=
4/6ATqFHNQZUEJ>
>     [sic]
>    - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0079r0.pdf
>
> The API compatibility problems arise by allowing extension methods to be
> added by the user rather than restricting them to the library author. I
> propose adding extension methods, but restricting them such that only the
> library author can add them.
>
>
> Currently, postfix function calls are restricted to member functions or
> imitated via operator overloading like Ranges. Both of these solutions ha=
ve
> their problems:
>
>    - Member functions apply only the the specific type. If I write
>    `Foo::member_function()`, it can only be called on objects of type `Fo=
o`,
>    not of type `Bar`. If I want to be able to call it on `Bar`, I need to=
 do a
>    lot of work to make it scale to the other types in the library
>    - Member functions can't be extended by users of the library. Using
>    Ranges as an example, the user can't add `my_fancy_algorithm()` as a m=
ember
>    function.
>
> Concerning Ranges pipe operator:
>
>    - It would be harder to produce good intellisense for | as contrasted
>    with . , as there are more things to potentially consider.
>    - Possible affect on compile times (not measured, this can also be
>    completely wrong)
>    - Each member of a chain has to be namespace qualified: myRange |
>    ranges::transform(...) | ranges::accumulate(...) . Using declarations
>    are not a viable solution; it's too much to require a using declaratio=
n for
>    each function. Using directives are glob imports, so they come with al=
l the
>    problems of glob imports.
>    - There's a wtf moment for someone unfamiliar with this usage of the
>    bitwise or operator. Once taught to think about it as a unix pipe, one=
 can
>    be more comfortable with it, but personally I've never grown fond of i=
t.
>
> Note: I am using Ranges as an example, but that doesn't mean I think that
> Ranges should be delayed. I just think it makes for good examples.
>
> I much prefer reading myRange.transform(...).accumulate(...), but I
> recognize that using member functions just doesn't work here. That's why =
I
> claim that extension methods are a better solution.
>
>
> With extension methods, I can write myRange.transform(...).my_
> fancy_algorithm(...).accumulate(...) rather than myRange |
> ranges::transform(...) | my_ns::my_fancy_algorithm(...) |
> ranges::accumulate(...)
>
> The biggest caveat of extension methods is that library authors lose
> control over what can come after the . . As a preliminary proposal on a
> restriction that restricts extension methods to library authors, let's
> choose the restriction that extension methods must be findable via ADL.
> Further, to avoid conflicts with free functions, let's consider all
> .foo(...) functions (whether member or extension methods) separate from
> free functions when performing overload resolution.
>
> Arbitrary syntax (considering the "deducing this" proposal, this should
> probably mimic the syntax decided for that):
>
> namespace ns::ranges {
>
> struct adl_tag {};
>
> template <typename Range>
> struct view {
>     auto begin() const;
>     auto end() const;
>     // ...
> };
>
> // ...
>
> template <typename T, typename F>
> auto transform(T&& this self, F&& fn) {
>     // ...
> }
>
> // ...
>
> }
>
> // Usage:
>
> ns::ranges::view(myRange)
>     .transform(...)
>     .accumulate(...);
>
> // Extending with my own algorithms:
>
> namespace user {
>
> template <typename Range>
> struct my_view
>     : private ns::ranges::adl_tag // allow ADL to look into ns::ranges
> {
>     // ...
> };
>
> template <typename T, typename F>
> auto my_fancy_algorithm(T&& this self, F&& fn) {
>     // ...
> }
>
> }
>
> // Usage:
>
> user::my_view(myRange)
>     .transform(...)
>     // Barring type erasure, we can still find my_fancy_algorithm since
> the
>     // user::my_view type is encoded into the template type somewhere
>     .my_fancy_algorithm(...)
>     .accumulate(...);
>
>
> Problems that have yet to be addressed:
>
>    - In the definition of a class method, does this->foo(...) consider
>    extension methods in overload resolution? Why or why not?
>    - Outside of the definition of a class method, does foo.bar(...)
>    consider both extension methods and member functions in overload
>    resolution? Why or why not? (I think it should overload both; if the m=
ember
>    function doesn't exist, it should be able to fall back on extension me=
thods)
>    - Should qualified function calls be allowed? That is, should I be
>    able to write foo.std::ranges::transform(...)? This would be
>    consistent with member functions; I can already write
>    string.std::string::size(). If we allow this, should this be able to
>    call extension methods from arbitrary namespaces, not just ones that c=
an be
>    found via ADL?
>    - Is this a reasonable restriction level? If the library implementer
>    does not put all the extension methods in their own namespace with a
>    wrapper that brings them into context, it could get out of hand fast.
>    Granted, this would be no different from using unqualified prefix func=
tion
>    calls.
>
> --
> 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/7ce23f53-d00e-45a0-
> a62b-c42060c5833d%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7ce23f53-d0=
0e-45a0-a62b-c42060c5833d%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=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/CAANG%3DkVgcf9o1K8dGVKj4_ECQRC_UmJXB%3D_NFOo%3DL=
ymMMsP6yQ%40mail.gmail.com.

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

<div dir=3D"ltr">Hi Justin,<div><br></div><div>I&#39;m posting just to say =
I will address this as I come back from holiday, in about a week and a half=
.. It&#39;s a very interesting take - but needs more careful consideration t=
han I can afford right now.</div><div><br></div><div>Thanks for your mentio=
n!</div><div><br></div><div>Ga=C5=A1per</div></div><div class=3D"gmail_extr=
a"><br><div class=3D"gmail_quote">On Sat, Aug 4, 2018 at 7:25 AM, Justin Ba=
ssett <span dir=3D"ltr">&lt;<a href=3D"mailto:jbassett271@gmail.com" target=
=3D"_blank">jbassett271@gmail.com</a>&gt;</span> wrote:<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr">Seeing as the trailing version of UFCS will=
 never happen (<font face=3D"courier new, monospace">x.foo()</font> meaning=
 <font face=3D"courier new, monospace">foo(x)</font>) due to the API compat=
ibility nightmare it creates, I would like to resurrect extension methods.<=
div><br></div><div>Extension methods are clearly very desired, seeing as it=
 has been brought up many times:</div><div><ul><li><a href=3D"https://group=
s.google.com/a/isocpp.org/d/msg/std-proposals/17tP4GJbYaI/KkFBl6izfpAJ" tar=
get=3D"_blank">Have &quot;extension methods&quot; been proposed for C++1y? =
(or any previous standard)</a><br></li><li><a href=3D"https://groups.google=
..com/a/isocpp.org/d/msg/std-proposals/A32ndecDoVA/pYARFXCLBAAJ" target=3D"_=
blank">Extension methods for C++</a><br></li><li><a href=3D"https://groups.=
google.com/a/isocpp.org/d/msg/std-proposals/fa42g-XAeD4/6ATqFHNQZUEJ" targe=
t=3D"_blank">extention methods or UFCS</a>=C2=A0[sic]<br></li><li><a href=
=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0079r0.pdf" ta=
rget=3D"_blank">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/201=
5/<wbr>p0079r0.pdf</a><br></li></ul><div>The API compatibility problems ari=
se by allowing extension methods to be added by the user rather than restri=
cting them to the library author. I propose adding extension methods, but r=
estricting them such that only the library author can add them.</div></div>=
<div><br><br></div><div>Currently, postfix function calls are restricted to=
 member functions or imitated via operator overloading like Ranges. Both of=
 these solutions have their problems:</div><div><ul><li>Member functions ap=
ply only the the specific type. If I write `Foo::member_function()`, it can=
 only be called on objects of type `Foo`, not of type `Bar`. If I want to b=
e able to call it on `Bar`, I need to do a lot of work to make it scale to =
the other types in the library</li><li>Member functions can&#39;t be extend=
ed by users of the library. Using Ranges as an example, the user can&#39;t =
add `my_fancy_algorithm()` as a member function.</li></ul><div>Concerning R=
anges pipe operator:</div></div><div><ul><li>It would be harder to produce =
good intellisense for=C2=A0<font face=3D"courier new, monospace">|</font> a=
s contrasted with=C2=A0<font face=3D"courier new, monospace">.</font>=C2=A0=
, as there are more things to potentially consider.</li><li>Possible affect=
 on compile times (not measured, this can also be completely wrong)</li><li=
>Each member of a chain has to be namespace qualified: <font face=3D"courie=
r new, monospace">myRange | ranges::transform(...) | ranges::accumulate(...=
)</font> . Using declarations are not a viable solution; it&#39;s too much =
to require a using declaration for each function. Using directives are glob=
 imports, so they come with all the problems of glob imports.</li><li>There=
&#39;s a wtf moment for someone unfamiliar with this usage of the bitwise o=
r operator. Once taught to think about it as a unix pipe, one can be more c=
omfortable with it, but personally I&#39;ve never grown fond of it.</li></u=
l></div><div>Note: I am using Ranges as an example, but that doesn&#39;t me=
an I think that Ranges should be delayed. I just think it makes for good ex=
amples.<br></div><div><br></div><div>I much prefer reading <font face=3D"co=
urier new, monospace">myRange.transform(...).<wbr>accumulate(...)</font><fo=
nt face=3D"arial, sans-serif">, but I recognize that using member functions=
 just doesn&#39;t work here. That&#39;s why I claim that extension methods =
are a better solution.</font></div><div><font face=3D"arial, sans-serif"><b=
r></font></div><div><br></div><div>With extension methods, I can write <fon=
t face=3D"courier new, monospace">myRange.transform(...).my_<wbr>fancy_algo=
rithm(...).<wbr>accumulate(...)</font> rather than=C2=A0<font face=3D"couri=
er new, monospace">myRange | ranges::transform(...) | my_ns::my_fancy_algor=
ithm(...) | ranges::accumulate(...)</font></div><div><font face=3D"courier =
new, monospace"><br></font></div><div><font face=3D"arial, sans-serif">The =
biggest caveat=C2=A0of extension methods is that library authors lose contr=
ol over what can come after the </font><font face=3D"courier new, monospace=
">.</font><font face=3D"arial, sans-serif"> . As a preliminary proposal on =
a restriction that restricts extension methods to library authors, let&#39;=
s choose the restriction that extension methods must be findable via ADL. F=
urther, to avoid conflicts with free functions, let&#39;s consider all </fo=
nt><font face=3D"courier new, monospace">.foo(...)</font><font face=3D"aria=
l, sans-serif"> functions (whether member or extension methods) separate fr=
om free functions when performing overload resolution.</font></div><div><fo=
nt face=3D"arial, sans-serif"><br></font></div><div><font face=3D"arial, sa=
ns-serif">Arbitrary syntax (considering the &quot;deducing this&quot; propo=
sal, this should probably mimic the syntax decided for that):</font></div><=
div><font face=3D"arial, sans-serif"><br></font></div><div><div class=3D"m_=
-7692250097086650299prettyprint" style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wra=
p:break-word;font-family:arial,sans-serif"><code class=3D"m_-76922500970866=
50299prettyprint"><div class=3D"m_-7692250097086650299subprettyprint"><span=
 style=3D"color:#008" class=3D"m_-7692250097086650299styled-by-prettify">na=
mespace</span><span style=3D"color:#000" class=3D"m_-7692250097086650299sty=
led-by-prettify"> ns</span><span style=3D"color:#660" class=3D"m_-769225009=
7086650299styled-by-prettify">::</span><span style=3D"color:#000" class=3D"=
m_-7692250097086650299styled-by-prettify">ranges </span><span style=3D"colo=
r:#660" class=3D"m_-7692250097086650299styled-by-prettify">{</span><span st=
yle=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br><=
br></span><span style=3D"color:#008" class=3D"m_-7692250097086650299styled-=
by-prettify">struct</span><span style=3D"color:#000" class=3D"m_-7692250097=
086650299styled-by-prettify"> adl_tag </span><span style=3D"color:#660" cla=
ss=3D"m_-7692250097086650299styled-by-prettify">{};</span><span style=3D"co=
lor:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br><br></span=
><span style=3D"color:#008" class=3D"m_-7692250097086650299styled-by-pretti=
fy">template</span><span style=3D"color:#000" class=3D"m_-76922500970866502=
99styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_-769225=
0097086650299styled-by-prettify">&lt;</span><span style=3D"color:#008" clas=
s=3D"m_-7692250097086650299styled-by-prettify">typename</span><span style=
=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"> </span>=
<span style=3D"color:#606" class=3D"m_-7692250097086650299styled-by-prettif=
y">Range</span><span style=3D"color:#660" class=3D"m_-7692250097086650299st=
yled-by-prettify">&gt;</span><span style=3D"color:#000" class=3D"m_-7692250=
097086650299styled-by-prettify"><br></span><span style=3D"color:#008" class=
=3D"m_-7692250097086650299styled-by-prettify">struct</span><span style=3D"c=
olor:#000" class=3D"m_-7692250097086650299styled-by-prettify"> view </span>=
<span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettif=
y">{</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled=
-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"=
m_-7692250097086650299styled-by-prettify">auto</span><span style=3D"color:#=
000" class=3D"m_-7692250097086650299styled-by-prettify"> </span><span style=
=3D"color:#008" class=3D"m_-7692250097086650299styled-by-prettify">begin</s=
pan><span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-pre=
ttify">()</span><span style=3D"color:#000" class=3D"m_-7692250097086650299s=
tyled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_-769225009=
7086650299styled-by-prettify">const</span><span style=3D"color:#660" class=
=3D"m_-7692250097086650299styled-by-prettify">;</span><span style=3D"color:=
#000" class=3D"m_-7692250097086650299styled-by-prettify"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008" class=3D"m_-7692250097086650299styled-by-=
prettify">auto</span><span style=3D"color:#000" class=3D"m_-769225009708665=
0299styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_-7692=
250097086650299styled-by-prettify">end</span><span style=3D"color:#660" cla=
ss=3D"m_-7692250097086650299styled-by-prettify">()</span><span style=3D"col=
or:#000" class=3D"m_-7692250097086650299styled-by-prettify"> </span><span s=
tyle=3D"color:#008" class=3D"m_-7692250097086650299styled-by-prettify">cons=
t</span><span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by=
-prettify">;</span><span style=3D"color:#000" class=3D"m_-76922500970866502=
99styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#800" c=
lass=3D"m_-7692250097086650299styled-by-prettify">// ...</span><span style=
=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br></sp=
an><span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-pret=
tify">};</span><span style=3D"color:#000" class=3D"m_-7692250097086650299st=
yled-by-prettify"><br><br></span><span style=3D"color:#800" class=3D"m_-769=
2250097086650299styled-by-prettify">// ...</span><span style=3D"color:#000"=
 class=3D"m_-7692250097086650299styled-by-prettify"><br><br></span><span st=
yle=3D"color:#008" class=3D"m_-7692250097086650299styled-by-prettify">templ=
ate</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled-=
by-prettify"> </span><span style=3D"color:#660" class=3D"m_-769225009708665=
0299styled-by-prettify">&lt;</span><span style=3D"color:#008" class=3D"m_-7=
692250097086650299styled-by-prettify">typename</span><span style=3D"color:#=
000" class=3D"m_-7692250097086650299styled-by-prettify"> T</span><span styl=
e=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify">,</span=
><span style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-pretti=
fy"> </span><span style=3D"color:#008" class=3D"m_-7692250097086650299style=
d-by-prettify">typename</span><span style=3D"color:#000" class=3D"m_-769225=
0097086650299styled-by-prettify"> F</span><span style=3D"color:#660" class=
=3D"m_-7692250097086650299styled-by-prettify">&gt;</span><span style=3D"col=
or:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br></span><spa=
n style=3D"color:#008" class=3D"m_-7692250097086650299styled-by-prettify">a=
uto</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled-=
by-prettify"> transform</span><span style=3D"color:#660" class=3D"m_-769225=
0097086650299styled-by-prettify">(</span><span style=3D"color:#000" class=
=3D"m_-7692250097086650299styled-by-prettify">T</span><span style=3D"color:=
#660" class=3D"m_-7692250097086650299styled-by-prettify">&amp;&amp;</span><=
span style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify=
"> </span><span style=3D"color:#008" class=3D"m_-7692250097086650299styled-=
by-prettify">this</span><span style=3D"color:#000" class=3D"m_-769225009708=
6650299styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_-7=
692250097086650299styled-by-prettify">self</span><span style=3D"color:#660"=
 class=3D"m_-7692250097086650299styled-by-prettify">,</span><span style=3D"=
color:#000" class=3D"m_-7692250097086650299styled-by-prettify"> F</span><sp=
an style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify">=
&amp;&amp;</span><span style=3D"color:#000" class=3D"m_-7692250097086650299=
styled-by-prettify"> fn</span><span style=3D"color:#660" class=3D"m_-769225=
0097086650299styled-by-prettify">)</span><span style=3D"color:#000" class=
=3D"m_-7692250097086650299styled-by-prettify"> </span><span style=3D"color:=
#660" class=3D"m_-7692250097086650299styled-by-prettify">{</span><span styl=
e=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#800" class=3D"m_-769225009708665029=
9styled-by-prettify">// ...</span><span style=3D"color:#000" class=3D"m_-76=
92250097086650299styled-by-prettify"><br></span><span style=3D"color:#660" =
class=3D"m_-7692250097086650299styled-by-prettify">}</span><span style=3D"c=
olor:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br><br></spa=
n><span style=3D"color:#800" class=3D"m_-7692250097086650299styled-by-prett=
ify">// ...</span><span style=3D"color:#000" class=3D"m_-769225009708665029=
9styled-by-prettify"><br><br></span><span style=3D"color:#660" class=3D"m_-=
7692250097086650299styled-by-prettify">}</span><span style=3D"color:#000" c=
lass=3D"m_-7692250097086650299styled-by-prettify"><br><br></span><span styl=
e=3D"color:#800" class=3D"m_-7692250097086650299styled-by-prettify">// Usag=
e:</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled-b=
y-prettify"><br><br>ns</span><span style=3D"color:#660" class=3D"m_-7692250=
097086650299styled-by-prettify">::</span><span style=3D"color:#000" class=
=3D"m_-7692250097086650299styled-by-prettify">ranges</span><span style=3D"c=
olor:#660" class=3D"m_-7692250097086650299styled-by-prettify">::</span><spa=
n style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify">v=
iew</span><span style=3D"color:#660" class=3D"m_-7692250097086650299styled-=
by-prettify">(</span><span style=3D"color:#000" class=3D"m_-769225009708665=
0299styled-by-prettify">myRange</span><span style=3D"color:#660" class=3D"m=
_-7692250097086650299styled-by-prettify">)</span><span style=3D"color:#000"=
 class=3D"m_-7692250097086650299styled-by-prettify"><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prett=
ify">.</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styl=
ed-by-prettify">transform</span><span style=3D"color:#660" class=3D"m_-7692=
250097086650299styled-by-prettify">(...)</span><span style=3D"color:#000" c=
lass=3D"m_-7692250097086650299styled-by-prettify"><br>=C2=A0 =C2=A0 </span>=
<span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettif=
y">.</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled=
-by-prettify">accumulate</span><span style=3D"color:#660" class=3D"m_-76922=
50097086650299styled-by-prettify">(...);</span><span style=3D"color:#000" c=
lass=3D"m_-7692250097086650299styled-by-prettify"><br><br></span><span styl=
e=3D"color:#800" class=3D"m_-7692250097086650299styled-by-prettify">// Exte=
nding with my own algorithms:</span><span style=3D"color:#000" class=3D"m_-=
7692250097086650299styled-by-prettify"><br><br></span><span style=3D"color:=
#008" class=3D"m_-7692250097086650299styled-by-prettify">namespace</span><s=
pan style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"=
> user </span><span style=3D"color:#660" class=3D"m_-7692250097086650299sty=
led-by-prettify">{</span><span style=3D"color:#000" class=3D"m_-76922500970=
86650299styled-by-prettify"><br><br></span><span style=3D"color:#008" class=
=3D"m_-7692250097086650299styled-by-prettify">template</span><span style=3D=
"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"> </span><sp=
an style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify">=
&lt;</span><span style=3D"color:#008" class=3D"m_-7692250097086650299styled=
-by-prettify">typename</span><span style=3D"color:#000" class=3D"m_-7692250=
097086650299styled-by-prettify"> </span><span style=3D"color:#606" class=3D=
"m_-7692250097086650299styled-by-prettify">Range</span><span style=3D"color=
:#660" class=3D"m_-7692250097086650299styled-by-prettify">&gt;</span><span =
style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br=
></span><span style=3D"color:#008" class=3D"m_-7692250097086650299styled-by=
-prettify">struct</span><span style=3D"color:#000" class=3D"m_-769225009708=
6650299styled-by-prettify"> my_view<br>=C2=A0 =C2=A0 </span><span style=3D"=
color:#660" class=3D"m_-7692250097086650299styled-by-prettify">:</span><spa=
n style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"> =
</span><span style=3D"color:#008" class=3D"m_-7692250097086650299styled-by-=
prettify">private</span><span style=3D"color:#000" class=3D"m_-769225009708=
6650299styled-by-prettify"> ns</span><span style=3D"color:#660" class=3D"m_=
-7692250097086650299styled-by-prettify">::</span><span style=3D"color:#000"=
 class=3D"m_-7692250097086650299styled-by-prettify">ranges</span><span styl=
e=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify">::</spa=
n><span style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prett=
ify">adl_tag </span><span style=3D"color:#800" class=3D"m_-7692250097086650=
299styled-by-prettify">// allow ADL to look into ns::ranges</span><span sty=
le=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br></=
span><span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-pr=
ettify">{</span><span style=3D"color:#000" class=3D"m_-7692250097086650299s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#800" clas=
s=3D"m_-7692250097086650299styled-by-prettify">// ...</span><span style=3D"=
color:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br></span><=
span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify=
">};</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled=
-by-prettify"><br><br></span><span style=3D"color:#008" class=3D"m_-7692250=
097086650299styled-by-prettify">template</span><span style=3D"color:#000" c=
lass=3D"m_-7692250097086650299styled-by-prettify"> </span><span style=3D"co=
lor:#660" class=3D"m_-7692250097086650299styled-by-prettify">&lt;</span><sp=
an style=3D"color:#008" class=3D"m_-7692250097086650299styled-by-prettify">=
typename</span><span style=3D"color:#000" class=3D"m_-7692250097086650299st=
yled-by-prettify"> T</span><span style=3D"color:#660" class=3D"m_-769225009=
7086650299styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m=
_-7692250097086650299styled-by-prettify"> </span><span style=3D"color:#008"=
 class=3D"m_-7692250097086650299styled-by-prettify">typename</span><span st=
yle=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"> F</s=
pan><span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-pre=
ttify">&gt;</span><span style=3D"color:#000" class=3D"m_-769225009708665029=
9styled-by-prettify"><br></span><span style=3D"color:#008" class=3D"m_-7692=
250097086650299styled-by-prettify">auto</span><span style=3D"color:#000" cl=
ass=3D"m_-7692250097086650299styled-by-prettify"> my_fancy_algorithm</span>=
<span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettif=
y">(</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled=
-by-prettify">T</span><span style=3D"color:#660" class=3D"m_-76922500970866=
50299styled-by-prettify">&amp;&amp;</span><span style=3D"color:#000" class=
=3D"m_-7692250097086650299styled-by-prettify"> </span><span style=3D"color:=
#008" class=3D"m_-7692250097086650299styled-by-prettify">this</span><span s=
tyle=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"> </s=
pan><span style=3D"color:#008" class=3D"m_-7692250097086650299styled-by-pre=
ttify">self</span><span style=3D"color:#660" class=3D"m_-769225009708665029=
9styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_-7692250=
097086650299styled-by-prettify"> F</span><span style=3D"color:#660" class=
=3D"m_-7692250097086650299styled-by-prettify">&amp;&amp;</span><span style=
=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"> fn</spa=
n><span style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prett=
ify">)</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styl=
ed-by-prettify"> </span><span style=3D"color:#660" class=3D"m_-769225009708=
6650299styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_-7=
692250097086650299styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#800" class=3D"m_-7692250097086650299styled-by-prettify">// ...</=
span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-pr=
ettify"><br></span><span style=3D"color:#660" class=3D"m_-76922500970866502=
99styled-by-prettify">}</span><span style=3D"color:#000" class=3D"m_-769225=
0097086650299styled-by-prettify"><br><br></span><span style=3D"color:#660" =
class=3D"m_-7692250097086650299styled-by-prettify">}</span><span style=3D"c=
olor:#000" class=3D"m_-7692250097086650299styled-by-prettify"><br><br></spa=
n><span style=3D"color:#800" class=3D"m_-7692250097086650299styled-by-prett=
ify">// Usage:</span><span style=3D"color:#000" class=3D"m_-769225009708665=
0299styled-by-prettify"><br><br>user</span><span style=3D"color:#660" class=
=3D"m_-7692250097086650299styled-by-prettify">::</span><span style=3D"color=
:#000" class=3D"m_-7692250097086650299styled-by-prettify">my_view</span><sp=
an style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify">=
(</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled-by=
-prettify">myRange</span><span style=3D"color:#660" class=3D"m_-76922500970=
86650299styled-by-prettify">)</span><span style=3D"color:#000" class=3D"m_-=
7692250097086650299styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify">.</span>=
<span style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettif=
y">transform</span><span style=3D"color:#660" class=3D"m_-76922500970866502=
99styled-by-prettify">(...)</span><span style=3D"color:#000" class=3D"m_-76=
92250097086650299styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#800" class=3D"m_-7692250097086650299styled-by-prettify">// Barri=
ng type erasure, we can still find my_fancy_algorithm since the</span><span=
 style=3D"color:#000" class=3D"m_-7692250097086650299styled-by-prettify"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#800" class=3D"m_-7692250097086=
650299styled-by-prettify">//=C2=A0</span><span style=3D"color:rgb(136,0,0);=
font-family:arial,sans-serif">user::my_view type is encoded=C2=A0</span><sp=
an style=3D"color:rgb(136,0,0);font-family:arial,sans-serif">into the templ=
ate type somewhere</span></div><div class=3D"m_-7692250097086650299subprett=
yprint"><span style=3D"color:#000" class=3D"m_-7692250097086650299styled-by=
-prettify">=C2=A0 =C2=A0 </span><span style=3D"color:#660" class=3D"m_-7692=
250097086650299styled-by-prettify">.</span><span style=3D"color:#000" class=
=3D"m_-7692250097086650299styled-by-prettify">my_fancy_algorithm</span><spa=
n style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify">(=
....)</span><span style=3D"color:#000" class=3D"m_-7692250097086650299styled=
-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660" class=3D"=
m_-7692250097086650299styled-by-prettify">.</span><span style=3D"color:#000=
" class=3D"m_-7692250097086650299styled-by-prettify">accumulate</span><span=
 style=3D"color:#660" class=3D"m_-7692250097086650299styled-by-prettify">(.=
...);</span></div></code></div></div><div><font face=3D"arial, sans-serif"><=
br></font></div><div><font face=3D"arial, sans-serif"><br></font></div><div=
><font face=3D"arial, sans-serif">Problems that have yet to be addressed:</=
font></div><div><ul><li><font face=3D"arial, sans-serif">In the definition =
of a class method, does </font><font face=3D"courier new, monospace">this-&=
gt;foo(...)</font><font face=3D"arial, sans-serif"> consider extension meth=
ods in overload resolution? Why or why not?</font></li><li><font face=3D"ar=
ial, sans-serif">Outside of the definition of a class method, does </font><=
font face=3D"courier new, monospace">foo.bar(...)</font><font face=3D"arial=
, sans-serif"> consider both extension methods and member functions in over=
load resolution? Why or why not? (I think it should overload both; if the m=
ember function doesn&#39;t exist, it should be able to fall back on extensi=
on methods)</font></li><li><font face=3D"arial, sans-serif">Should qualifie=
d function calls be allowed? That is, should I be able to write </font><fon=
t face=3D"courier new, monospace">foo.std::ranges::transform(...<wbr>)</fon=
t><font face=3D"arial, sans-serif">? This would be consistent with member f=
unctions; I can already write </font><font face=3D"courier new, monospace">=
string.std::string::size()</font><font face=3D"arial, sans-serif">. If we a=
llow this, should this be able to call extension methods from arbitrary nam=
espaces, not just ones that can be found via ADL?</font></li><li><font face=
=3D"arial, sans-serif">Is this a reasonable restriction level? If the libra=
ry implementer does not put all the extension methods in their own namespac=
e with a wrapper that brings them into context, it could get out of hand fa=
st. Granted, this would be no different from using unqualified prefix funct=
ion calls.</font></li></ul></div></div><span class=3D"HOEnZb"><font color=
=3D"#888888">

<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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7ce23f53-d00e-45a0-a62b-c42060c5833d%=
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/7ce2=
3f53-d00e-45a0-<wbr>a62b-c42060c5833d%40isocpp.org</a><wbr>.<br>
</font></span></blockquote></div><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/CAANG%3DkVgcf9o1K8dGVKj4_ECQRC_UmJXB%=
3D_NFOo%3DLymMMsP6yQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkVg=
cf9o1K8dGVKj4_ECQRC_UmJXB%3D_NFOo%3DLymMMsP6yQ%40mail.gmail.com</a>.<br />

--0000000000000868a505729a6a53--

.


Author: yakitori1010@gmail.com
Date: Sat, 11 Aug 2018 14:41:03 -0700 (PDT)
Raw View
------=_Part_1101_1701983629.1534023664112
Content-Type: multipart/alternative;
 boundary="----=_Part_1102_1540946120.1534023664112"

------=_Part_1102_1540946120.1534023664112
Content-Type: text/plain; charset="UTF-8"

hello.

i hope and want function chainning method.
but i grasp think to one of big problem.
it is look up time for type T.
i want to chainning the template function.
now we not have to force function direction.
T is any type at first time.
it  makes suggest explosion.
maybe need clear it.
and that's clear facter is concept.maybe...

and other.why i want it.
i want to make utility for time to time.
i am basicaly user code writer.
the this pointer is not important.
and i like that looks.it's importnt.

if jamimng the libraryan's mind to must need this pointer.
to hope safe use to not open the this pointer.and i am not needed.
if truely need this pointer to inherit it.

we have hint to call with namespace.this is user defined literal.
i grasp remenber to it is user need use using.maybe...
why refer it.it is total rule.
if you not have strongly reason. i suggest to stand by manner.

last.
i am not native english.sorry.
thank you.

--
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/52a0fc45-b46a-4589-ae9d-6d93fdfb813d%40isocpp.org.

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

<div dir=3D"ltr"><div>hello.</div><div><br></div><div>i hope and want funct=
ion chainning method.</div><div>but i grasp think to one of big problem.</d=
iv><div>it is look up time for type T.</div><div>i want to chainning the te=
mplate function.</div><div>now we not have to force function direction.</di=
v><div>T is any type at first time.</div><div>it=C2=A0 makes suggest explos=
ion.</div><div>maybe need clear it.=C2=A0</div><div>and that&#39;s clear fa=
cter is concept.maybe...</div><div><br></div><div>and other.why i want it.<=
/div><div>i want to make utility for time to time.</div><div>i am basicaly =
user code writer.</div><div>the this pointer is not important.</div><div>an=
d i like that looks.it&#39;s importnt.</div><div><br></div><div>if jamimng =
the libraryan&#39;s mind to must need this pointer.</div><div>to hope safe =
use to not open the this pointer.and i am not needed.</div><div>if truely n=
eed this pointer to inherit it.</div><div><br></div><div>we have hint to ca=
ll with namespace.this is user defined literal.</div><div><span style=3D"di=
splay: inline !important; float: none; background-color: transparent; color=
: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decor=
ation: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wi=
dth: 0px; white-space: normal; word-spacing: 0px;">i grasp remenber to it i=
s user need use using.maybe...</span></div><div>why refer it.it is total ru=
le.</div><div>if you not have strongly reason. i suggest to stand by manner=
..</div><div><br></div><div>last.</div><div>i am not native english.sorry.</=
div><div>thank you.</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/52a0fc45-b46a-4589-ae9d-6d93fdfb813d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/52a0fc45-b46a-4589-ae9d-6d93fdfb813d=
%40isocpp.org</a>.<br />

------=_Part_1102_1540946120.1534023664112--

------=_Part_1101_1701983629.1534023664112--

.