Topic: Standardize use of tail-call optimization


Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Tue, 29 May 2018 13:25:22 -0700 (PDT)
Raw View
------=_Part_22058_912588883.1527625522757
Content-Type: multipart/alternative;
 boundary="----=_Part_22059_476680886.1527625522758"

------=_Part_22059_476680886.1527625522758
Content-Type: text/plain; charset="UTF-8"

*Proposal: *Tail-call optimization is a standard feature of many
programming languages, and is already supported by the main C++ compilers
(when optimizations are enabled). We should standardize it's use to make
code that relies on recursion *safer* and *more reliable*.

*Example code: *

template<class F, class sum_t = int>
auto Sum(size_t start, size_t end, F&& f, sum_t partial_sum = 0)
{
   if(start == end)
        return partial_sum + f(start);
   else
        return Sum(start + 1, end, f, partial_sum + f(start));
};

This code calculates the sum of f(i) over the range [start, end] using
recursion.

*With optimization enabled,* both GCC and Clang produce machine code that
is equally performant to the procedural version of the sum (O2 and above),
although *without optimization*, the program segfaults due to running out
of space on the stack. (For the test I used a function which returned the
square of it's input).

Tail call recursion is a well-understood optimization. It has a history of
use in other languages, and since many compilers already support it as one
of a number of possible optimizations, requiring it's use won't by an
unnecessary burden to the people writing our compilers. *If it works with
optimization enabled, well-defined and standard compliant code shouldn't
break when compiled without optimization. *

*Benefits:*

   - Makes recursive code faster and more reliable
   - Reduces usage of the stack
   - Aligns with the C++ philosophy of cost-free abstraction
   - Won't break any old code

--
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/a69afdc5-8f1a-4628-a08d-49b6c1810b57%40isocpp.org.

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

<div dir=3D"ltr"><b>Proposal:=C2=A0</b>Tail-call optimization is a standard=
 feature of many programming languages, and is already supported by the mai=
n C++ compilers (when optimizations are enabled). We should standardize it&=
#39;s use to make code that relies on recursion <u>safer</u> and <u>more re=
liable</u>.=C2=A0<div><br></div><div><b>Example code:=C2=A0</b></div><div><=
br></div><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187=
, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><div style=3D"font-family: Menlo, Monaco, &quot;Courier=
 New&quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre=
; background-color: rgb(255, 255, 255);"><div style=3D"color: rgb(212, 212,=
 212);"><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">template</span></span><span style=3D"colo=
r: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;</span></span><span style=3D"color: rgb(116, 151, 145);"><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">class</span></span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: rgb(174, 238, 149);"><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">F</span></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: rgb(116, 151, 145);"><span style=3D"color: #=
008;" class=3D"styled-by-prettify">class</span></span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(174,=
 238, 149);"><span style=3D"color: #000;" class=3D"styled-by-prettify">sum_=
t</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</span></span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(116, 151,=
 145);"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span=
></span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span></span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span></div><div style=3D"color: rgb(2=
12, 212, 212);"><span style=3D"color: rgb(116, 151, 145);"><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span></span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rg=
b(139, 238, 217);"><span style=3D"color: #606;" class=3D"styled-by-prettify=
">Sum</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: rgb(174, 238, 149);"><span style=3D"color: =
#000;" class=3D"styled-by-prettify">size_t</span></span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> start</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: rgb(174, 238, 149);=
"><span style=3D"color: #000;" class=3D"styled-by-prettify">size_t</span></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n 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"> F</span><span style=3D"color: rgb(12=
9, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">&a=
mp;&amp;</span></span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: rgb(174, 238, 149);"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">sum_t</span></span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> partial_sum </span><span style=3D"color: rgb(129=
, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" =
class=3D"styled-by-prettify">0</span></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span></div><div style=3D"color: rgb(212, 212, 212);"><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span></div><div=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</=
span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">if</span></span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">start </span><font color=3D"#666600"><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D=3D</span></font><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;" c=
lass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> <br></span><span style=3D"color: rgb(116, 151, 145);"><=
span style=3D"color: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>return</span></span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> partial_sum </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">+</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">start</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">);</span></div><div><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span>=
<span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">else</span></span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> <br></span><span style=3D"color: rgb(116, 151, =
145);"><span style=3D"color: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">return</span></span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: rgb(139, 238, 217);"><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Sum</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">start </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</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 styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> partial_sum </span><span style=3D"color: rg=
b(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify=
">+</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">f</span></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><font color=3D"#000088"><span style=
=3D"color: #000;" class=3D"styled-by-prettify">start</span></font><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">));</span></div><div style=
=3D"color: rgb(212, 212, 212);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span></div></div></div></code></div><br>This code calcul=
ates the sum of f(i) over the range [start, end] using recursion.</div><div=
><br></div><div><b>With optimization enabled,</b>=C2=A0both GCC and Clang p=
roduce machine code that is equally performant to the procedural version of=
 the sum (O2 and above), although <b>without optimization</b>, the program =
segfaults due to running out of space on the stack. (For the test I used a =
function which returned the square of it&#39;s input).=C2=A0</div><div><br>=
</div><div>Tail call recursion is a well-understood optimization. It has a =
history of use in other languages, and since many compilers already support=
 it as one of a number of possible optimizations, requiring it&#39;s use wo=
n&#39;t by an unnecessary burden to the people writing our compilers. <b>If=
 it works with optimization enabled, well-defined and standard compliant co=
de shouldn&#39;t break when compiled without optimization.=C2=A0</b><br></d=
iv><div><br></div><div><b>Benefits:</b></div><div><ul><li>Makes recursive c=
ode faster and more reliable</li><li>Reduces usage of the stack</li><li>Ali=
gns with the C++ philosophy of cost-free abstraction</li><li>Won&#39;t brea=
k any old code</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/a69afdc5-8f1a-4628-a08d-49b6c1810b57%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a69afdc5-8f1a-4628-a08d-49b6c1810b57=
%40isocpp.org</a>.<br />

------=_Part_22059_476680886.1527625522758--

------=_Part_22058_912588883.1527625522757--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 29 May 2018 13:35:25 -0700 (PDT)
Raw View
------=_Part_21686_863093129.1527626125172
Content-Type: multipart/alternative;
 boundary="----=_Part_21687_1506405312.1527626125172"

------=_Part_21687_1506405312.1527626125172
Content-Type: text/plain; charset="UTF-8"

So... what exactly is your proposal?

I use a language that has proper tail calls: Lua. In the language
specification is a set of rules that you have to follow to get a proper
tail call.

What rules do you propose that users should follow if they want to make a
tail call proper in C++?

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

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

<div dir=3D"ltr"><div>So... what exactly is your proposal?</div><div><br></=
div><div>I use a language that has proper tail calls: Lua. In the language =
specification is a set of rules that you have to follow to get a proper tai=
l call.</div><div><br></div><div>What rules do you propose that users shoul=
d follow if they want to make a tail call proper in C++?<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/b548def3-7a2b-4e89-9346-29618d0372fd%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b548def3-7a2b-4e89-9346-29618d0372fd=
%40isocpp.org</a>.<br />

------=_Part_21687_1506405312.1527626125172--

------=_Part_21686_863093129.1527626125172--

.


Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Tue, 29 May 2018 14:17:15 -0700 (PDT)
Raw View
------=_Part_40778_225941297.1527628635932
Content-Type: multipart/alternative;
 boundary="----=_Part_40779_1612460085.1527628635933"

------=_Part_40779_1612460085.1527628635933
Content-Type: text/plain; charset="UTF-8"

My proposal is that C++ compilers are required to perform tail-call
optimization when the final action of a procedure is a call to another
procedure provided that:

   - All remaining variables that would have been destroyed after the
   return call are trivially destructible,
   - are given to the function as an argument that is copy-by-value OR a
   universal reference (when a function returns an object, that object isn't
   destroyed in the function itself but in whichever scope originated the
   call. I propose variables passed in a tail-recursive call are treated
   similarly).
   - or can be safely destroyed prior to the tail call

 This last one is requires further specification. *Objects can't be
destroyed prior to the tail call if the object has side-effects that could
lead to a race condition when destroyed*, or if it's destruction would
invalidate data that is accessible once the tail call procedure is entered.

*Examples:*
void foo() {
    struct bar {
        ~bar() { std::cout << "Hello, world!" << std::endl;
    } myBar;
    foo(); //Tail call can't be optimized; destruction of myBar has
external side effects that may lead to race condition
}






*void foo(int* ptr) {    struct bar {        ~bar() { *ptr = 10; }    }
myBar;    foo(ptr); //Tail call can't be optimized; destruction of myBar
has external side effects that may lead to race condition}*

void foo() {
    std::vector<int> myVect = {1, 2, 3};
    foo(); //Tail call CAN be optimized; destruction of myVect doesn't have
external side effects that would lead to race condition
}

template<class T, class F>
void foo(T&& obj, F&& func) {
    func(obj);
    foo(obj, func); //Tail call CAN be optimized; obj and func don't get
destroyed in foo
}

template<class T>
void bar(T&& obj) {
    std::cout << obj << std::endl;
    std::string my_str = obj + std::string { "Hello" };
    bar(my_str); //Tail call CAN be optimized; compiler can transfer
ownership of my_str so it doesn't get destroyed in bar
}

(This is a first draft of what the rules could be)

--
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/ab49ce60-edf5-4abd-8397-8923dc7e7155%40isocpp.org.

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

<div dir=3D"ltr">My proposal is that C++ compilers are required to perform =
tail-call optimization when the final action of a procedure is a call to an=
other procedure provided that:<div><ul><li>All remaining variables that wou=
ld have been destroyed after the return call are trivially destructible,=C2=
=A0</li><li>are given to the function as an argument that is copy-by-value =
OR a universal reference (when a function returns an object, that object is=
n&#39;t destroyed in the function itself but in whichever scope originated =
the call. I propose variables passed in a tail-recursive call are treated s=
imilarly).=C2=A0</li><li>or can be safely destroyed prior to the tail call<=
/li></ul><div><div>=C2=A0This last one is requires further specification. <=
b>Objects can&#39;t be destroyed prior to the tail call if the object has s=
ide-effects that could lead to a race condition when destroyed</b>, or if i=
t&#39;s destruction would invalidate data that is accessible once the tail =
call procedure is entered.=C2=A0</div></div></div><div><br></div><div><b>Ex=
amples:</b></div><div><div class=3D"prettyprint" style=3D"font-weight: bold=
; background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187=
); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><font><span style=3D"color: #008;" class=3D"styled-by-prettify">v=
oid</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><spa=
n 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: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> bar </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 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">~</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">bar</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cout =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify">&quot;Hello, world!&q=
uot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span>=
<font color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"caret-color: rgb(102, 0, 102);"><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">endl</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span></span></font><span style=3D"colo=
r: #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"> myBar</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 foo</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: #800;" class=3D"=
styled-by-prettify">//Tail call can&#39;t be optimized; destruction of myBa=
r has external side effects that may lead to race condition</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">}</span></font></div></code></di=
v><div style=3D"font-weight: bold;"><b><br></b></div><div style=3D"font-wei=
ght: bold;"><b><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"=
><code class=3D"prettyprint"><div class=3D"subprettyprint" style=3D"caret-c=
olor: rgb(102, 0, 102);"><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> ptr</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</span><span 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"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> bar </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>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">~</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">bar</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><font color=3D"#666600"><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span 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">ptr </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">10</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">}</span></font><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> myBar</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 foo</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">ptr</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: #800;" class=3D"styled-by-prettify">//Tail call can&#=
39;t be optimized; destruction of myBar has external side effects that may =
lead to race condition</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">}</span></div></code></div></b></div><div style=3D"font-weight: bold;=
"><b><br></b></div><div class=3D"prettyprint" style=3D"font-weight: bold; b=
ackground-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); =
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpretty=
print" style=3D"caret-color: rgb(102, 0, 102);"><font color=3D"#660066"><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> foo</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: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">vector</span><span style=3D"color: #080;" class=3D"styl=
ed-by-prettify">&lt;int&gt;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> myVect </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><s=
pan 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=
: #066;" class=3D"styled-by-prettify">2</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: #066;" class=3D"styled-by=
-prettify">3</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 foo</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//Tail ca=
ll CAN be optimized; destruction of myVect doesn&#39;t have external side e=
ffects that would lead to race condition</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span></font></div></code></div><div style=3D"fon=
t-weight: bold;"><b><br></b></div><div class=3D"prettyprint" style=3D"font-=
weight: bold; background-color: rgb(250, 250, 250); border: 1px solid rgb(1=
87, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">template</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">cla=
ss</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">class</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> F</span><span style=3D"color: #660;" c=
lass=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"st=
yled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</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"> obj</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> func</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </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>=C2=A0 =C2=A0 func</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">obj</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 foo</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ob=
j</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> func</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: #=
800;" class=3D"styled-by-prettify">//Tail call CAN be optimized; obj and fu=
nc don&#39;t get destroyed in foo</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">template</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">c=
lass</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</sp=
an><font color=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;</span></font><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> obj</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: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">cout </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> obj </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">endl</sp=
an><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 std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">string</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> my_str </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> obj </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><font color=3D"#008800"><span style=3D"=
color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">string</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&qu=
ot;Hello&quot;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</s=
pan></font><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 bar</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><font color=3D"#000000"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">my_str</span></font><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">//Tail call CAN be optimized; compiler can transfer ownership of =
my_str so it doesn&#39;t get destroyed in bar</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">}</span></div></code></div><br>(This is a firs=
t draft of what the rules could be)</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/ab49ce60-edf5-4abd-8397-8923dc7e7155%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ab49ce60-edf5-4abd-8397-8923dc7e7155=
%40isocpp.org</a>.<br />

------=_Part_40779_1612460085.1527628635933--

------=_Part_40778_225941297.1527628635932--

.


Author: Nicolas Lesser <blitzrakete@gmail.com>
Date: Tue, 29 May 2018 23:20:02 +0200
Raw View
--000000000000c9675e056d5eccc8
Content-Type: text/plain; charset="UTF-8"

I don't think we should start to standardize optimizations that are already
valid under the as-if rule.

I don't really see the benefit in doing so. Compilers already implement
this optimization. If compiling without any optimization results in the
compiler not optimizing the recursion away, well that's the expected
behavior. Why do you want the compiler to optimize something away when you
explicitly ask it to not perform any optimization?

Also you say that it would make code "safer and more reliable", how so?
Safer maybe because you are not going to overflow your stack, but if you
are, then you should use a different algorithm. If the compiler transforms
your stack usage heavy algorithm to a more stack friendly one, that's great
but we should not require the compiler to do so.

Another related question might be: Where do we draw the line? Should we
require most optimizations that compilers do mandatory just so that we have
faster (unoptimized - i.e. with no optimum optimization flags) code that is
already generated with appropriate optimization flags?

What benefit does your proposal bring? Because as far as I can see, the
only benefit would be to have faster unoptimized code, which is a bit weird.

On Tue, May 29, 2018, 10:25 PM Antonio Perez <antonio@perezexcelsior.com>
wrote:

> *Proposal: *Tail-call optimization is a standard feature of many
> programming languages, and is already supported by the main C++ compilers
> (when optimizations are enabled). We should standardize it's use to make
> code that relies on recursion *safer* and *more reliable*.
>
> *Example code: *
>
> template<class F, class sum_t = int>
> auto Sum(size_t start, size_t end, F&& f, sum_t partial_sum = 0)
> {
>    if(start == end)
>         return partial_sum + f(start);
>    else
>         return Sum(start + 1, end, f, partial_sum + f(start));
> };
>
> This code calculates the sum of f(i) over the range [start, end] using
> recursion.
>
> *With optimization enabled,* both GCC and Clang produce machine code that
> is equally performant to the procedural version of the sum (O2 and above),
> although *without optimization*, the program segfaults due to running out
> of space on the stack. (For the test I used a function which returned the
> square of it's input).
>
> Tail call recursion is a well-understood optimization. It has a history of
> use in other languages, and since many compilers already support it as one
> of a number of possible optimizations, requiring it's use won't by an
> unnecessary burden to the people writing our compilers. *If it works with
> optimization enabled, well-defined and standard compliant code shouldn't
> break when compiled without optimization. *
>
> *Benefits:*
>
>    - Makes recursive code faster and more reliable
>    - Reduces usage of the stack
>    - Aligns with the C++ philosophy of cost-free abstraction
>    - Won't break any old code
>
> --
> 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/a69afdc5-8f1a-4628-a08d-49b6c1810b57%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a69afdc5-8f1a-4628-a08d-49b6c1810b57%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CALmDwq3K0ffwpUs46VtRWOmYdR%2B8s4G2EX-VNVRAcHj-Wy1PDQ%40mail.gmail.com.

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

<div dir=3D"auto">I don&#39;t think we should start to standardize optimiza=
tions that are already valid under the as-if rule.<div dir=3D"auto"><br></d=
iv><div dir=3D"auto">I don&#39;t really see the benefit in doing so. Compil=
ers already implement this optimization. If compiling without any optimizat=
ion results in the compiler not optimizing the recursion away, well that&#3=
9;s the expected behavior. Why do you want the compiler to optimize somethi=
ng away when you explicitly ask it to not perform any optimization?<br></di=
v><div dir=3D"auto"><br></div><div dir=3D"auto">Also you say that it would =
make code &quot;safer and more reliable&quot;, how so? Safer maybe because =
you are not going to overflow your stack, but if you are, then you should u=
se a different algorithm. If the compiler transforms your stack usage heavy=
 algorithm to a more stack friendly one, that&#39;s great but we should not=
 require the compiler to do so.</div><div dir=3D"auto"><br></div><div dir=
=3D"auto">Another related question might be: Where do we draw the line? Sho=
uld we require most optimizations that compilers do mandatory just so that =
we have faster (unoptimized - i.e. with no optimum optimization flags) code=
 that is already generated with appropriate optimization flags?</div><div d=
ir=3D"auto"><br></div><div dir=3D"auto">What benefit does your proposal bri=
ng? Because as far as I can see, the only benefit would be to have faster u=
noptimized code, which is a bit weird.</div></div><br><div class=3D"gmail_q=
uote"><div dir=3D"ltr">On Tue, May 29, 2018, 10:25 PM Antonio Perez &lt;<a =
href=3D"mailto:antonio@perezexcelsior.com" rel=3D"noreferrer noreferrer nor=
eferrer noreferrer noreferrer noreferrer noreferrer" target=3D"_blank">anto=
nio@perezexcelsior.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><b>Proposal:=C2=A0</b>Tail-call optimization is a stand=
ard feature of many programming languages, and is already supported by the =
main C++ compilers (when optimizations are enabled). We should standardize =
it&#39;s use to make code that relies on recursion <u>safer</u> and <u>more=
 reliable</u>.=C2=A0<div><br></div><div><b>Example code:=C2=A0</b></div><di=
v><br></div><div><div class=3D"m_317489642134780931m_-5868171486550583864m_=
-7846267993825401439m_-647208999166993943m_4996917809552376415m_45821576666=
41291293m_-2577808990818708883m_-7333618902031481816prettyprint" style=3D"b=
order:1px solid rgb(187,187,187);word-wrap:break-word"><code class=3D"m_317=
489642134780931m_-5868171486550583864m_-7846267993825401439m_-6472089991669=
93943m_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-733=
3618902031481816prettyprint"><div class=3D"m_317489642134780931m_-586817148=
6550583864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m=
_4582157666641291293m_-2577808990818708883m_-7333618902031481816subprettypr=
int"><div style=3D"font-family:Menlo,Monaco,&quot;Courier New&quot;,monospa=
ce;font-size:12px;line-height:18px;white-space:pre-wrap;background-color:rg=
b(255,255,255)"><div style=3D"color:rgb(212,212,212)"><span style=3D"color:=
rgb(116,151,145)"><span style=3D"color:#008" class=3D"m_317489642134780931m=
_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_499691780=
9552376415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816=
styled-by-prettify">template</span></span><span style=3D"color:rgb(129,198,=
190)"><span style=3D"color:#660" class=3D"m_317489642134780931m_-5868171486=
550583864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_=
4582157666641291293m_-2577808990818708883m_-7333618902031481816styled-by-pr=
ettify">&lt;</span></span><span style=3D"color:rgb(116,151,145)"><span styl=
e=3D"color:#008" class=3D"m_317489642134780931m_-5868171486550583864m_-7846=
267993825401439m_-647208999166993943m_4996917809552376415m_4582157666641291=
293m_-2577808990818708883m_-7333618902031481816styled-by-prettify">class</s=
pan></span><span style=3D"color:#000" class=3D"m_317489642134780931m_-58681=
71486550583864m_-7846267993825401439m_-647208999166993943m_4996917809552376=
415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816styled-=
by-prettify"> </span><span style=3D"color:rgb(174,238,149)"><span style=3D"=
color:#000" class=3D"m_317489642134780931m_-5868171486550583864m_-784626799=
3825401439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_=
-2577808990818708883m_-7333618902031481816styled-by-prettify">F</span></spa=
n><span style=3D"color:#660" class=3D"m_317489642134780931m_-58681714865505=
83864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_4582=
157666641291293m_-2577808990818708883m_-7333618902031481816styled-by-pretti=
fy">,</span><span style=3D"color:#000" class=3D"m_317489642134780931m_-5868=
171486550583864m_-7846267993825401439m_-647208999166993943m_499691780955237=
6415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816styled=
-by-prettify"> </span><span style=3D"color:rgb(116,151,145)"><span style=3D=
"color:#008" class=3D"m_317489642134780931m_-5868171486550583864m_-78462679=
93825401439m_-647208999166993943m_4996917809552376415m_4582157666641291293m=
_-2577808990818708883m_-7333618902031481816styled-by-prettify">class</span>=
</span><span style=3D"color:#000" class=3D"m_317489642134780931m_-586817148=
6550583864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m=
_4582157666641291293m_-2577808990818708883m_-7333618902031481816styled-by-p=
rettify"> </span><span style=3D"color:rgb(174,238,149)"><span style=3D"colo=
r:#000" class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825=
401439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-257=
7808990818708883m_-7333618902031481816styled-by-prettify">sum_t</span></spa=
n><span style=3D"color:#000" class=3D"m_317489642134780931m_-58681714865505=
83864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_4582=
157666641291293m_-2577808990818708883m_-7333618902031481816styled-by-pretti=
fy"> </span><span style=3D"color:rgb(129,198,190)"><span style=3D"color:#66=
0" class=3D"m_317489642134780931m_-5868171486550583864m_-784626799382540143=
9m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-25778089=
90818708883m_-7333618902031481816styled-by-prettify">=3D</span></span><span=
 style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550583864m_=
-7846267993825401439m_-647208999166993943m_4996917809552376415m_45821576666=
41291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify"> </=
span><span style=3D"color:rgb(116,151,145)"><span style=3D"color:#008" clas=
s=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439m_-647=
208999166993943m_4996917809552376415m_4582157666641291293m_-257780899081870=
8883m_-7333618902031481816styled-by-prettify">int</span></span><span style=
=3D"color:rgb(129,198,190)"><span style=3D"color:#660" class=3D"m_317489642=
134780931m_-5868171486550583864m_-7846267993825401439m_-647208999166993943m=
_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-733361890=
2031481816styled-by-prettify">&gt;</span></span><span style=3D"color:#000" =
class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439m_=
-647208999166993943m_4996917809552376415m_4582157666641291293m_-25778089908=
18708883m_-7333618902031481816styled-by-prettify"> </span></div><div style=
=3D"color:rgb(212,212,212)"><span style=3D"color:rgb(116,151,145)"><span st=
yle=3D"color:#008" class=3D"m_317489642134780931m_-5868171486550583864m_-78=
46267993825401439m_-647208999166993943m_4996917809552376415m_45821576666412=
91293m_-2577808990818708883m_-7333618902031481816styled-by-prettify">auto</=
span></span><span style=3D"color:#000" class=3D"m_317489642134780931m_-5868=
171486550583864m_-7846267993825401439m_-647208999166993943m_499691780955237=
6415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816styled=
-by-prettify"> </span><span style=3D"color:rgb(139,238,217)"><span style=3D=
"color:#606" class=3D"m_317489642134780931m_-5868171486550583864m_-78462679=
93825401439m_-647208999166993943m_4996917809552376415m_4582157666641291293m=
_-2577808990818708883m_-7333618902031481816styled-by-prettify">Sum</span></=
span><span style=3D"color:#660" class=3D"m_317489642134780931m_-58681714865=
50583864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_4=
582157666641291293m_-2577808990818708883m_-7333618902031481816styled-by-pre=
ttify">(</span><span style=3D"color:rgb(174,238,149)"><span style=3D"color:=
#000" class=3D"m_317489642134780931m_-5868171486550583864m_-784626799382540=
1439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-25778=
08990818708883m_-7333618902031481816styled-by-prettify">size_t</span></span=
><span style=3D"color:#000" class=3D"m_317489642134780931m_-586817148655058=
3864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_45821=
57666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettif=
y"> start</span><span style=3D"color:#660" class=3D"m_317489642134780931m_-=
5868171486550583864m_-7846267993825401439m_-647208999166993943m_49969178095=
52376415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816st=
yled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_31748964213=
4780931m_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_4=
996917809552376415m_4582157666641291293m_-2577808990818708883m_-73336189020=
31481816styled-by-prettify"> </span><span style=3D"color:rgb(174,238,149)">=
<span style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550583=
864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_458215=
7666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify=
">size_t</span></span><span style=3D"color:#000" class=3D"m_317489642134780=
931m_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_49969=
17809552376415m_4582157666641291293m_-2577808990818708883m_-733361890203148=
1816styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_31748=
9642134780931m_-5868171486550583864m_-7846267993825401439m_-647208999166993=
943m_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-73336=
18902031481816styled-by-prettify">end</span><span style=3D"color:#660" clas=
s=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439m_-647=
208999166993943m_4996917809552376415m_4582157666641291293m_-257780899081870=
8883m_-7333618902031481816styled-by-prettify">,</span><span style=3D"color:=
#000" class=3D"m_317489642134780931m_-5868171486550583864m_-784626799382540=
1439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-25778=
08990818708883m_-7333618902031481816styled-by-prettify"> F</span><span styl=
e=3D"color:rgb(129,198,190)"><span style=3D"color:#660" class=3D"m_31748964=
2134780931m_-5868171486550583864m_-7846267993825401439m_-647208999166993943=
m_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-73336189=
02031481816styled-by-prettify">&amp;&amp;</span></span><span style=3D"color=
:#000" class=3D"m_317489642134780931m_-5868171486550583864m_-78462679938254=
01439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-2577=
808990818708883m_-7333618902031481816styled-by-prettify"> f</span><span sty=
le=3D"color:#660" class=3D"m_317489642134780931m_-5868171486550583864m_-784=
6267993825401439m_-647208999166993943m_4996917809552376415m_458215766664129=
1293m_-2577808990818708883m_-7333618902031481816styled-by-prettify">,</span=
><span style=3D"color:#000" class=3D"m_317489642134780931m_-586817148655058=
3864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_45821=
57666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettif=
y"> </span><span style=3D"color:rgb(174,238,149)"><span style=3D"color:#000=
" class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439=
m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-257780899=
0818708883m_-7333618902031481816styled-by-prettify">sum_t</span></span><spa=
n style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550583864m=
_-7846267993825401439m_-647208999166993943m_4996917809552376415m_4582157666=
641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify"> p=
artial_sum </span><span style=3D"color:rgb(129,198,190)"><span style=3D"col=
or:#660" class=3D"m_317489642134780931m_-5868171486550583864m_-784626799382=
5401439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-25=
77808990818708883m_-7333618902031481816styled-by-prettify">=3D</span></span=
><span style=3D"color:#000" class=3D"m_317489642134780931m_-586817148655058=
3864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_45821=
57666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettif=
y"> </span><span style=3D"color:rgb(0,255,255)"><span style=3D"color:#066" =
class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439m_=
-647208999166993943m_4996917809552376415m_4582157666641291293m_-25778089908=
18708883m_-7333618902031481816styled-by-prettify">0</span></span><span styl=
e=3D"color:#660" class=3D"m_317489642134780931m_-5868171486550583864m_-7846=
267993825401439m_-647208999166993943m_4996917809552376415m_4582157666641291=
293m_-2577808990818708883m_-7333618902031481816styled-by-prettify">)</span>=
<span style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550583=
864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_458215=
7666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify=
"> </span></div><div style=3D"color:rgb(212,212,212)"><span style=3D"color:=
#660" class=3D"m_317489642134780931m_-5868171486550583864m_-784626799382540=
1439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-25778=
08990818708883m_-7333618902031481816styled-by-prettify">{</span></div><div>=
<span style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550583=
864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_458215=
7666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify=
"> =C2=A0 =C2=A0</span><span style=3D"color:rgb(116,151,145)"><span style=
=3D"color:#008" class=3D"m_317489642134780931m_-5868171486550583864m_-78462=
67993825401439m_-647208999166993943m_4996917809552376415m_45821576666412912=
93m_-2577808990818708883m_-7333618902031481816styled-by-prettify">if</span>=
</span><span style=3D"color:#660" class=3D"m_317489642134780931m_-586817148=
6550583864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m=
_4582157666641291293m_-2577808990818708883m_-7333618902031481816styled-by-p=
rettify">(</span><span style=3D"color:#000" class=3D"m_317489642134780931m_=
-5868171486550583864m_-7846267993825401439m_-647208999166993943m_4996917809=
552376415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816s=
tyled-by-prettify">start </span><font color=3D"#666600"><span style=3D"colo=
r:#660" class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825=
401439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-257=
7808990818708883m_-7333618902031481816styled-by-prettify">=3D=3D</span></fo=
nt><span style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550=
583864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_458=
2157666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prett=
ify"> </span><span style=3D"color:#008" class=3D"m_317489642134780931m_-586=
8171486550583864m_-7846267993825401439m_-647208999166993943m_49969178095523=
76415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816style=
d-by-prettify">end</span><span style=3D"color:#660" class=3D"m_317489642134=
780931m_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_49=
96917809552376415m_4582157666641291293m_-2577808990818708883m_-733361890203=
1481816styled-by-prettify">)</span><span style=3D"color:#000" class=3D"m_31=
7489642134780931m_-5868171486550583864m_-7846267993825401439m_-647208999166=
993943m_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-73=
33618902031481816styled-by-prettify"> <br></span><span style=3D"color:rgb(1=
16,151,145)"><span style=3D"color:#000" class=3D"m_317489642134780931m_-586=
8171486550583864m_-7846267993825401439m_-647208999166993943m_49969178095523=
76415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816style=
d-by-prettify">=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008=
" class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439=
m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-257780899=
0818708883m_-7333618902031481816styled-by-prettify">return</span></span><sp=
an style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550583864=
m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_458215766=
6641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify"> =
partial_sum </span><span style=3D"color:#660" class=3D"m_317489642134780931=
m_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_49969178=
09552376415m_4582157666641291293m_-2577808990818708883m_-733361890203148181=
6styled-by-prettify">+</span><span style=3D"color:#000" class=3D"m_31748964=
2134780931m_-5868171486550583864m_-7846267993825401439m_-647208999166993943=
m_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-73336189=
02031481816styled-by-prettify"> f</span><span style=3D"color:#660" class=3D=
"m_317489642134780931m_-5868171486550583864m_-7846267993825401439m_-6472089=
99166993943m_4996917809552376415m_4582157666641291293m_-2577808990818708883=
m_-7333618902031481816styled-by-prettify">(</span><span style=3D"color:#000=
" class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439=
m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-257780899=
0818708883m_-7333618902031481816styled-by-prettify">start</span><span style=
=3D"color:#660" class=3D"m_317489642134780931m_-5868171486550583864m_-78462=
67993825401439m_-647208999166993943m_4996917809552376415m_45821576666412912=
93m_-2577808990818708883m_-7333618902031481816styled-by-prettify">);</span>=
</div><div><span style=3D"color:#000" class=3D"m_317489642134780931m_-58681=
71486550583864m_-7846267993825401439m_-647208999166993943m_4996917809552376=
415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816styled-=
by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color:rgb(116,151,145)"><s=
pan style=3D"color:#008" class=3D"m_317489642134780931m_-586817148655058386=
4m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_45821576=
66641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify">=
else</span></span><span style=3D"color:#000" class=3D"m_317489642134780931m=
_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_499691780=
9552376415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816=
styled-by-prettify"> <br></span><span style=3D"color:rgb(116,151,145)"><spa=
n style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550583864m=
_-7846267993825401439m_-647208999166993943m_4996917809552376415m_4582157666=
641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"m_31=
7489642134780931m_-5868171486550583864m_-7846267993825401439m_-647208999166=
993943m_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-73=
33618902031481816styled-by-prettify">return</span></span><span style=3D"col=
or:#000" class=3D"m_317489642134780931m_-5868171486550583864m_-784626799382=
5401439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-25=
77808990818708883m_-7333618902031481816styled-by-prettify"> </span><span st=
yle=3D"color:rgb(139,238,217)"><span style=3D"color:#606" class=3D"m_317489=
642134780931m_-5868171486550583864m_-7846267993825401439m_-6472089991669939=
43m_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-733361=
8902031481816styled-by-prettify">Sum</span></span><span style=3D"color:#660=
" class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439=
m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-257780899=
0818708883m_-7333618902031481816styled-by-prettify">(</span><span style=3D"=
color:#000" class=3D"m_317489642134780931m_-5868171486550583864m_-784626799=
3825401439m_-647208999166993943m_4996917809552376415m_4582157666641291293m_=
-2577808990818708883m_-7333618902031481816styled-by-prettify">start </span>=
<span style=3D"color:#660" class=3D"m_317489642134780931m_-5868171486550583=
864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_458215=
7666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify=
">+</span><span style=3D"color:#000" class=3D"m_317489642134780931m_-586817=
1486550583864m_-7846267993825401439m_-647208999166993943m_49969178095523764=
15m_4582157666641291293m_-2577808990818708883m_-7333618902031481816styled-b=
y-prettify"> </span><span style=3D"color:#066" class=3D"m_31748964213478093=
1m_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_4996917=
809552376415m_4582157666641291293m_-2577808990818708883m_-73336189020314818=
16styled-by-prettify">1</span><span style=3D"color:#660" class=3D"m_3174896=
42134780931m_-5868171486550583864m_-7846267993825401439m_-64720899916699394=
3m_4996917809552376415m_4582157666641291293m_-2577808990818708883m_-7333618=
902031481816styled-by-prettify">,</span><span style=3D"color:#000" class=3D=
"m_317489642134780931m_-5868171486550583864m_-7846267993825401439m_-6472089=
99166993943m_4996917809552376415m_4582157666641291293m_-2577808990818708883=
m_-7333618902031481816styled-by-prettify"> </span><span style=3D"color:#008=
" class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439=
m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-257780899=
0818708883m_-7333618902031481816styled-by-prettify">end</span><span style=
=3D"color:#660" class=3D"m_317489642134780931m_-5868171486550583864m_-78462=
67993825401439m_-647208999166993943m_4996917809552376415m_45821576666412912=
93m_-2577808990818708883m_-7333618902031481816styled-by-prettify">,</span><=
span style=3D"color:#000" class=3D"m_317489642134780931m_-58681714865505838=
64m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_4582157=
666641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify"=
> f</span><span style=3D"color:#660" class=3D"m_317489642134780931m_-586817=
1486550583864m_-7846267993825401439m_-647208999166993943m_49969178095523764=
15m_4582157666641291293m_-2577808990818708883m_-7333618902031481816styled-b=
y-prettify">,</span><span style=3D"color:#000" class=3D"m_31748964213478093=
1m_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_4996917=
809552376415m_4582157666641291293m_-2577808990818708883m_-73336189020314818=
16styled-by-prettify"> partial_sum </span><span style=3D"color:rgb(129,198,=
190)"><span style=3D"color:#660" class=3D"m_317489642134780931m_-5868171486=
550583864m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_=
4582157666641291293m_-2577808990818708883m_-7333618902031481816styled-by-pr=
ettify">+</span></span><span style=3D"color:#000" class=3D"m_31748964213478=
0931m_-5868171486550583864m_-7846267993825401439m_-647208999166993943m_4996=
917809552376415m_4582157666641291293m_-2577808990818708883m_-73336189020314=
81816styled-by-prettify"> </span><span style=3D"color:rgb(139,238,217)"><sp=
an style=3D"color:#000" class=3D"m_317489642134780931m_-5868171486550583864=
m_-7846267993825401439m_-647208999166993943m_4996917809552376415m_458215766=
6641291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify">f=
</span></span><span style=3D"color:#660" class=3D"m_317489642134780931m_-58=
68171486550583864m_-7846267993825401439m_-647208999166993943m_4996917809552=
376415m_4582157666641291293m_-2577808990818708883m_-7333618902031481816styl=
ed-by-prettify">(</span><font color=3D"#000088"><span style=3D"color:#000" =
class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439m_=
-647208999166993943m_4996917809552376415m_4582157666641291293m_-25778089908=
18708883m_-7333618902031481816styled-by-prettify">start</span></font><span =
style=3D"color:#660" class=3D"m_317489642134780931m_-5868171486550583864m_-=
7846267993825401439m_-647208999166993943m_4996917809552376415m_458215766664=
1291293m_-2577808990818708883m_-7333618902031481816styled-by-prettify">));<=
/span></div><div style=3D"color:rgb(212,212,212)"><span style=3D"color:#660=
" class=3D"m_317489642134780931m_-5868171486550583864m_-7846267993825401439=
m_-647208999166993943m_4996917809552376415m_4582157666641291293m_-257780899=
0818708883m_-7333618902031481816styled-by-prettify">};</span></div></div></=
div></code></div><br>This code calculates the sum of f(i) over the range [s=
tart, end] using recursion.</div><div><br></div><div><b>With optimization e=
nabled,</b>=C2=A0both GCC and Clang produce machine code that is equally pe=
rformant to the procedural version of the sum (O2 and above), although <b>w=
ithout optimization</b>, the program segfaults due to running out of space =
on the stack. (For the test I used a function which returned the square of =
it&#39;s input).=C2=A0</div><div><br></div><div>Tail call recursion is a we=
ll-understood optimization. It has a history of use in other languages, and=
 since many compilers already support it as one of a number of possible opt=
imizations, requiring it&#39;s use won&#39;t by an unnecessary burden to th=
e people writing our compilers. <b>If it works with optimization enabled, w=
ell-defined and standard compliant code shouldn&#39;t break when compiled w=
ithout optimization.=C2=A0</b><br></div><div><br></div><div><b>Benefits:</b=
></div><div><ul><li>Makes recursive code faster and more reliable</li><li>R=
educes usage of the stack</li><li>Aligns with the C++ philosophy of cost-fr=
ee abstraction</li><li>Won&#39;t break any old code</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" rel=3D"nore=
ferrer noreferrer noreferrer noreferrer noreferrer noreferrer noreferrer no=
referrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer noreferrer noreferrer noreferrer norefer=
rer noreferrer noreferrer" 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/a69afdc5-8f1a-4628-a08d-49b6c1810b57%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" rel=3D"noreferrer =
noreferrer noreferrer noreferrer noreferrer noreferrer noreferrer noreferre=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/a69afdc5-8f1a-4628-a08d-49b6c1810b57%40isocpp.org</a>.<br>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALmDwq3K0ffwpUs46VtRWOmYdR%2B8s4G2EX=
-VNVRAcHj-Wy1PDQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALmDwq3K0ffwpU=
s46VtRWOmYdR%2B8s4G2EX-VNVRAcHj-Wy1PDQ%40mail.gmail.com</a>.<br />

--000000000000c9675e056d5eccc8--

.


Author: Chris Hallock <christopherhallock@gmail.com>
Date: Tue, 29 May 2018 14:31:25 -0700 (PDT)
Raw View
------=_Part_40510_1432432682.1527629485228
Content-Type: multipart/alternative;
 boundary="----=_Part_40511_1174238224.1527629485229"

------=_Part_40511_1174238224.1527629485229
Content-Type: text/plain; charset="UTF-8"



On Tuesday, May 29, 2018 at 4:25:22 PM UTC-4, Antonio Perez wrote:
>
> *Proposal: *Tail-call optimization is a standard feature of many
> programming languages, and is already supported by the main C++ compilers
> (when optimizations are enabled). We should standardize it's use to make
> code that relies on recursion *safer* and *more reliable*.
>
> *Example code: *
>
> template<class F, class sum_t = int>
> auto Sum(size_t start, size_t end, F&& f, sum_t partial_sum = 0)
> {
>    if(start == end)
>         return partial_sum + f(start);
>    else
>         return Sum(start + 1, end, f, partial_sum + f(start));
> };
>
> This code calculates the sum of f(i) over the range [start, end] using
> recursion.
>
> *With optimization enabled,* both GCC and Clang produce machine code that
> is equally performant to the procedural version of the sum (O2 and above),
> although *without optimization*, the program segfaults due to running out
> of space on the stack. (For the test I used a function which returned the
> square of it's input).
>
> Tail call recursion is a well-understood optimization. It has a history of
> use in other languages, and since many compilers already support it as one
> of a number of possible optimizations, requiring it's use won't by an
> unnecessary burden to the people writing our compilers. *If it works with
> optimization enabled, well-defined and standard compliant code shouldn't
> break when compiled without optimization. *
>
> *Benefits:*
>
>    - Makes recursive code faster and more reliable
>    - Reduces usage of the stack
>    - Aligns with the C++ philosophy of cost-free abstraction
>    - Won't break any old code
>
>
Since the Standard doesn't have any notion of stack space, how would you
require tail-call optimization?

--
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/b40de061-5f65-4028-a6b8-0b38dd55f2b6%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Tuesday, May 29, 2018 at 4:25:22 PM UTC-4, Anto=
nio Perez 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"lt=
r"><b>Proposal:=C2=A0</b>Tail-call optimization is a standard feature of ma=
ny programming languages, and is already supported by the main C++ compiler=
s (when optimizations are enabled). We should standardize it&#39;s use to m=
ake code that relies on recursion <u>safer</u> and <u>more reliable</u>.=C2=
=A0<div><br></div><div><b>Example code:=C2=A0</b></div><div><br></div><div>=
<div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word"><code=
><div><div style=3D"font-family:Menlo,Monaco,&quot;Courier New&quot;,monosp=
ace;font-size:12px;line-height:18px;white-space:pre;background-color:rgb(25=
5,255,255)"><div style=3D"color:rgb(212,212,212)"><span style=3D"color:rgb(=
116,151,145)"><span style=3D"color:#008">template</span></span><span style=
=3D"color:rgb(129,198,190)"><span style=3D"color:#660">&lt;</span></span><s=
pan style=3D"color:rgb(116,151,145)"><span style=3D"color:#008">class</span=
></span><span style=3D"color:#000"> </span><span style=3D"color:rgb(174,238=
,149)"><span style=3D"color:#000">F</span></span><span style=3D"color:#660"=
>,</span><span style=3D"color:#000"> </span><span style=3D"color:rgb(116,15=
1,145)"><span style=3D"color:#008">class</span></span><span style=3D"color:=
#000"> </span><span style=3D"color:rgb(174,238,149)"><span style=3D"color:#=
000">sum_t</span></span><span style=3D"color:#000"> </span><span style=3D"c=
olor:rgb(129,198,190)"><span style=3D"color:#660">=3D</span></span><span st=
yle=3D"color:#000"> </span><span style=3D"color:rgb(116,151,145)"><span sty=
le=3D"color:#008">int</span></span><span style=3D"color:rgb(129,198,190)"><=
span style=3D"color:#660">&gt;</span></span><span style=3D"color:#000"> </s=
pan></div><div style=3D"color:rgb(212,212,212)"><span style=3D"color:rgb(11=
6,151,145)"><span style=3D"color:#008">auto</span></span><span style=3D"col=
or:#000"> </span><span style=3D"color:rgb(139,238,217)"><span style=3D"colo=
r:#606">Sum</span></span><span style=3D"color:#660">(</span><span style=3D"=
color:rgb(174,238,149)"><span style=3D"color:#000">size_t</span></span><spa=
n style=3D"color:#000"> start</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:rgb(174,238,149)"><span=
 style=3D"color:#000">size_t</span></span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">end</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> F</span><span style=3D"color:rgb(129,198,190)"><=
span style=3D"color:#660">&amp;&amp;</span></span><span style=3D"color:#000=
"> f</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> <=
/span><span style=3D"color:rgb(174,238,149)"><span style=3D"color:#000">sum=
_t</span></span><span style=3D"color:#000"> partial_sum </span><span style=
=3D"color:rgb(129,198,190)"><span style=3D"color:#660">=3D</span></span><sp=
an style=3D"color:#000"> </span><span style=3D"color:rgb(0,255,255)"><span =
style=3D"color:#066">0</span></span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> </span></div><div style=3D"color:rgb(212,212,212)">=
<span style=3D"color:#660">{</span></div><div><span style=3D"color:#000"> =
=C2=A0 =C2=A0</span><span style=3D"color:rgb(116,151,145)"><span style=3D"c=
olor:#008">if</span></span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">start </span><font color=3D"#666600"><span style=3D"color:#=
660">=3D=3D</span></font><span style=3D"color:#000"> </span><span style=3D"=
color:#008">end</span><span style=3D"color:#660">)</span><span style=3D"col=
or:#000"> <br></span><span style=3D"color:rgb(116,151,145)"><span style=3D"=
color:#000">=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">r=
eturn</span></span><span style=3D"color:#000"> partial_sum </span><span sty=
le=3D"color:#660">+</span><span style=3D"color:#000"> f</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">start</span><span style=
=3D"color:#660">);</span></div><div><span style=3D"color:#000"> =C2=A0 =C2=
=A0</span><span style=3D"color:rgb(116,151,145)"><span style=3D"color:#008"=
>else</span></span><span style=3D"color:#000"> <br></span><span style=3D"co=
lor:rgb(116,151,145)"><span style=3D"color:#000">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color:#008">return</span></span><span style=3D"co=
lor:#000"> </span><span style=3D"color:rgb(139,238,217)"><span style=3D"col=
or:#606">Sum</span></span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">start </span><span style=3D"color:#660">+</span><span style=3D=
"color:#000"> </span><span style=3D"color:#066">1</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#00=
8">end</span><span style=3D"color:#660">,</span><span style=3D"color:#000">=
 f</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> par=
tial_sum </span><span style=3D"color:rgb(129,198,190)"><span style=3D"color=
:#660">+</span></span><span style=3D"color:#000"> </span><span style=3D"col=
or:rgb(139,238,217)"><span style=3D"color:#000">f</span></span><span style=
=3D"color:#660">(</span><font color=3D"#000088"><span style=3D"color:#000">=
start</span></font><span style=3D"color:#660">));</span></div><div style=3D=
"color:rgb(212,212,212)"><span style=3D"color:#660">};</span></div></div></=
div></code></div><br>This code calculates the sum of f(i) over the range [s=
tart, end] using recursion.</div><div><br></div><div><b>With optimization e=
nabled,</b>=C2=A0both GCC and Clang produce machine code that is equally pe=
rformant to the procedural version of the sum (O2 and above), although <b>w=
ithout optimization</b>, the program segfaults due to running out of space =
on the stack. (For the test I used a function which returned the square of =
it&#39;s input).=C2=A0</div><div><br></div><div>Tail call recursion is a we=
ll-understood optimization. It has a history of use in other languages, and=
 since many compilers already support it as one of a number of possible opt=
imizations, requiring it&#39;s use won&#39;t by an unnecessary burden to th=
e people writing our compilers. <b>If it works with optimization enabled, w=
ell-defined and standard compliant code shouldn&#39;t break when compiled w=
ithout optimization.=C2=A0</b><br></div><div><br></div><div><b>Benefits:</b=
></div><div><ul><li>Makes recursive code faster and more reliable</li><li>R=
educes usage of the stack</li><li>Aligns with the C++ philosophy of cost-fr=
ee abstraction</li><li>Won&#39;t break any old code</li></ul></div></div></=
blockquote><div><br></div><div>Since the Standard doesn&#39;t have any noti=
on of stack space, how would you require tail-call optimization?<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/b40de061-5f65-4028-a6b8-0b38dd55f2b6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b40de061-5f65-4028-a6b8-0b38dd55f2b6=
%40isocpp.org</a>.<br />

------=_Part_40511_1174238224.1527629485229--

------=_Part_40510_1432432682.1527629485228--

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Wed, 30 May 2018 00:47:06 +0300
Raw View
On 05/30/18 00:20, Nicolas Lesser wrote:
>
> What benefit does your proposal bring? Because as far as I can see, the
> only benefit would be to have faster unoptimized code, which is a bit weird.

Mandatory tail call optimization could (mostly) guarantee that recursive
algorithms that employ it won't fail due to stack overflow. (Mostly -
because stack overflow could still happen because of other reasons.)

--
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/9bd6ea66-fb3e-4135-8ad4-251351d4d813%40gmail.com.

.


Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Tue, 29 May 2018 15:03:05 -0700 (PDT)
Raw View
------=_Part_41015_787889545.1527631385576
Content-Type: multipart/alternative;
 boundary="----=_Part_41016_941414735.1527631385576"

------=_Part_41016_941414735.1527631385576
Content-Type: text/plain; charset="UTF-8"

I appreciate your feedback. This proposal is based on a rather
uncontroversial idea: If it's semantically and syntactically valid, a
program should work when compiled without optimizations enabled (emphasis
on "semantically valid"). Tail call optimization is different from other
types of optimization in that the functionality of programs is
fundamentally affected if tail call optimization doesn't occur. Programmers
expect unoptimized programs to run slower, and to use a bit more memory,
but they accept the tradeoff because the lack of optimization doesn't break
valid programs. In this case, it does break valid programs.

Standardizing tail call optimization provides programmers with greater
certainty that their code will work, and that it'll be portable. It's not
just about recursion, either: programmers working on embedded systems often
have limited stack space, and the standardization of this optimization will
allow them to better design their code to fit the tight memory requirements
(for example, by putting calls to memory hungry routines at the end of a
function).

Aside from that, there are many ideas that are best expressed through the
use of recursion. Making recursion safe to use will make it easier to write
clean and maintainable code.

--
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/443c5867-0a8e-48c3-9a44-750d7182f65e%40isocpp.org.

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

<div dir=3D"ltr"><div>I appreciate your feedback. This proposal is based on=
 a rather uncontroversial idea: If it&#39;s semantically and syntactically =
valid, a program should work when compiled without optimizations enabled (e=
mphasis on &quot;semantically valid&quot;). Tail call optimization is diffe=
rent from other types of optimization in that the functionality of programs=
 is fundamentally affected if tail call optimization doesn&#39;t occur. Pro=
grammers expect unoptimized programs to run slower, and to use a bit more m=
emory, but they accept the tradeoff because the lack of optimization doesn&=
#39;t break valid programs. In this case, it does break valid programs.=C2=
=A0</div><div><br></div><div>Standardizing tail call optimization provides =
programmers with greater certainty that their code will work, and that it&#=
39;ll be portable. It&#39;s not just about recursion, either: programmers w=
orking on embedded systems often have limited stack space, and the standard=
ization of this optimization will allow them to better design their code to=
 fit the tight memory requirements (for example, by putting calls to memory=
 hungry routines at the end of a function).=C2=A0</div><div><br></div><div>=
Aside from that, there are many ideas that are best expressed through the u=
se of recursion. Making recursion safe to use will make it easier to write =
clean and maintainable code.=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/443c5867-0a8e-48c3-9a44-750d7182f65e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/443c5867-0a8e-48c3-9a44-750d7182f65e=
%40isocpp.org</a>.<br />

------=_Part_41016_941414735.1527631385576--

------=_Part_41015_787889545.1527631385576--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 29 May 2018 15:45:56 -0700
Raw View
On Tuesday, 29 May 2018 14:17:15 PDT Antonio Perez wrote:
> My proposal is that C++ compilers are required to perform tail-call
> optimization when the final action of a procedure is a call to another
> procedure provided that:
>
>    - All remaining variables that would have been destroyed after the
>    return call are trivially destructible,
>    - are given to the function as an argument that is copy-by-value OR a
>    universal reference (when a function returns an object, that object isn't
> destroyed in the function itself but in whichever scope originated the
> call. I propose variables passed in a tail-recursive call are treated
> similarly).
>    - or can be safely destroyed prior to the tail call

You forgot:

 - the exception specification of the called function is compatible with the
caller (see the GCC bug where an exception escaped a noexcept function that
optimised by tail-call to a noexcept(false) function)

 - the implementation-defined way of passing arguments to the callee is
compatible with the caller's return mechanism

This last one is a deal-breaker.

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



--
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/52721628.Ib5DnFPV8U%40tjmaciei-mobl1.

.


Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Tue, 29 May 2018 15:59:13 -0700 (PDT)
Raw View
------=_Part_40515_1299888835.1527634753957
Content-Type: multipart/alternative;
 boundary="----=_Part_40516_538066606.1527634753957"

------=_Part_40516_538066606.1527634753957
Content-Type: text/plain; charset="UTF-8"

Could you explain more about why it's a deal-breaker, or about how to
circumvent this issue?

--
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/56974d35-8b32-4651-9e81-3e0116a03332%40isocpp.org.

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

<div dir=3D"ltr">Could you explain more about why it&#39;s a deal-breaker, =
or about how to circumvent this issue?</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/56974d35-8b32-4651-9e81-3e0116a03332%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/56974d35-8b32-4651-9e81-3e0116a03332=
%40isocpp.org</a>.<br />

------=_Part_40516_538066606.1527634753957--

------=_Part_40515_1299888835.1527634753957--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 29 May 2018 16:25:43 -0700
Raw View
On Tuesday, 29 May 2018 15:59:13 PDT Antonio Perez wrote:
> I don't think you understand the point I made:
> An optimization is not something you can assume and structure your entire
> code around.

Case 1:

void __cdecl f(int);
void __stdcall g()
{
    f(0);
}

For __stdcall:
https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
 "Called function pops its own arguments from the stack."

For __cdecl:
https://msdn.microsoft.com/en-us/library/zkwh89ks.aspx
  "Calling function pops the arguments from the stack."

The function that called g is expecting g() to clean up its stack. But f()'s
caller expects its caller to clean up the stack. So who cleans up in the case
above, for tail-call?

Case 2:

The number of arguments passed on the stack are different, and thus there's a
difference in cleaning up. Most modern architectures pass the main arguments
in registers, but in ALL modern architectures, the limit is 8 arguments. In
some, it's quite fewer (ARM 32-bit, Windows 64-bit x86 both are 4). And, of
course, 32-bit x86 passes no arguments in registers.

Case 2 is made more difficult by the requirement that the stack be aligned to
a multiple of 16 on x86.


Tests, two in one: https://godbolt.org/g/ovbSk9. That's four compilers, no
tail call optimisation.

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



--
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/1876294.A0XuQFE8zp%40tjmaciei-mobl1.

.


Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Tue, 29 May 2018 18:06:50 -0700 (PDT)
Raw View
------=_Part_30363_279761035.1527642410845
Content-Type: multipart/alternative;
 boundary="----=_Part_30364_238191585.1527642410849"

------=_Part_30364_238191585.1527642410849
Content-Type: text/plain; charset="UTF-8"

*Discussion of Case 1: *I'm not knowledgable enough to propose a resolution
in Case 1. Given that __stdcall and __cdecl are already an extension to the
standard, any proposed rules about tail call optimization wouldn't
necessarily apply to them (as those rules would only apply strictly to
standard-compliant functions that didn't use implementation-specific
extensions).

*Discussion of Case 2*
In Case 2, implementing tail-call optimization is a technical problem,
rather than a fundamental one, and one that I would already consider
(pretty much entirely) solved. All that's left is for the behavior to be
standardized. Shown below is code for a (terribly ugly and pathological)
recursive function that takes 11 arguments, all of which are involved in
the recursion in some manner. Despite being unable to fit all arguments
into the cpu registers, both GCC and the apple version of the clang
compiler still succeed in performing tail-call optimization at O2
optimization. HOW the tail-call optimization is implemented should be left
up compiler designer, but guarantees about *when* it optimization occurs
would be extremely useful to C++ programmers. It would make the use of tail
recursion a cost-free abstraction programmers could use without being
concerned about their code breaking.

*The other version of Case 2: *Suppose the arguments of function F take up
N bytes on the stack, and function F calls function G in such a way that
(under the proposed rule change) the standard requires the call to G be
tail-call optimized. If the arguments of G take up M bytes on the stack,
with M > N, then the compiler could allocate an additional (M-N) bytes
immediately after the space for the arguments of F on the stack. This is
space that would get allocated anyways when G was called, except instead of
using worst-case N+M space, tail recursion results in only using M space.



*Pathological case with 11 arguments:*
#include <cstddef>
#include <cstdint>
#include <array>
#include <iostream>
#include <string>
std::array<uint64_t, 10> complex_recurse(
   const uint64_t a0,
   const uint64_t a1,
   const uint64_t a2,
   const uint64_t a3,
   const uint64_t a4,
   const uint64_t a5,
   const uint64_t a6,
   const uint64_t a7,
   const uint64_t a8,
   const uint64_t a9,
   const uint64_t counter
) {
   if(counter) {
       if(a0 & 1)
           if(a1 & 1)
               if(a2 & 1)
                   if(a3 & 1)
                       if(a4 & 1)
                           if(a5 & 1)
                               if(a6 & 1)
                                   if(a7 & 1)
                                       if(a8 & 1)
                                           return complex_recurse(a0 + 1,
a1 + 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8 + 1, a9 + 1,
counter - 1);
                                       else
                                            return complex_recurse(a0 + 1,
a1 + 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8 + 1, a9, counter
- 1);
                                   else
                                        return complex_recurse(a0 + 1, a1 +
1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8, a9, counter - 1);
                               else
                                    return complex_recurse(a0 + 1, a1 + 1,
a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7, a8, a9, counter - 1);
                           else
                                return complex_recurse(a0 + 1, a1 + 1, a2 +
1, a3 + 1, a4 + 1, a5 + 1, a6, a7, a8, a9, counter - 1);
                       else
                            return complex_recurse(a0 + 1, a1 + 1, a2 + 1,
a3 + 1, a4 + 1, a5, a6, a7, a8, a9, counter - 1);
                   else
                        return complex_recurse(a0 + 1, a1 + 1, a2 + 1, a3 +
1, a4, a5, a6, a7, a8, a9, counter - 1);
               else
                   return complex_recurse(a0 + 1, a1 + 1, a2 + 1, a3, a4, a5
, a6, a7, a8, a9, counter - 1);
           else
               return complex_recurse(a0 + 1, a1 + 1, a2, a3, a4, a5, a6, a7
, a8, a9, counter - 1);
       else
           return complex_recurse(a0 + 1, a1, a2, a3, a4, a5, a6, a7, a8, a9
, counter - 1);
   } else {
       return std::array<uint64_t, 10> { a0, a1, a2, a3, a4, a5, a6, a7, a8,
a9};
   }
}
int main(int argc, char** argv) {
   uint64_t times = std::stoull(argv[1]);
   auto output = complex_recurse(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, times);
   for(auto elem : output) {
       std::cout << elem << std::endl;
   }
}


--
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/1dd3b433-887e-46df-90a8-3d89a82731a7%40isocpp.org.

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

<div dir=3D"ltr"><b>Discussion of Case 1:=C2=A0</b>I&#39;m not knowledgable=
 enough to propose a resolution in Case 1. Given that __stdcall and __cdecl=
 are already an extension to the standard, any proposed rules about tail ca=
ll optimization wouldn&#39;t necessarily apply to them (as those rules woul=
d only apply strictly to standard-compliant functions that didn&#39;t use i=
mplementation-specific extensions).=C2=A0<div><br></div><div><b>Discussion =
of Case 2</b></div><div>In Case 2, implementing tail-call optimization is a=
 technical problem, rather than a fundamental one, and one that I would alr=
eady consider (pretty much entirely) solved. All that&#39;s left is for the=
 behavior to be standardized. Shown below is code for a (terribly ugly and =
pathological) recursive function that takes 11 arguments, all of which are =
involved in the recursion in some manner. Despite being unable to fit all a=
rguments into the cpu registers, both GCC and the apple version of the clan=
g compiler still succeed in performing tail-call optimization at O2 optimiz=
ation. HOW the tail-call optimization is implemented should be left up comp=
iler designer, but guarantees about *when* it optimization occurs would be =
extremely useful to C++ programmers. It would make the use of tail recursio=
n a cost-free abstraction programmers could use without being concerned abo=
ut their code breaking.=C2=A0</div><div><br></div><div><b>The other version=
 of Case 2:=C2=A0</b>Suppose the arguments of function F take up N bytes on=
 the stack, and function F calls function G in such a way that (under the p=
roposed rule change) the standard requires the call to G be tail-call optim=
ized. If the arguments of G take up M bytes on the stack, with M &gt; N, th=
en the compiler could allocate an additional (M-N) bytes immediately after =
the space for the arguments of F on the stack. This is space that would get=
 allocated anyways when G was called, except instead of using worst-case N+=
M space, tail recursion results in only using M space.=C2=A0</div><div><br>=
</div><div><br></div><div><br></div><div><b>Pathological case with 11 argum=
ents:</b></div><div><div class=3D"prettyprint" style=3D"border: 1px solid r=
gb(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div=
 class=3D"subprettyprint"><div style=3D"color: rgb(212, 212, 212); font-fam=
ily: Menlo, Monaco, &quot;Courier New&quot;, monospace; font-size: 12px; li=
ne-height: 18px; white-space: pre; background-color: rgb(255, 255, 255);"><=
div><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">#include</span></span><span style=3D"color: r=
gb(158, 151, 113);"><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span></span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify">&lt;cstddef&gt;</span></span></di=
v><div><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">#include</span></span><span style=3D"color=
: rgb(158, 151, 113);"><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span></span><span style=3D"color: rgb(0, 255, 255);"><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&lt;cstdint&gt;</span></span=
></div><div><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color=
: #800;" class=3D"styled-by-prettify">#include</span></span><span style=3D"=
color: rgb(158, 151, 113);"><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span></span><span style=3D"color: rgb(0, 255, 255);"><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify">&lt;array&gt;</span></spa=
n></div><div><span style=3D"color: rgb(116, 151, 145);"><span style=3D"colo=
r: #800;" class=3D"styled-by-prettify">#include</span></span><span style=3D=
"color: rgb(158, 151, 113);"><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span></span><span style=3D"color: rgb(0, 255, 255);"><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">&lt;iostream&gt;</span><=
/span></div><div><span style=3D"color: rgb(116, 151, 145);"><span style=3D"=
color: #800;" class=3D"styled-by-prettify">#include</span></span><span styl=
e=3D"color: rgb(158, 151, 113);"><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span></span><span style=3D"color: rgb(0, 255, 255);"><sp=
an style=3D"color: #080;" class=3D"styled-by-prettify">&lt;string&gt;</span=
></span></div><div><span style=3D"color: #000;" class=3D"styled-by-prettify=
">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">array</span><=
span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span></span><span style=3D"color: rgb(174, 2=
38, 149);"><span style=3D"color: #000;" class=3D"styled-by-prettify">uint64=
_t</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify">,=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=
=3D"styled-by-prettify">10</span></span><span style=3D"color: rgb(129, 198,=
 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</spa=
n></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">complex_recurse</span></span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span></div><div><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=3D=
"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">const</span></span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: rgb(174, 238, 149);"><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">uint64_t</span></span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> a0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span></div><div><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span=
 style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">const</span></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(174, 238, 149);">=
<span style=3D"color: #000;" class=3D"styled-by-prettify">uint64_t</span></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span></div><div>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</s=
pan><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">const</span></span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(174, 238,=
 149);"><span style=3D"color: #000;" class=3D"styled-by-prettify">uint64_t<=
/span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a2<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span></d=
iv><div><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =
=C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">const</span></span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(=
174, 238, 149);"><span style=3D"color: #000;" class=3D"styled-by-prettify">=
uint64_t</span></span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> a3</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span></div><div><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span></span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: rgb(174, 238, 149);"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">uint64_t</span></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> a4</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span></div><div><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">const</span></span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: rgb(174, 238, 149);"><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">uint64_t</span></span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> a5</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">,</span></div><div><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 14=
5);"><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: rgb(174, 238, 149);"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">uint64_t</span></span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> a6</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span></div><div><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: rgb(11=
6, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-prettify">co=
nst</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: rgb(174, 238, 149);"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">uint64_t</span></span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> a7</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span></div><div><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color=
: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">const</span></span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: rgb(174, 238, 149);"><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">uint64_t</span></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a8</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span></div><div><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=
=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"style=
d-by-prettify">const</span></span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: rgb(174, 238, 149);"><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">uint64_t</span></span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> a9</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span></div><div><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><sp=
an style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span></span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: rgb(174, 238, 149);=
"><span style=3D"color: #000;" class=3D"styled-by-prettify">uint64_t</span>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> counter</=
span></div><div><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span></div><div>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</s=
pan><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">if</span></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">counter</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span></div><div><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145=
);"><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">a0 </span><span style=
=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;</span></span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span></div><div><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">if</span></span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">a1 </span><span style=3D"color: rgb=
(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&amp;</span></span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #=
066;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">)</span></div><div><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">if</span></span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">a2 </span><span style=3D"color: rgb=
(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&amp;</span></span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #=
066;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">)</span></div><div><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 1=
45);"><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span></=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">a3 </span><span style=
=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;</span></span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span></div><div><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span sty=
le=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">if</span></span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">a4 </span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&amp;</span></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">)</span></div><div><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);=
"><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">a5 </span><span style=3D"=
color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&amp;</span></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span></div><div><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">if</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">a6 </span><span style=3D"color: rgb(1=
29, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
amp;</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #06=
6;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span></div><div><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">if</span></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">a7 </span><span style=3D"color: rgb(129, 1=
98, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;<=
/span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" c=
lass=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">)</span></div><div><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">if</span></span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">a8 </span><span style=3D"color: =
rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&amp;</span></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color=
: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">)</span></div><div><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: r=
gb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">return</span></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: rgb(139, 238, 217);"><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">complex_recurse</span></span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">a0 </span><span style=3D"color: =
rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">+</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #0=
66;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> a1 </span><span style=3D"color: rgb(129, 198, 190)=
;"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span></span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> a2 </span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">+</span></span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0=
, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</=
span></span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> a3 </span><sp=
an style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=
=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a4 </span><span style=3D"co=
lor: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> a5 </span><span style=3D"color: rgb(129, 198, =
190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"=
styled-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> a6 </span><span style=3D"color: rgb(129, 198, 190);"><span style=
=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a7 </s=
pan><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);=
"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> a8 </span><span style=3D"=
color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by=
-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> a9 </span><span style=3D"color: rgb(129, 198=
, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> counter </span><span style=3D"color: rgb(129, 198, 190);"><=
span style=3D"color: #660;" class=3D"styled-by-prettify">-</span></span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-=
by-prettify">1</span></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span></div><div><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">else</span></span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span></div><div><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">return</span></span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: rgb(139, 238, 217);"><span style=3D=
"color: #000;" class=3D"styled-by-prettify">complex_recurse</span></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">a0 </span><span style=3D"col=
or: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color=
: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> a1 </span><span style=3D"color: rgb(129, 198, 1=
90);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span></s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"s=
tyled-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> a2 </span><span style=3D"color: rgb(129, 198, 190);"><span style=
=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a3 </s=
pan><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);=
"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> a4 </span><span style=3D"=
color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by=
-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> a5 </span><span style=3D"color: rgb(129, 198=
, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> a6 </span><span style=3D"color: rgb(129, 198, 190);"><span =
style=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a7 =
</span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 25=
5);"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> a8 </span><span style=
=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> a9</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> counter </span><span style=3D"color: rgb(129, 198,=
 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">-</span><=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D=
"styled-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">);</span></div><div><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: =
#008;" class=3D"styled-by-prettify">else</span></span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span></div><div><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: rgb(116, 151, =
145);"><span style=3D"color: #008;" class=3D"styled-by-prettify">return</sp=
an></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">complex_recurse</span></span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">a0 </span><span style=3D"color: rgb(129, 198,=
 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span><=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D=
"styled-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> a1 </span><span style=3D"color: rgb(129, 198, 190);"><span style=
=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a2 </s=
pan><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);=
"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> a3 </span><span style=3D"=
color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by=
-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> a4 </span><span style=3D"color: rgb(129, 198=
, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> a5 </span><span style=3D"color: rgb(129, 198, 190);"><span =
style=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a6 =
</span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 25=
5);"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> a7 </span><span style=
=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> a8</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> a9</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> counter </span><span style=3D"color: rgb(129, 198, 190);"><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">-</span></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">);</span></div><div><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: r=
gb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">else</span></span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span></div><div><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"style=
d-by-prettify">return</span></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: rgb(139, 238, 217);"><span =
style=3D"color: #000;" class=3D"styled-by-prettify">complex_recurse</span><=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">a0 </span><span styl=
e=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> a1 </span><span style=3D"color: rgb(=
129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">=
+</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;"=
 class=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> a2 </span><span style=3D"color: rgb(129, 198, 190);"><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-=
by-prettify">1</span></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> a3 </span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">+</span></span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 2=
55, 255);"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</spa=
n></span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> a4 </span><span =
style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"=
styled-by-prettify">+</span></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span st=
yle=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> a5 </span><span style=3D"color: rgb=
(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>+</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;=
" class=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> a6 </span><span style=3D"color: rgb(129, 198, 190);"><=
span style=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-=
by-prettify">1</span></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> a7</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> a8</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a9</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> counter </span><span style=3D"color: rgb(12=
9, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">-<=
/span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" c=
lass=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">);</span></div><div><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"c=
olor: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">else</span></span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span></div><div><span style=3D"color: #000;" class=3D"styled-=
by-prettify">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"col=
or: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">return</span></span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: rgb(139, 238, 217);"><span style=
=3D"color: #000;" class=3D"styled-by-prettify">complex_recurse</span></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">a0 </span><span style=3D"=
color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by=
-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> a1 </span><span style=3D"color: rgb(129, 198=
, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> a2 </span><span style=3D"color: rgb(129, 198, 190);"><span =
style=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a3 =
</span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 25=
5);"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> a4 </span><span style=
=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> a5 </span><span style=3D"color: rgb(=
129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">=
+</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;"=
 class=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> a6</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> a7</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> a8</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a9</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> counter </span><span style=3D"color: rgb(12=
9, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">-<=
/span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" c=
lass=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">);</span></div><div><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116,=
 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-prettify">else=
</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span></div><div><span style=3D"color: #000;" class=3D"styled-by-prettify">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: rgb(116, 151, 145);">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">return</span></sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #000;" class=3D"=
styled-by-prettify">complex_recurse</span></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">a0 </span><span style=3D"color: rgb(129, 198, 190);=
"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span></span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"style=
d-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> a1 </span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">+</span></span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0,=
 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</s=
pan></span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> a2 </span><spa=
n style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=
=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a3 </span><span style=3D"co=
lor: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> a4 </span><span style=3D"color: rgb(129, 198, =
190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"=
styled-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> a5</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a6</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> a7</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> a8</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> a9</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> counter </span><span style=3D"color: rgb(129, 198, 190);"><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">-</span></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">);</span></div><div><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: =
#008;" class=3D"styled-by-prettify">else</span></span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span></div><div><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">return</span></span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: rgb(139, 238, 217);"><span style=3D=
"color: #000;" class=3D"styled-by-prettify">complex_recurse</span></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">a0 </span><span style=3D"col=
or: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color=
: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> a1 </span><span style=3D"color: rgb(129, 198, 1=
90);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span></s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"s=
tyled-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> a2 </span><span style=3D"color: rgb(129, 198, 190);"><span style=
=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a3 </s=
pan><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">+</span></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);=
"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> a4</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> a5</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> a6</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> a7</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> a8</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> a9</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> counter </span><span style=3D"color: rgb(129, =
198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">-</sp=
an></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" clas=
s=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span></div><div><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">else</span></span></div><div><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"c=
olor: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">return</span></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: rgb(139, 238, 217);"><span style=
=3D"color: #000;" class=3D"styled-by-prettify">complex_recurse</span></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">a0 </span><span style=3D"=
color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by=
-prettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> a1 </span><span style=3D"color: rgb(129, 198=
, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> a2 </span><span style=3D"color: rgb(129, 198, 190);"><span =
style=3D"color: #660;" class=3D"styled-by-prettify">+</span></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a3<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> a4</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> a5</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> a6</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> a7</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a8</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> a9</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> counter </span><span style=3D"color: rg=
b(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify=
">-</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066=
;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">);</span></div><div><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">else</span></span></div><div><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145)=
;"><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">complex_recurse</span></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">a0 </span><span style=3D"color: rgb(129, 198, 19=
0);"><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span></sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"st=
yled-by-prettify">1</span></span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> a1 </span><span style=3D"color: rgb(129, 198, 190);"><span style=3D=
"color: #660;" class=3D"styled-by-prettify">+</span></span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb=
(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-prettify">1=
</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a2</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a3</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> a4</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> a5</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
a6</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> a7</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> a8</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> a9</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> counter </span><span style=3D"color: rgb(129, 198, 190);"><span =
style=3D"color: #660;" class=3D"styled-by-prettify">-</span></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span></div><div><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: rgb(116, 1=
51, 145);"><span style=3D"color: #008;" class=3D"styled-by-prettify">else</=
span></span></div><div><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color=
: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">return</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(139, 238, 217);"><span style=3D"=
color: #000;" class=3D"styled-by-prettify">complex_recurse</span></span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">a0 </span><span style=3D"col=
or: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">+</span></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color=
: #066;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> a1</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> a2</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a3</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> a4</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> a5</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> a6</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> a7</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a8</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> a9</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> counter </span><span style=3D"color: rg=
b(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify=
">-</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066=
;" class=3D"styled-by-prettify">1</span></span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">);</span></div><div><span style=3D"color: #00=
0;" 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;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(116, 151, 145=
);"><span style=3D"color: #008;" class=3D"styled-by-prettify">else</span></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span></div><div><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=
=A0 =C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">return</span></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">array</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">uint64_t</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pret=
tify">10</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> a0</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> a1</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> a2</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> a3</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> a4</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> a5</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> a6</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> a7</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a8<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> a9</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">};</span></div><div><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div><div><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div><div=
><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">int</span></span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(139, 238, 217)=
;"><span style=3D"color: #000;" class=3D"styled-by-prettify">main</span></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">int</span></span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> argc</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">char</span></span><span style=3D"c=
olor: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-=
prettify">**</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> argv</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: #660;" class=3D"styled-by-prettify">{</span></div>=
<div><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=
=A0</span><span style=3D"color: rgb(174, 238, 149);"><span style=3D"color: =
#000;" class=3D"styled-by-prettify">uint64_t</span></span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> times </span><span style=3D"color=
: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D</span></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: rgb(139, 238, 217);"><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">stoull</span></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">argv</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">[</span><span style=3D"color: rgb(0, 255, 255);"><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">]);</span></div><div><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><sp=
an style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> output </span><span style=3D"color: rgb(129, 198,=
 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">complex_recurse</span></span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: rgb(0, 2=
55, 255);"><span style=3D"color: #066;" class=3D"styled-by-prettify">0</spa=
n></span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"style=
d-by-prettify">0</span></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: =
#066;" class=3D"styled-by-prettify">0</span></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><=
span style=3D"color: #066;" class=3D"styled-by-prettify">0</span></span><sp=
an 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=
: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">0</span></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: rgb(0, 255, 255);"><span style=3D"color: #066;" clas=
s=3D"styled-by-prettify">0</span></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=
=3D"color: #066;" class=3D"styled-by-prettify">0</span></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: rgb(0, =
255, 255);"><span style=3D"color: #066;" class=3D"styled-by-prettify">0</sp=
an></span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: rgb(0, 255, 255);"><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">0</span></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color:=
 #066;" class=3D"styled-by-prettify">0</span></span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> times</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span></div><div><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: rgb(1=
16, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-prettify">f=
or</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span></span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> elem </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> output</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span></div><div><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> =C2=A0 =C2=A0 =C2=A0 =C2=A0std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">cout </span><span style=3D"color: rgb(129, 198, 190);"><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span></span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> elem </span><sp=
an style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;&lt;</span></span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">endl</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span></div><div><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">}</span></div><div><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span></div></div></div></code></div><br><br></div></di=
v>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1dd3b433-887e-46df-90a8-3d89a82731a7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1dd3b433-887e-46df-90a8-3d89a82731a7=
%40isocpp.org</a>.<br />

------=_Part_30364_238191585.1527642410849--

------=_Part_30363_279761035.1527642410845--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 29 May 2018 18:49:19 -0700 (PDT)
Raw View
------=_Part_42338_94074308.1527644960059
Content-Type: multipart/alternative;
 boundary="----=_Part_42339_1510546825.1527644960059"

------=_Part_42339_1510546825.1527644960059
Content-Type: text/plain; charset="UTF-8"

On Tuesday, May 29, 2018 at 6:03:05 PM UTC-4, Antonio Perez wrote:
>
> I appreciate your feedback. This proposal is based on a rather
> uncontroversial idea: If it's semantically and syntactically valid, a
> program should work when compiled without optimizations enabled (emphasis
> on "semantically valid").
>

I would find that idea rather controversial, since the distinction between
"work" and "not-work" is a matter of resource exhaustion, which is not a
standard-defined thing. Also, the standard doesn't recognize the
distinction between "optimized" and "not optimized"; the standard is the
standard.

Having written a few programs in semi-resource-constrained environments,
there was rarely any expectation that the project would run with no
optimizations enabled. And it wasn't for lack of tail recursion; there were
plenty of other things that drew on those constrained resources.

I don't believe proper tail calls will do much to change things for such
people.

Guaranteed elision wasn't added because it freed up developers from relying
on an optimization. It was added because it allowed people to do things
that otherwise wouldn't work, like return immobile objects.

Proper tail calls need some motivation like that, where it gives you an
ability that would be otherwise impossible.

Tail call optimization is different from other types of optimization in
> that the functionality of programs is fundamentally affected if tail call
> optimization doesn't occur. Programmers expect unoptimized programs to run
> slower, and to use a bit more memory, but they accept the tradeoff because
> the lack of optimization doesn't break valid programs. In this case, it
> does break valid programs.
>
> Standardizing tail call optimization provides programmers with greater
> certainty that their code will work, and that it'll be portable. It's not
> just about recursion, either: programmers working on embedded systems often
> have limited stack space, and the standardization of this optimization will
> allow them to better design their code to fit the tight memory requirements
> (for example, by putting calls to memory hungry routines at the end of a
> function).
>

Such programmers already have to carefully plan their compiler options to
fit within their environment. So this really would change very little for
them.


>
> Aside from that, there are many ideas that are best expressed through the
> use of recursion. Making recursion safe to use will make it easier to write
> clean and maintainable code.
>

Recursion already is safe to use. And I hope that you aren't limiting your
thinking on proper tail calls to just recursion.

--
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/2ad8b6ba-c6f6-4455-bed2-3a1d9556f065%40isocpp.org.

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

<div dir=3D"ltr">On Tuesday, May 29, 2018 at 6:03:05 PM UTC-4, Antonio Pere=
z wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>=
I appreciate your feedback. This proposal is based on a rather uncontrovers=
ial idea: If it&#39;s semantically and syntactically valid, a program shoul=
d work when compiled without optimizations enabled (emphasis on &quot;seman=
tically valid&quot;).</div></div></blockquote><div><br></div><div>I would f=
ind that idea rather controversial, since the distinction between &quot;wor=
k&quot; and &quot;not-work&quot; is a matter of resource exhaustion, which =
is not a standard-defined thing. Also, the standard doesn&#39;t recognize t=
he distinction between &quot;optimized&quot; and &quot;not optimized&quot;;=
 the standard is the standard.<br></div><div><br></div><div>Having written =
a few programs in semi-resource-constrained environments, there was rarely =
any expectation that the project would run with no optimizations enabled. A=
nd it wasn&#39;t for lack of tail recursion; there were plenty of other thi=
ngs that drew on those constrained resources.</div><div><br></div><div>I do=
n&#39;t believe proper tail calls will do much to change things for such pe=
ople.</div><div><br></div><div>Guaranteed elision wasn&#39;t added because =
it freed up developers from relying on an optimization. It was added becaus=
e it allowed people to do things that otherwise wouldn&#39;t work, like ret=
urn immobile objects.</div><div><br></div><div>Proper tail calls need some =
motivation like that, where it gives you an ability that would be otherwise=
 impossible.<br></div><div><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"ltr"><div>Tail call optimization is different from other=
 types of optimization in that the functionality of programs is fundamental=
ly affected if tail call optimization doesn&#39;t occur. Programmers expect=
 unoptimized programs to run slower, and to use a bit more memory, but they=
 accept the tradeoff because the lack of optimization doesn&#39;t break val=
id programs. In this case, it does break valid programs.=C2=A0</div><div><b=
r></div><div>Standardizing tail call optimization provides programmers with=
 greater certainty that their code will work, and that it&#39;ll be portabl=
e. It&#39;s not just about recursion, either: programmers working on embedd=
ed systems often have limited stack space, and the standardization of this =
optimization will allow them to better design their code to fit the tight m=
emory requirements (for example, by putting calls to memory hungry routines=
 at the end of a function).</div></div></blockquote><div><br></div><div>Suc=
h programmers already have to carefully plan their compiler options to fit =
within their environment. So this really would change very little for them.=
<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div><br></div><div>Aside from that, there are many ideas tha=
t are best expressed through the use of recursion. Making recursion safe to=
 use will make it easier to write clean and maintainable code.</div></div><=
/blockquote><div><br></div><div>Recursion already is safe to use. And I hop=
e that you aren&#39;t limiting your thinking on proper tail calls to just r=
ecursion. <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/2ad8b6ba-c6f6-4455-bed2-3a1d9556f065%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2ad8b6ba-c6f6-4455-bed2-3a1d9556f065=
%40isocpp.org</a>.<br />

------=_Part_42339_1510546825.1527644960059--

------=_Part_42338_94074308.1527644960059--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 29 May 2018 21:02:32 -0700
Raw View
On Tuesday, 29 May 2018 18:06:50 PDT Antonio Perez wrote:
> #include <cstddef>
> #include <cstdint>
> #include <array>
> #include <iostream>
> #include <string>
> std::array<uint64_t, 10> complex_recurse(
>    const uint64_t a0,
>    const uint64_t a1,
>    const uint64_t a2,
>    const uint64_t a3,
>    const uint64_t a4,
>    const uint64_t a5,
>    const uint64_t a6,
>    const uint64_t a7,
>    const uint64_t a8,
>    const uint64_t a9,
>    const uint64_t counter
> ) {
>    if(counter) {
>        if(a0 & 1)
>            if(a1 & 1)
>                if(a2 & 1)
>                    if(a3 & 1)
>                        if(a4 & 1)
>                            if(a5 & 1)
>                                if(a6 & 1)
>                                    if(a7 & 1)
>                                        if(a8 & 1)
>                                            return complex_recurse(a0 + 1,
> a1 + 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8 + 1, a9 + 1,
> counter - 1);
>                                        else
>                                             return complex_recurse(a0 + 1,
> a1 + 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8 + 1, a9, counter
> - 1);
>                                    else
>                                         return complex_recurse(a0 + 1, a1 +
> 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8, a9, counter - 1);
>                                else
>                                     return complex_recurse(a0 + 1, a1 + 1,
> a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7, a8, a9, counter - 1);
>                            else
>                                 return complex_recurse(a0 + 1, a1 + 1, a2 +
> 1, a3 + 1, a4 + 1, a5 + 1, a6, a7, a8, a9, counter - 1);
>                        else
>                             return complex_recurse(a0 + 1, a1 + 1, a2 + 1,
> a3 + 1, a4 + 1, a5, a6, a7, a8, a9, counter - 1);
>                    else
>                         return complex_recurse(a0 + 1, a1 + 1, a2 + 1, a3 +
> 1, a4, a5, a6, a7, a8, a9, counter - 1);
>                else
>                    return complex_recurse(a0 + 1, a1 + 1, a2 + 1, a3, a4, a5
> , a6, a7, a8, a9, counter - 1);
>            else
>                return complex_recurse(a0 + 1, a1 + 1, a2, a3, a4, a5, a6, a7
> , a8, a9, counter - 1);
>        else
>            return complex_recurse(a0 + 1, a1, a2, a3, a4, a5, a6, a7, a8, a9
> , counter - 1);
>    } else {
>        return std::array<uint64_t, 10> { a0, a1, a2, a3, a4, a5, a6, a7, a8,
> a9};
>    }
> }
> int main(int argc, char** argv) {
>    uint64_t times = std::stoull(argv[1]);
>    auto output = complex_recurse(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, times);
>    for(auto elem : output) {
>        std::cout << elem << std::endl;
>    }
> }

Explain where you're seeing tail call optimisation in

https://godbolt.org/g/zA8XCN

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



--
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/3039993.vrrMQ0tnQ4%40tjmaciei-mobl1.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 29 May 2018 21:07:26 -0700
Raw View
On Tuesday, 29 May 2018 18:06:50 PDT Antonio Perez wrote:
> *The other version of Case 2: *Suppose the arguments of function F take up
> N bytes on the stack, and function F calls function G in such a way that
> (under the proposed rule change) the standard requires the call to G be
> tail-call optimized. If the arguments of G take up M bytes on the stack,
> with M > N, then the compiler could allocate an additional (M-N) bytes
> immediately after the space for the arguments of F on the stack. This is
> space that would get allocated anyways when G was called, except instead of
> using worst-case N+M space, tail recursion results in only using M space.

You need to study ABI documents and assembly a little. What you're proposing
cannot be implemented: function F cannot just allocate some more bytes on the
stack. In order for that o work, you need to answer the other end of this:
what deallocates those bytes from the stack.

Not to mention that the standard does not talk about a stack, return pointers
and passing arguments in registers at all. If you want this feature, like I
said in the beginning, describe it without saying "optimisation" or "stack".
Just describe what visible behaviour you want the language to guarantee the
developer.

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



--
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/3816579.35Dq8gmGDy%40tjmaciei-mobl1.

.


Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Wed, 30 May 2018 10:54:51 -0700 (PDT)
Raw View
------=_Part_45647_2053835173.1527702891726
Content-Type: multipart/alternative;
 boundary="----=_Part_45648_1259985484.1527702891726"

------=_Part_45648_1259985484.1527702891726
Content-Type: text/plain; charset="UTF-8"

It's there. If you remove the main method and the #include <iostream> and
#include <string>, the resulting assembly code doesn't contain any calls
whatsoever.

On Tuesday, May 29, 2018 at 10:02:36 PM UTC-6, Thiago Macieira wrote:
>
> On Tuesday, 29 May 2018 18:06:50 PDT Antonio Perez wrote:
> > #include <cstddef>
> > #include <cstdint>
> > #include <array>
> > #include <iostream>
> > #include <string>
> > std::array<uint64_t, 10> complex_recurse(
> >    const uint64_t a0,
> >    const uint64_t a1,
> >    const uint64_t a2,
> >    const uint64_t a3,
> >    const uint64_t a4,
> >    const uint64_t a5,
> >    const uint64_t a6,
> >    const uint64_t a7,
> >    const uint64_t a8,
> >    const uint64_t a9,
> >    const uint64_t counter
> > ) {
> >    if(counter) {
> >        if(a0 & 1)
> >            if(a1 & 1)
> >                if(a2 & 1)
> >                    if(a3 & 1)
> >                        if(a4 & 1)
> >                            if(a5 & 1)
> >                                if(a6 & 1)
> >                                    if(a7 & 1)
> >                                        if(a8 & 1)
> >                                            return complex_recurse(a0 +
> 1,
> > a1 + 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8 + 1, a9 + 1,
> > counter - 1);
> >                                        else
> >                                             return complex_recurse(a0 +
> 1,
> > a1 + 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8 + 1, a9,
> counter
> > - 1);
> >                                    else
> >                                         return complex_recurse(a0 + 1,
> a1 +
> > 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8, a9, counter - 1);
> >                                else
> >                                     return complex_recurse(a0 + 1, a1 +
> 1,
> > a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7, a8, a9, counter - 1);
> >                            else
> >                                 return complex_recurse(a0 + 1, a1 + 1,
> a2 +
> > 1, a3 + 1, a4 + 1, a5 + 1, a6, a7, a8, a9, counter - 1);
> >                        else
> >                             return complex_recurse(a0 + 1, a1 + 1, a2 +
> 1,
> > a3 + 1, a4 + 1, a5, a6, a7, a8, a9, counter - 1);
> >                    else
> >                         return complex_recurse(a0 + 1, a1 + 1, a2 + 1,
> a3 +
> > 1, a4, a5, a6, a7, a8, a9, counter - 1);
> >                else
> >                    return complex_recurse(a0 + 1, a1 + 1, a2 + 1, a3,
> a4, a5
> > , a6, a7, a8, a9, counter - 1);
> >            else
> >                return complex_recurse(a0 + 1, a1 + 1, a2, a3, a4, a5,
> a6, a7
> > , a8, a9, counter - 1);
> >        else
> >            return complex_recurse(a0 + 1, a1, a2, a3, a4, a5, a6, a7,
> a8, a9
> > , counter - 1);
> >    } else {
> >        return std::array<uint64_t, 10> { a0, a1, a2, a3, a4, a5, a6, a7,
> a8,
> > a9};
> >    }
> > }
> > int main(int argc, char** argv) {
> >    uint64_t times = std::stoull(argv[1]);
> >    auto output = complex_recurse(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, times);
> >    for(auto elem : output) {
> >        std::cout << elem << std::endl;
> >    }
> > }
>
> Explain where you're seeing tail call optimisation in
>
> https://godbolt.org/g/zA8XCN
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
>
>
>

--
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/bff2d63d-5dd0-4611-80d1-25974f8cf19a%40isocpp.org.

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

<div dir=3D"ltr">It&#39;s there. If you remove the main method and the #inc=
lude &lt;iostream&gt; and #include &lt;string&gt;, the resulting assembly c=
ode doesn&#39;t contain any calls whatsoever.=C2=A0<br><br>On Tuesday, May =
29, 2018 at 10:02:36 PM UTC-6, Thiago Macieira wrote:<blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;">On Tuesday, 29 May 2018 18:06:50 PDT Antonio Perez w=
rote:
<br>&gt; #include &lt;cstddef&gt;
<br>&gt; #include &lt;cstdint&gt;
<br>&gt; #include &lt;array&gt;
<br>&gt; #include &lt;iostream&gt;
<br>&gt; #include &lt;string&gt;
<br>&gt; std::array&lt;uint64_t, 10&gt; complex_recurse(
<br>&gt; =C2=A0 =C2=A0const uint64_t a0,
<br>&gt; =C2=A0 =C2=A0const uint64_t a1,
<br>&gt; =C2=A0 =C2=A0const uint64_t a2,
<br>&gt; =C2=A0 =C2=A0const uint64_t a3,
<br>&gt; =C2=A0 =C2=A0const uint64_t a4,
<br>&gt; =C2=A0 =C2=A0const uint64_t a5,
<br>&gt; =C2=A0 =C2=A0const uint64_t a6,
<br>&gt; =C2=A0 =C2=A0const uint64_t a7,
<br>&gt; =C2=A0 =C2=A0const uint64_t a8,
<br>&gt; =C2=A0 =C2=A0const uint64_t a9,
<br>&gt; =C2=A0 =C2=A0const uint64_t counter
<br>&gt; ) {
<br>&gt; =C2=A0 =C2=A0if(counter) {
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0if(a0 &amp; 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if(a1 &amp; 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if(a2 &amp;=
 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0if(a3 &amp; 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0if(a4 &amp; 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if(a5 &amp; 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if(a6 &amp; 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if(a7 &amp; 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if=
(a8 &amp; 1)
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0return complex_recurse(a0 + 1,
<br>&gt; a1 + 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8 + 1, a9=
 + 1,
<br>&gt; counter - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0el=
se
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 return complex_recurse(a0 + 1,
<br>&gt; a1 + 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8 + 1, a9=
, counter
<br>&gt; - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 r=
eturn complex_recurse(a0 + 1, a1 +
<br>&gt; 1, a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7 + 1, a8, a9, counter=
 - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return complex_=
recurse(a0 + 1, a1 + 1,
<br>&gt; a2 + 1, a3 + 1, a4 + 1, a5 + 1, a6 + 1, a7, a8, a9, counter - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return complex_recurse(a0 + 1=
, a1 + 1, a2 +
<br>&gt; 1, a3 + 1, a4 + 1, a5 + 1, a6, a7, a8, a9, counter - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0else
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return complex_recurse(a0 + 1, a1 + 1, a2 +=
 1,
<br>&gt; a3 + 1, a4 + 1, a5, a6, a7, a8, a9, counter - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0else
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 return complex_recurse(a0 + 1, a1 + 1, a2 + 1, a3 +
<br>&gt; 1, a4, a5, a6, a7, a8, a9, counter - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0return complex_recurse(a0 + 1, a1 + 1, a2 + 1, a3, a4, a5
<br>&gt; , a6, a7, a8, a9, counter - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return comp=
lex_recurse(a0 + 1, a1 + 1, a2, a3, a4, a5, a6, a7
<br>&gt; , a8, a9, counter - 1);
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0else
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return complex_recurse(a0=
 + 1, a1, a2, a3, a4, a5, a6, a7, a8, a9
<br>&gt; , counter - 1);
<br>&gt; =C2=A0 =C2=A0} else {
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0return std::array&lt;uint64_t, 10&gt; {=
 a0, a1, a2, a3, a4, a5, a6, a7, a8,
<br>&gt; a9};
<br>&gt; =C2=A0 =C2=A0}
<br>&gt; }
<br>&gt; int main(int argc, char** argv) {
<br>&gt; =C2=A0 =C2=A0uint64_t times =3D std::stoull(argv[1]);
<br>&gt; =C2=A0 =C2=A0auto output =3D complex_recurse(0, 0, 0, 0, 0, 0, 0, =
0, 0, 0, times);
<br>&gt; =C2=A0 =C2=A0for(auto elem : output) {
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0std::cout &lt;&lt; elem &lt;&lt; std::e=
ndl;
<br>&gt; =C2=A0 =C2=A0}
<br>&gt; }
<br>
<br>Explain where you&#39;re seeing tail call optimisation in
<br>
<br><a href=3D"https://godbolt.org/g/zA8XCN" target=3D"_blank" rel=3D"nofol=
low" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%=
3A%2F%2Fgodbolt.org%2Fg%2FzA8XCN\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFi=
5TXvZZc76fcPoDJUdlBPvm3uEA&#39;;return true;" onclick=3D"this.href=3D&#39;h=
ttps://www.google.com/url?q\x3dhttps%3A%2F%2Fgodbolt.org%2Fg%2FzA8XCN\x26sa=
\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFi5TXvZZc76fcPoDJUdlBPvm3uEA&#39;;return=
 true;">https://godbolt.org/g/zA8XCN</a>
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br>
<br>
<br></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bff2d63d-5dd0-4611-80d1-25974f8cf19a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bff2d63d-5dd0-4611-80d1-25974f8cf19a=
%40isocpp.org</a>.<br />

------=_Part_45648_1259985484.1527702891726--

------=_Part_45647_2053835173.1527702891726--

.


Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Wed, 30 May 2018 11:52:15 -0700 (PDT)
Raw View
------=_Part_35150_759547788.1527706335653
Content-Type: multipart/alternative;
 boundary="----=_Part_35151_675917088.1527706335653"

------=_Part_35151_675917088.1527706335653
Content-Type: text/plain; charset="UTF-8"

*UPDATE*

Thank you, everyone, for the feedback to this proposal. I understand the
difficulties with requiring "tail calls should be optimized", and I will
work to develop several separate proposals which I believe will, together,
guarantee tail-call optimization.

--
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/265642a6-ae7e-46ad-b5b2-f912b2ed7cd5%40isocpp.org.

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

<div dir=3D"ltr"><b>UPDATE</b><div><b><br></b></div><div>Thank you, everyon=
e, for the feedback to this proposal. I understand the difficulties with re=
quiring &quot;tail calls should be optimized&quot;, and I will work to deve=
lop several separate proposals which I believe will, together, guarantee ta=
il-call optimization.=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/265642a6-ae7e-46ad-b5b2-f912b2ed7cd5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/265642a6-ae7e-46ad-b5b2-f912b2ed7cd5=
%40isocpp.org</a>.<br />

------=_Part_35151_675917088.1527706335653--

------=_Part_35150_759547788.1527706335653--

.


Author: inkwizytoryankes@gmail.com
Date: Wed, 30 May 2018 14:21:09 -0700 (PDT)
Raw View
------=_Part_360_1341593166.1527715269850
Content-Type: multipart/alternative;
 boundary="----=_Part_361_1473947536.1527715269851"

------=_Part_361_1473947536.1527715269851
Content-Type: text/plain; charset="UTF-8"



On Wednesday, May 30, 2018 at 1:25:46 AM UTC+2, Thiago Macieira wrote:
>
> On Tuesday, 29 May 2018 15:59:13 PDT Antonio Perez wrote:
> > I don't think you understand the point I made:
> > An optimization is not something you can assume and structure your
> entire
> > code around.
>
> Case 1:
>
> void __cdecl f(int);
> void __stdcall g()
> {
>     f(0);
> }
>
> For __stdcall:
> https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
>  "Called function pops its own arguments from the stack."
>
> For __cdecl:
> https://msdn.microsoft.com/en-us/library/zkwh89ks.aspx
>   "Calling function pops the arguments from the stack."
>
> The function that called g is expecting g() to clean up its stack. But
> f()'s
> caller expects its caller to clean up the stack. So who cleans up in the
> case
> above, for tail-call?
>
> Case 2:
>
> The number of arguments passed on the stack are different, and thus
> there's a
> difference in cleaning up. Most modern architectures pass the main
> arguments
> in registers, but in ALL modern architectures, the limit is 8 arguments.
> In
> some, it's quite fewer (ARM 32-bit, Windows 64-bit x86 both are 4). And,
> of
> course, 32-bit x86 passes no arguments in registers.
>
> Case 2 is made more difficult by the requirement that the stack be aligned
> to
> a multiple of 16 on x86.
>
>
> Tests, two in one: https://godbolt.org/g/ovbSk9. That's four compilers,
> no
> tail call optimisation.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
>
>
>
I think that if we add opt-in requirement then most of this problems
despair because it could be rejected at compile time, we can add some
generic limitations and force compiler to do it even without optimization.
Another thing is we could change lifetime of local variables to fit
tail-call recursion. Something like that:

class NotTrival;
int foo(int, int);
int bar(int a, int b) tailcall //new contextual keyword
{
  NotTrival z; //this normaly would prevent compiler from doing tail-call
  return foo(a, b);// scope ends BEFORE `foo` "call", `a` and `b` can have
additional copies done to escape ending scope that destroy all variables
}


If this is impossible to do then compiler can simply print error. Every
`return` should return variable or call function than can be tail-call.
This will allow to disable this for some paths:
float bar(float);
int foo(int i) tailcall
{
  auto f = bar(i * 0.5); //it could be tail-call by compiler but for
simplicity and portability we disallow this
  return f;
}


--
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/087fca95-71bb-44b8-baec-62351b4dc9d3%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Wednesday, May 30, 2018 at 1:25:46 AM UTC+2, Th=
iago Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Tuesday=
, 29 May 2018 15:59:13 PDT Antonio Perez wrote:
<br>&gt; I don&#39;t think you understand the point I made:
<br>&gt; An optimization is not something you can assume and structure your=
 entire
<br>&gt; code around.
<br>
<br>Case 1:
<br>
<br>void __cdecl f(int);
<br>void __stdcall g()
<br>{
<br>=C2=A0 =C2=A0 f(0);
<br>}
<br>
<br>For __stdcall:
<br><a href=3D"https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx" targ=
et=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.=
google.com/url?q\x3dhttps%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fzx=
k0tw93.aspx\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFsW7jvTUm4MUs-OvUJYDYWT=
T8FvA&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com=
/url?q\x3dhttps%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fzxk0tw93.asp=
x\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFsW7jvTUm4MUs-OvUJYDYWTT8FvA&#39;=
;return true;">https://msdn.microsoft.com/en-<wbr>us/library/zxk0tw93.aspx<=
/a>
<br>=C2=A0&quot;Called function pops its own arguments from the stack.&quot=
;
<br>
<br>For __cdecl:
<br><a href=3D"https://msdn.microsoft.com/en-us/library/zkwh89ks.aspx" targ=
et=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.=
google.com/url?q\x3dhttps%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fzk=
wh89ks.aspx\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFpuk5Iib3AV1_WP3k0T1Nau=
ule_w&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com=
/url?q\x3dhttps%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fzkwh89ks.asp=
x\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFpuk5Iib3AV1_WP3k0T1Nauule_w&#39;=
;return true;">https://msdn.microsoft.com/en-<wbr>us/library/zkwh89ks.aspx<=
/a>
<br>=C2=A0 &quot;Calling function pops the arguments from the stack.&quot;
<br>
<br>The function that called g is expecting g() to clean up its stack. But =
f()&#39;s=20
<br>caller expects its caller to clean up the stack. So who cleans up in th=
e case=20
<br>above, for tail-call?
<br>
<br>Case 2:
<br>
<br>The number of arguments passed on the stack are different, and thus the=
re&#39;s a=20
<br>difference in cleaning up. Most modern architectures pass the main argu=
ments=20
<br>in registers, but in ALL modern architectures, the limit is 8 arguments=
.. In=20
<br>some, it&#39;s quite fewer (ARM 32-bit, Windows 64-bit x86 both are 4).=
 And, of=20
<br>course, 32-bit x86 passes no arguments in registers.
<br>
<br>Case 2 is made more difficult by the requirement that the stack be alig=
ned to=20
<br>a multiple of 16 on x86.
<br>
<br>
<br>Tests, two in one: <a href=3D"https://godbolt.org/g/ovbSk9" target=3D"_=
blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.=
com/url?q\x3dhttps%3A%2F%2Fgodbolt.org%2Fg%2FovbSk9\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNG2FWD0npHe7aWG0bM_PJQ4VXdxjg&#39;;return true;" onclick=3D=
"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgodbolt.org=
%2Fg%2FovbSk9\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG2FWD0npHe7aWG0bM_PJQ=
4VXdxjg&#39;;return true;">https://godbolt.org/g/ovbSk9</a>. That&#39;s fou=
r compilers, no=20
<br>tail call optimisation.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br>
<br>
<br></blockquote><div><br></div><div>I think that if we add opt-in requirem=
ent then most of this problems despair because it could be rejected at comp=
ile time, we can add some generic limitations and force compiler to do it e=
ven without optimization.</div><div>Another thing is we could change lifeti=
me of local variables to fit tail-call recursion. Something like that:</div=
><div><br></div><div><div style=3D"background-color: rgb(250, 250, 250); bo=
rder-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; ove=
rflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint">=
<div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-=
by-prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">N=
otTrival</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: #008;" class=3D"styled-by-prettify">int</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">int</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">int</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> bar</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #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-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tailcall=
 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//new con=
textual keyword</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>=C2=A0=
 </span><span style=3D"color: #606;" class=3D"styled-by-prettify">NotTrival=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> z</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #800;" class=3D"styled-by-prettify">//this normaly would prevent compile=
r from doing tail-call</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #=
800;" class=3D"styled-by-prettify">// scope ends BEFORE `foo` &quot;call&qu=
ot;, `a` and `b` can have additional copies done to escape ending scope tha=
t destroy all variables</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r><br></span></div></code></div><br>If this is impossible to do then compil=
er can simply print error. Every `return` should return variable or call fu=
nction than can be tail-call. This will allow to disable this for some path=
s:</div><div><div style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wr=
ap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">float</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">float</span><sp=
an 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">int</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> i</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tail=
call<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> f </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">i </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pret=
tify">0.5</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: #800;" class=3D"styled-by-prettify">//it could be tail=
-call by compiler but for simplicity and portability we disallow this</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</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">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><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/087fca95-71bb-44b8-baec-62351b4dc9d3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/087fca95-71bb-44b8-baec-62351b4dc9d3=
%40isocpp.org</a>.<br />

------=_Part_361_1473947536.1527715269851--

------=_Part_360_1341593166.1527715269850--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 30 May 2018 20:56:20 -0700
Raw View
On Wednesday, 30 May 2018 10:54:51 PDT Antonio Perez wrote:
> It's there. If you remove the main method and the #include <iostream> and
> #include <string>, the resulting assembly code doesn't contain any calls
> whatsoever.

I don't see anything about tail-call optimisation. I see a lot of inlining by
GCC and Clang. I see no tail-call optimisation or inlining with ICC and MSVC.

So I don't think your example shows anything.

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



--
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/4452235.Hz1C2I9rOp%40tjmaciei-mobl1.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 30 May 2018 21:03:14 -0700
Raw View
On Wednesday, 30 May 2018 14:21:09 PDT inkwizytoryankes@gmail.com wrote:
> int bar(int a, int b) tailcall //new contextual keyword

We could do that.

Why should we? I haven't heard a good, compelling argument for why we should
go through the trouble. The only thing that a tail-call optimisation helps is
reduce resource consumption (stack), something that isn't in the standard in
the first place. Other than that, there's no observable behaviour.

What algorithms would benefit from this? Is there anything that could be
implemented using it that cannot be today?

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



--
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/2631070.P4Dxe4lEtQ%40tjmaciei-mobl1.

.


Author: "dgutson ." <danielgutson@gmail.com>
Date: Thu, 31 May 2018 01:11:06 -0300
Raw View
--000000000000c0c29e056d78a884
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

El jue., 31 de mayo de 2018 1:03, Thiago Macieira <thiago@macieira.org>
escribi=C3=B3:

> On Wednesday, 30 May 2018 14:21:09 PDT inkwizytoryankes@gmail.com wrote:
> > int bar(int a, int b) tailcall //new contextual keyword
>
> We could do that.
>
> Why should we? I haven't heard a good, compelling argument for why we
> should
> go through the trouble. The only thing that a tail-call optimisation help=
s
> is
> reduce resource consumption (stack), something that isn't in the standard
> in
> the first place. Other than that, there's no observable behaviour.
>
> What algorithms would benefit from this? Is there anything that could be
> implemented using it that cannot be today?
>

I would liketo comment on the "how" rather than the "why": maybe two
attributes could help: one to tag the function signature (or the return
type) and another to tag the call statement.
These tags would, actually, help to diagnose when conditions (specofic for
the compiler) to do tail call opt cannot be met, so the user is warned and
maybe hinted. A way for the user of saying "I want, or I think you compiler
should optimoze here, let me know if you can't ". And of course, could be
optionally implemented.


> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
>
>
> --
> 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/2631070.P4Dx=
e4lEtQ%40tjmaciei-mobl1
> .
>

--=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/CAFdMc-2cOkt9fU5QCpySCiYaBWor8XUhxf2LpkNJ5bSyE1_=
LfA%40mail.gmail.com.

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

<div dir=3D"auto"><div><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">=
El jue., 31 de mayo de 2018 1:03, Thiago Macieira &lt;<a href=3D"mailto:thi=
ago@macieira.org">thiago@macieira.org</a>&gt; escribi=C3=B3:<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex">On Wednesday, 30 May 2018 14:21:09 PDT <a href=3D=
"mailto:inkwizytoryankes@gmail.com" target=3D"_blank" rel=3D"noreferrer">in=
kwizytoryankes@gmail.com</a> wrote:<br>
&gt; int bar(int a, int b) tailcall //new contextual keyword<br>
<br>
We could do that.<br>
<br>
Why should we? I haven&#39;t heard a good, compelling argument for why we s=
hould <br>
go through the trouble. The only thing that a tail-call optimisation helps =
is <br>
reduce resource consumption (stack), something that isn&#39;t in the standa=
rd in <br>
the first place. Other than that, there&#39;s no observable behaviour.<br>
<br>
What algorithms would benefit from this? Is there anything that could be <b=
r>
implemented using it that cannot be today?<br></blockquote></div></div><div=
 dir=3D"auto"><br></div><div dir=3D"auto">I would liketo comment on the &qu=
ot;how&quot; rather than the &quot;why&quot;: maybe two attributes could he=
lp: one to tag the function signature (or the return type) and another to t=
ag the call statement.</div><div dir=3D"auto">These tags would, actually, h=
elp to diagnose when conditions (specofic for the compiler) to do tail call=
 opt cannot be met, so the user is warned and maybe hinted. A way for the u=
ser of saying &quot;I want, or I think you compiler should optimoze here, l=
et me know if you can&#39;t &quot;. And of course, could be optionally impl=
emented.</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"g=
mail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex">
<br>
-- <br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer noreferrer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=
=3D"http://kde.org" rel=3D"noreferrer noreferrer" target=3D"_blank">kde.org=
</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
<br>
<br>
<br>
-- <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%2Bunsubscribe@isocpp.org" target=3D=
"_blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/2631070.P4Dxe4lEtQ%40tjmaciei-mobl1" =
rel=3D"noreferrer noreferrer" target=3D"_blank">https://groups.google.com/a=
/isocpp.org/d/msgid/std-proposals/2631070.P4Dxe4lEtQ%40tjmaciei-mobl1</a>.<=
br>
</blockquote></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAFdMc-2cOkt9fU5QCpySCiYaBWor8XUhxf2L=
pkNJ5bSyE1_LfA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFdMc-2cOkt9fU5Q=
CpySCiYaBWor8XUhxf2LpkNJ5bSyE1_LfA%40mail.gmail.com</a>.<br />

--000000000000c0c29e056d78a884--

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Thu, 31 May 2018 09:30:15 +0200
Raw View
On Wed, May 30, 2018 at 09:03:14PM -0700, Thiago Macieira wrote:
> On Wednesday, 30 May 2018 14:21:09 PDT inkwizytoryankes@gmail.com wrote:
> > int bar(int a, int b) tailcall //new contextual keyword
>
> We could do that.
>
> Why should we? I haven't heard a good, compelling argument for why we should
> go through the trouble. The only thing that a tail-call optimisation helps is
> reduce resource consumption (stack), something that isn't in the standard in
> the first place.

In standardeese I suppose this would create a subclass of function calls that
won't contribute to the minimum call stack depth implementation limit.

> Other than that, there's no observable behaviour.
>
> What algorithms would benefit from this?

Any tail recursive algorithm.

> Is there anything that could be implemented using it that cannot be today?

No, since it, IIRC from my CS days, is proven that any tail recursive
algorithm can be converted to a loop.

No, I do not think this is worth the standardization effort.

/MF

--
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/20180531073015.GA18526%40noemi.bahnhof.se.

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Thu, 31 May 2018 10:10:06 +0200
Raw View
--0000000000007b034a056d7bffb6
Content-Type: text/plain; charset="UTF-8"

I've followed this thread with interest.

If I am correct, the proposal seems to be that the programmer is to be
given a way to *coerce* the compiler into implementing *logical* recursion
as a *physical* loop.

The proposal immediately smells a little to me because it's *conflating
logical intent* (recursive algorithm) *with physical implementation* (a
machine code loop). This breaks the useful separation between the language
model and the hardware. It is this separation that allows the as-if rule,
which leads to aggressive and reliable optimisations.

This seems to be against the grain of the purpose of a language definition
and would seem at best to be in the realm of compiler extension, perhaps
implemented as a #pragma.

Ignoring this, I think there are some useful tests we could apply:

1. Is a language change required because the task is currently not possible
or overly difficult when implemented another way?
2. Will it be logically meaningful on every conceivable future hardware
implementation?
3. Does it provide sufficient benefit to the user community to justify the
increased complexity and  explanations of all cases where the function must
fail to compile?
4. Is the proposal actually a specialisation of a wider principle?

My answers are:

1. No, today we can simply write a loop [fact], which unless you are a
functional programming enthusiast, is arguably clearer [opinion].
2. Probably unanswerable in this case.
3. As a long-time teacher and user of c++, my opinion leans towards no.
4. It seems to me that yes, this is a special case of the wider principle
of requesting space and speed optimisations, which are an implementation
detail of the compiler.



On Thu, 31 May 2018 at 09:30, Magnus Fromreide <magfr@lysator.liu.se> wrote:

> On Wed, May 30, 2018 at 09:03:14PM -0700, Thiago Macieira wrote:
> > On Wednesday, 30 May 2018 14:21:09 PDT inkwizytoryankes@gmail.com wrote:
> > > int bar(int a, int b) tailcall //new contextual keyword
> >
> > We could do that.
> >
> > Why should we? I haven't heard a good, compelling argument for why we
> should
> > go through the trouble. The only thing that a tail-call optimisation
> helps is
> > reduce resource consumption (stack), something that isn't in the
> standard in
> > the first place.
>
> In standardeese I suppose this would create a subclass of function calls
> that
> won't contribute to the minimum call stack depth implementation limit.
>
> > Other than that, there's no observable behaviour.
> >
> > What algorithms would benefit from this?
>
> Any tail recursive algorithm.
>
> > Is there anything that could be implemented using it that cannot be
> today?
>
> No, since it, IIRC from my CS days, is proven that any tail recursive
> algorithm can be converted to a loop.
>
> No, I do not think this is worth the standardization effort.
>
> /MF
>
> --
> 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/20180531073015.GA18526%40noemi.bahnhof.se
> .
>

--
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/CALvx3hY2OnofrL2Qpp-EjuLzYrgWFXDOYEaTigDQ-P4YJCExkg%40mail.gmail.com.

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

<div dir=3D"ltr">I&#39;ve followed this thread with interest.<div><br></div=
><div>If I am correct, the proposal seems to be that the programmer is to b=
e given a way to <i>coerce</i> the compiler into implementing <i>logical</i=
> recursion as a <i>physical</i> loop.</div><div><br></div><div>The proposa=
l immediately smells a little to me because it&#39;s <i><b>conflating logic=
al intent</b></i> (recursive algorithm) <i><b>with physical implementation<=
/b></i> (a machine code loop). This breaks the useful separation between th=
e language model and the hardware. It is this separation that allows the as=
-if rule, which leads to aggressive and reliable optimisations.</div><div><=
br></div><div>This seems to be against the grain of the purpose of a langua=
ge definition and would seem at best to be in the realm of compiler extensi=
on, perhaps implemented as a #pragma.</div><div><br></div><div>Ignoring thi=
s, I think there are some useful tests we could apply:</div><div><br></div>=
<div>1. Is a language change required because the task is currently not pos=
sible or overly difficult when implemented another way?</div><div>2. Will i=
t be logically meaningful on every conceivable future hardware implementati=
on?</div><div>3. Does it provide sufficient benefit to the user community t=
o justify the increased complexity and=C2=A0 explanations of all cases wher=
e the function must fail to compile?</div><div>4. Is the proposal actually =
a specialisation of a wider principle?=C2=A0</div><div><br></div><div>My an=
swers are:</div><div><br>1. No, today we can simply write a loop [fact], wh=
ich unless you are a functional programming enthusiast, is arguably clearer=
 [opinion].</div><div>2. Probably unanswerable in this case.<br>3. As a lon=
g-time teacher and user of c++, my opinion leans towards no.</div><div>4. I=
t seems to me that yes, this is a special case of the wider principle of re=
questing space and speed optimisations, which are an implementation detail =
of the compiler.</div><div><br><br></div></div><br><div class=3D"gmail_quot=
e"><div dir=3D"ltr">On Thu, 31 May 2018 at 09:30, Magnus Fromreide &lt;<a h=
ref=3D"mailto:magfr@lysator.liu.se">magfr@lysator.liu.se</a>&gt; wrote:<br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">On Wed, May 30, 2018 at 09:03:14PM -07=
00, Thiago Macieira wrote:<br>
&gt; On Wednesday, 30 May 2018 14:21:09 PDT <a href=3D"mailto:inkwizytoryan=
kes@gmail.com" target=3D"_blank">inkwizytoryankes@gmail.com</a> wrote:<br>
&gt; &gt; int bar(int a, int b) tailcall //new contextual keyword<br>
&gt; <br>
&gt; We could do that.<br>
&gt; <br>
&gt; Why should we? I haven&#39;t heard a good, compelling argument for why=
 we should <br>
&gt; go through the trouble. The only thing that a tail-call optimisation h=
elps is <br>
&gt; reduce resource consumption (stack), something that isn&#39;t in the s=
tandard in <br>
&gt; the first place.<br>
<br>
In standardeese I suppose this would create a subclass of function calls th=
at<br>
won&#39;t contribute to the minimum call stack depth implementation limit.<=
br>
<br>
&gt; Other than that, there&#39;s no observable behaviour.<br>
&gt; <br>
&gt; What algorithms would benefit from this?<br>
<br>
Any tail recursive algorithm.<br>
<br>
&gt; Is there anything that could be implemented using it that cannot be to=
day?<br>
<br>
No, since it, IIRC from my CS days, is proven that any tail recursive<br>
algorithm can be converted to a loop.<br>
<br>
No, I do not think this is worth the standardization effort.<br>
<br>
/MF<br>
<br>
-- <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%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20180531073015.GA18526%40noemi.bahnho=
f.se" rel=3D"noreferrer" target=3D"_blank">https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/20180531073015.GA18526%40noemi.bahnhof.se</a>.=
<br>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3hY2OnofrL2Qpp-EjuLzYrgWFXDOYEaT=
igDQ-P4YJCExkg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hY2OnofrL2Q=
pp-EjuLzYrgWFXDOYEaTigDQ-P4YJCExkg%40mail.gmail.com</a>.<br />

--0000000000007b034a056d7bffb6--

.


Author: =?UTF-8?B?R2HFoXBlciBBxb5tYW4=?= <gasper.azman@gmail.com>
Date: Thu, 31 May 2018 09:31:56 +0100
Raw View
--0000000000008f7199056d7c4d13
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

I believe a related thing might be the tail return proposed by the core
coroutines paper - p1063r0.

It's needed for correctness there.

Ga=C5=A1per

On Thu, May 31, 2018, 09:10 Richard Hodges <hodges.r@gmail.com> wrote:

> I've followed this thread with interest.
>
> If I am correct, the proposal seems to be that the programmer is to be
> given a way to *coerce* the compiler into implementing *logical*
> recursion as a *physical* loop.
>
> The proposal immediately smells a little to me because it's *conflating
> logical intent* (recursive algorithm) *with physical implementation* (a
> machine code loop). This breaks the useful separation between the languag=
e
> model and the hardware. It is this separation that allows the as-if rule,
> which leads to aggressive and reliable optimisations.
>
> This seems to be against the grain of the purpose of a language definitio=
n
> and would seem at best to be in the realm of compiler extension, perhaps
> implemented as a #pragma.
>
> Ignoring this, I think there are some useful tests we could apply:
>
> 1. Is a language change required because the task is currently not
> possible or overly difficult when implemented another way?
> 2. Will it be logically meaningful on every conceivable future hardware
> implementation?
> 3. Does it provide sufficient benefit to the user community to justify th=
e
> increased complexity and  explanations of all cases where the function mu=
st
> fail to compile?
> 4. Is the proposal actually a specialisation of a wider principle?
>
> My answers are:
>
> 1. No, today we can simply write a loop [fact], which unless you are a
> functional programming enthusiast, is arguably clearer [opinion].
> 2. Probably unanswerable in this case.
> 3. As a long-time teacher and user of c++, my opinion leans towards no.
> 4. It seems to me that yes, this is a special case of the wider principle
> of requesting space and speed optimisations, which are an implementation
> detail of the compiler.
>
>
>
> On Thu, 31 May 2018 at 09:30, Magnus Fromreide <magfr@lysator.liu.se>
> wrote:
>
>> On Wed, May 30, 2018 at 09:03:14PM -0700, Thiago Macieira wrote:
>> > On Wednesday, 30 May 2018 14:21:09 PDT inkwizytoryankes@gmail.com
>> wrote:
>> > > int bar(int a, int b) tailcall //new contextual keyword
>> >
>> > We could do that.
>> >
>> > Why should we? I haven't heard a good, compelling argument for why we
>> should
>> > go through the trouble. The only thing that a tail-call optimisation
>> helps is
>> > reduce resource consumption (stack), something that isn't in the
>> standard in
>> > the first place.
>>
>> In standardeese I suppose this would create a subclass of function calls
>> that
>> won't contribute to the minimum call stack depth implementation limit.
>>
>> > Other than that, there's no observable behaviour.
>> >
>> > What algorithms would benefit from this?
>>
>> Any tail recursive algorithm.
>>
>> > Is there anything that could be implemented using it that cannot be
>> today?
>>
>> No, since it, IIRC from my CS days, is proven that any tail recursive
>> algorithm can be converted to a loop.
>>
>> No, I do not think this is worth the standardization effort.
>>
>> /MF
>>
>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/20180531073=
015.GA18526%40noemi.bahnhof.se
>> .
>>
> --
> 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/CALvx3hY2Ono=
frL2Qpp-EjuLzYrgWFXDOYEaTigDQ-P4YJCExkg%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hY2On=
ofrL2Qpp-EjuLzYrgWFXDOYEaTigDQ-P4YJCExkg%40mail.gmail.com?utm_medium=3Demai=
l&utm_source=3Dfooter>
> .
>

--=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%3DkUYbYgKdE8%2BFT9%3D1DZK3Os48ofMstUmSTkNB=
Duw7sbeDA%40mail.gmail.com.

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

<div dir=3D"auto">I believe a related thing might be the tail return propos=
ed by the core coroutines paper - p1063r0.<div dir=3D"auto"><br></div><div =
dir=3D"auto">It&#39;s needed for correctness there.</div><div dir=3D"auto">=
<br></div><div dir=3D"auto">Ga=C5=A1per</div></div><br><div class=3D"gmail_=
quote"><div dir=3D"ltr">On Thu, May 31, 2018, 09:10 Richard Hodges &lt;<a h=
ref=3D"mailto:hodges.r@gmail.com">hodges.r@gmail.com</a>&gt; wrote:<br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I&#39;ve followed this th=
read with interest.<div><br></div><div>If I am correct, the proposal seems =
to be that the programmer is to be given a way to <i>coerce</i> the compile=
r into implementing <i>logical</i> recursion as a <i>physical</i> loop.</di=
v><div><br></div><div>The proposal immediately smells a little to me becaus=
e it&#39;s <i><b>conflating logical intent</b></i> (recursive algorithm) <i=
><b>with physical implementation</b></i> (a machine code loop). This breaks=
 the useful separation between the language model and the hardware. It is t=
his separation that allows the as-if rule, which leads to aggressive and re=
liable optimisations.</div><div><br></div><div>This seems to be against the=
 grain of the purpose of a language definition and would seem at best to be=
 in the realm of compiler extension, perhaps implemented as a #pragma.</div=
><div><br></div><div>Ignoring this, I think there are some useful tests we =
could apply:</div><div><br></div><div>1. Is a language change required beca=
use the task is currently not possible or overly difficult when implemented=
 another way?</div><div>2. Will it be logically meaningful on every conceiv=
able future hardware implementation?</div><div>3. Does it provide sufficien=
t benefit to the user community to justify the increased complexity and=C2=
=A0 explanations of all cases where the function must fail to compile?</div=
><div>4. Is the proposal actually a specialisation of a wider principle?=C2=
=A0</div><div><br></div><div>My answers are:</div><div><br>1. No, today we =
can simply write a loop [fact], which unless you are a functional programmi=
ng enthusiast, is arguably clearer [opinion].</div><div>2. Probably unanswe=
rable in this case.<br>3. As a long-time teacher and user of c++, my opinio=
n leans towards no.</div><div>4. It seems to me that yes, this is a special=
 case of the wider principle of requesting space and speed optimisations, w=
hich are an implementation detail of the compiler.</div><div><br><br></div>=
</div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, 31 May 2018 a=
t 09:30, Magnus Fromreide &lt;<a href=3D"mailto:magfr@lysator.liu.se" targe=
t=3D"_blank" rel=3D"noreferrer">magfr@lysator.liu.se</a>&gt; wrote:<br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex">On Wed, May 30, 2018 at 09:03:14PM -0700, =
Thiago Macieira wrote:<br>
&gt; On Wednesday, 30 May 2018 14:21:09 PDT <a href=3D"mailto:inkwizytoryan=
kes@gmail.com" target=3D"_blank" rel=3D"noreferrer">inkwizytoryankes@gmail.=
com</a> wrote:<br>
&gt; &gt; int bar(int a, int b) tailcall //new contextual keyword<br>
&gt; <br>
&gt; We could do that.<br>
&gt; <br>
&gt; Why should we? I haven&#39;t heard a good, compelling argument for why=
 we should <br>
&gt; go through the trouble. The only thing that a tail-call optimisation h=
elps is <br>
&gt; reduce resource consumption (stack), something that isn&#39;t in the s=
tandard in <br>
&gt; the first place.<br>
<br>
In standardeese I suppose this would create a subclass of function calls th=
at<br>
won&#39;t contribute to the minimum call stack depth implementation limit.<=
br>
<br>
&gt; Other than that, there&#39;s no observable behaviour.<br>
&gt; <br>
&gt; What algorithms would benefit from this?<br>
<br>
Any tail recursive algorithm.<br>
<br>
&gt; Is there anything that could be implemented using it that cannot be to=
day?<br>
<br>
No, since it, IIRC from my CS days, is proven that any tail recursive<br>
algorithm can be converted to a loop.<br>
<br>
No, I do not think this is worth the standardization effort.<br>
<br>
/MF<br>
<br>
-- <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%2Bunsubscribe@isocpp.org" target=3D=
"_blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/20180531073015.GA18526%40noemi.bahnho=
f.se" rel=3D"noreferrer noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/d/msgid/std-proposals/20180531073015.GA18526%40noemi.bahn=
hof.se</a>.<br>
</blockquote></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/CALvx3hY2OnofrL2Qpp-EjuLzYrgWFXDOYEaT=
igDQ-P4YJCExkg%40mail.gmail.com?utm_medium=3Demail&amp;utm_source=3Dfooter"=
 target=3D"_blank" rel=3D"noreferrer">https://groups.google.com/a/isocpp.or=
g/d/msgid/std-proposals/CALvx3hY2OnofrL2Qpp-EjuLzYrgWFXDOYEaTigDQ-P4YJCExkg=
%40mail.gmail.com</a>.<br>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkUYbYgKdE8%2BFT9%3D1DZK3Os48o=
fMstUmSTkNBDuw7sbeDA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkUY=
bYgKdE8%2BFT9%3D1DZK3Os48ofMstUmSTkNBDuw7sbeDA%40mail.gmail.com</a>.<br />

--0000000000008f7199056d7c4d13--

.


Author: inkwizytoryankes@gmail.com
Date: Thu, 31 May 2018 04:19:02 -0700 (PDT)
Raw View
------=_Part_3496_194883499.1527765542228
Content-Type: multipart/alternative;
 boundary="----=_Part_3497_331153687.1527765542229"

------=_Part_3497_331153687.1527765542229
Content-Type: text/plain; charset="UTF-8"



On Thursday, May 31, 2018 at 10:10:20 AM UTC+2, Richard Hodges wrote:
>
> I've followed this thread with interest.
>
> If I am correct, the proposal seems to be that the programmer is to be
> given a way to *coerce* the compiler into implementing *logical*
> recursion as a *physical* loop.
>
> The proposal immediately smells a little to me because it's *conflating
> logical intent* (recursive algorithm) *with physical implementation* (a
> machine code loop). This breaks the useful separation between the language
> model and the hardware. It is this separation that allows the as-if rule,
> which leads to aggressive and reliable optimisations.
>
> This seems to be against the grain of the purpose of a language definition
> and would seem at best to be in the realm of compiler extension, perhaps
> implemented as a #pragma.
>
> Ignoring this, I think there are some useful tests we could apply:
>
> 1. Is a language change required because the task is currently not
> possible or overly difficult when implemented another way?
> 2. Will it be logically meaningful on every conceivable future hardware
> implementation?
> 3. Does it provide sufficient benefit to the user community to justify the
> increased complexity and  explanations of all cases where the function must
> fail to compile?
> 4. Is the proposal actually a specialisation of a wider principle?
>
> My answers are:
>
> 1. No, today we can simply write a loop [fact], which unless you are a
> functional programming enthusiast, is arguably clearer [opinion].
> 2. Probably unanswerable in this case.
> 3. As a long-time teacher and user of c++, my opinion leans towards no.
> 4. It seems to me that yes, this is a special case of the wider principle
> of requesting space and speed optimisations, which are an implementation
> detail of the compiler.
>
>
>
> On Thu, 31 May 2018 at 09:30, Magnus Fromreide <ma...@lysator.liu.se
> <javascript:>> wrote:
>
>> On Wed, May 30, 2018 at 09:03:14PM -0700, Thiago Macieira wrote:
>> > On Wednesday, 30 May 2018 14:21:09 PDT inkwizyt...@gmail.com
>> <javascript:> wrote:
>> > > int bar(int a, int b) tailcall //new contextual keyword
>> >
>> > We could do that.
>> >
>> > Why should we? I haven't heard a good, compelling argument for why we
>> should
>> > go through the trouble. The only thing that a tail-call optimisation
>> helps is
>> > reduce resource consumption (stack), something that isn't in the
>> standard in
>> > the first place.
>>
>> In standardeese I suppose this would create a subclass of function calls
>> that
>> won't contribute to the minimum call stack depth implementation limit.
>>
>> > Other than that, there's no observable behaviour.
>> >
>> > What algorithms would benefit from this?
>>
>> Any tail recursive algorithm.
>>
>> > Is there anything that could be implemented using it that cannot be
>> today?
>>
>> No, since it, IIRC from my CS days, is proven that any tail recursive
>> algorithm can be converted to a loop.
>>
>> No, I do not think this is worth the standardization effort.
>>
>> /MF
>>
>> --
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20180531073015.GA18526%40noemi.bahnhof.se
>> .
>>
>
I do not see tail-call as optimization but as control structure, probably
best place where I could use it is state machine.
Consider this code:
void state_a(input i) tailcall
{
  if (i.next() == 5)
  {
    return state_b(i);
  }
  else
  {
    return state_c(i); //what do state `c`? it could be loaded from dll but
it will still work fine
  }
}

void state_b(input i) tailcall
{
  if (i.next() == 0)
  {
    return state_a(i);
  }
  else
  {
    return state_end(i);
  }
}
Couple observation:
You can implement this as switch but how big it will be? and how easy to
expand. I would consider this as syntax sugar.

You can't determine stack size because you do not control `input`, there is
no implementation that handle this, even more if it could then you could
use whole memory if someone try DDoS you and it will afect other processes.
With tail-call resources usage is deterministic and have cap independent of
inputs. And it can work indefinite.

Rule could be simple, signature need be same and parameters should be
copyable/movable (or references but then you are forbidden to pass local
variables or temporals to it).


--
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/17e39178-4555-44ce-bb2e-91b3e626513a%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Thursday, May 31, 2018 at 10:10:20 AM UTC+2, Ri=
chard Hodges wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">I&#39;ve followed this thread with interest.<div><br></div><div>If I =
am correct, the proposal seems to be that the programmer is to be given a w=
ay to <i>coerce</i> the compiler into implementing <i>logical</i> recursion=
 as a <i>physical</i> loop.</div><div><br></div><div>The proposal immediate=
ly smells a little to me because it&#39;s <i><b>conflating logical intent</=
b></i> (recursive algorithm) <i><b>with physical implementation</b></i> (a =
machine code loop). This breaks the useful separation between the language =
model and the hardware. It is this separation that allows the as-if rule, w=
hich leads to aggressive and reliable optimisations.</div><div><br></div><d=
iv>This seems to be against the grain of the purpose of a language definiti=
on and would seem at best to be in the realm of compiler extension, perhaps=
 implemented as a #pragma.</div><div><br></div><div>Ignoring this, I think =
there are some useful tests we could apply:</div><div><br></div><div>1. Is =
a language change required because the task is currently not possible or ov=
erly difficult when implemented another way?</div><div>2. Will it be logica=
lly meaningful on every conceivable future hardware implementation?</div><d=
iv>3. Does it provide sufficient benefit to the user community to justify t=
he increased complexity and=C2=A0 explanations of all cases where the funct=
ion must fail to compile?</div><div>4. Is the proposal actually a specialis=
ation of a wider principle?=C2=A0</div><div><br></div><div>My answers are:<=
/div><div><br>1. No, today we can simply write a loop [fact], which unless =
you are a functional programming enthusiast, is arguably clearer [opinion].=
</div><div>2. Probably unanswerable in this case.<br>3. As a long-time teac=
her and user of c++, my opinion leans towards no.</div><div>4. It seems to =
me that yes, this is a special case of the wider principle of requesting sp=
ace and speed optimisations, which are an implementation detail of the comp=
iler.</div><div><br><br></div></div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr">On Thu, 31 May 2018 at 09:30, Magnus Fromreide &lt;<a href=3D"java=
script:" target=3D"_blank" gdf-obfuscated-mailto=3D"V-GkaVMiAAAJ" rel=3D"no=
follow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" oncl=
ick=3D"this.href=3D&#39;javascript:&#39;;return true;">ma...@lysator.liu.se=
</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, May 30, 201=
8 at 09:03:14PM -0700, Thiago Macieira wrote:<br>
&gt; On Wednesday, 30 May 2018 14:21:09 PDT <a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"V-GkaVMiAAAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">inkwizyt...@gmail.com</a> wrote:<br=
>
&gt; &gt; int bar(int a, int b) tailcall //new contextual keyword<br>
&gt; <br>
&gt; We could do that.<br>
&gt; <br>
&gt; Why should we? I haven&#39;t heard a good, compelling argument for why=
 we should <br>
&gt; go through the trouble. The only thing that a tail-call optimisation h=
elps is <br>
&gt; reduce resource consumption (stack), something that isn&#39;t in the s=
tandard in <br>
&gt; the first place.<br>
<br>
In standardeese I suppose this would create a subclass of function calls th=
at<br>
won&#39;t contribute to the minimum call stack depth implementation limit.<=
br>
<br>
&gt; Other than that, there&#39;s no observable behaviour.<br>
&gt; <br>
&gt; What algorithms would benefit from this?<br>
<br>
Any tail recursive algorithm.<br>
<br>
&gt; Is there anything that could be implemented using it that cannot be to=
day?<br>
<br>
No, since it, IIRC from my CS days, is proven that any tail recursive<br>
algorithm can be converted to a loop.<br>
<br>
No, I do not think this is worth the standardization effort.<br>
<br>
/MF<br>
<br>
-- <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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
V-GkaVMiAAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&=
#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"V-GkaVMiAAAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">std-pr...@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/20180531073015.GA18526%40noemi.bahnho=
f.se" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;ht=
tps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20180531073015.G=
A18526%40noemi.bahnhof.se&#39;;return true;" onclick=3D"this.href=3D&#39;ht=
tps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20180531073015.G=
A18526%40noemi.bahnhof.se&#39;;return true;">https://groups.google.com/a/<w=
br>isocpp.org/d/msgid/std-<wbr>proposals/20180531073015.<wbr>GA18526%40noem=
i.bahnhof.se</a>.<br></blockquote></div></blockquote><div><br></div><div>I =
do not see tail-call as optimization but as control structure, probably bes=
t place where I could use it is state machine.</div><div>Consider this code=
:</div><div><div style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wra=
p: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s=
tate_a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">input</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify"></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> tailcall<br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">if</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">i=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><c=
ode class=3D"prettyprint"><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">next</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y"></span></code><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: #660;" class=3D"styled-by-prettify">=3D=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">5</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #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"styled-by-prettify">return</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> state_b</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">i</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">else</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </sp=
an><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 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> state_c</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">i</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> //what do state `c`? it could be loaded from=
 dll but it will still work fine<br>=C2=A0 </span><span style=3D"color: #66=
0;" 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"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> state_b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">input</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify"></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> tailcall<br></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">if</span><span 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=
">i</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">next</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=
: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" clas=
s=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">return</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> state_a</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">i</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">else</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br>=C2=A0 </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"styled-by-prettify">return</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> state_end</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">i</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">}</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></span></div=
></code></div>Couple observation:</div><div>You can implement this as switc=
h but how big it will be? and how easy to expand. I would consider this as =
syntax sugar.</div><div><br></div><div>You can&#39;t determine stack size b=
ecause you do not control `input`, there is no implementation that handle t=
his, even more if it could then you could use whole memory if someone try D=
DoS you and it will afect other processes. With tail-call resources usage i=
s deterministic and have cap independent of inputs. And it can work indefin=
ite.<br></div><div><br></div><div>Rule could be simple, signature need be s=
ame and parameters should be copyable/movable (or references but then you a=
re forbidden to pass local variables or temporals to it).</div><div><br></d=
iv><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/17e39178-4555-44ce-bb2e-91b3e626513a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/17e39178-4555-44ce-bb2e-91b3e626513a=
%40isocpp.org</a>.<br />

------=_Part_3497_331153687.1527765542229--

------=_Part_3496_194883499.1527765542228--

.


Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Thu, 31 May 2018 05:26:48 -0700 (PDT)
Raw View
------=_Part_3831_1829951327.1527769608360
Content-Type: multipart/alternative;
 boundary="----=_Part_3832_441272554.1527769608360"

------=_Part_3832_441272554.1527769608360
Content-Type: text/plain; charset="UTF-8"

Tail call optimization, as an optimization, is mostly not worth being
standardized in a general-purposed language. The possibly needed feature
here is the guarantees of proper tail calls in several tail contexts.

Though the differences are often ignored by many users, they are actually
quite significant, and vital for purpose of specification. See
https://stackoverflow.com/questions/12045299/what-is-difference-between-tail-calls-and-tail-recursion
for more details. Reading thoroughly of Clinger's paper will be a good
start. See also
https://groups.google.com/d/msg/comp.lang.lisp/AezzhxTliME/2Zsq7HUn_ssJ.

--
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/461d68f4-ea1c-4f30-b800-66f92232424d%40isocpp.org.

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

<div dir=3D"ltr">Tail call optimization, as an optimization, is mostly not =
worth being standardized in a general-purposed language. The possibly neede=
d feature here is the guarantees of proper tail calls in several tail conte=
xts.<br><br>Though the differences are often ignored by many users, they ar=
e actually quite significant, and vital for purpose of specification. See h=
ttps://stackoverflow.com/questions/12045299/what-is-difference-between-tail=
-calls-and-tail-recursion for more details. Reading thoroughly of Clinger&#=
39;s paper will be a good start. See also https://groups.google.com/d/msg/c=
omp.lang.lisp/AezzhxTliME/2Zsq7HUn_ssJ.<br><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/461d68f4-ea1c-4f30-b800-66f92232424d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/461d68f4-ea1c-4f30-b800-66f92232424d=
%40isocpp.org</a>.<br />

------=_Part_3832_441272554.1527769608360--

------=_Part_3831_1829951327.1527769608360--

.


Author: =?UTF-8?B?R2HFoXBlciBBxb5tYW4=?= <gasper.azman@gmail.com>
Date: Thu, 31 May 2018 13:45:01 +0100
Raw View
--000000000000306582056d7fd7b6
Content-Type: text/plain; charset="UTF-8"

I also agree that we need a flavor of "return" that basically says "return
the result of this continuation, but before you run that, end my frame"
effectively.

There are a lot of really cool things that enables, state machines being
one and the core coroutines paper the second. There are doubtlessly more
uses for this feature.

What it must not be confused with is "optimization" - this is not an
optimization, it's a longjump with pre-cleanup, which is fundamentally
different from an optimization, since when you need it for correctness, you
really need it.

In http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1063r0.pdf , tail
return is needed for correctness, and they outline some of what it takes to
make it work. I think a properly designed feature like tail return would be
welcome for a number of uses.

G

On Thu, May 31, 2018 at 1:26 PM, FrankHB1989 <frankhb1989@gmail.com> wrote:

> Tail call optimization, as an optimization, is mostly not worth being
> standardized in a general-purposed language. The possibly needed feature
> here is the guarantees of proper tail calls in several tail contexts.
>
> Though the differences are often ignored by many users, they are actually
> quite significant, and vital for purpose of specification. See
> https://stackoverflow.com/questions/12045299/what-is-
> difference-between-tail-calls-and-tail-recursion for more details.
> Reading thoroughly of Clinger's paper will be a good start. See also
> https://groups.google.com/d/msg/comp.lang.lisp/AezzhxTliME/2Zsq7HUn_ssJ.
>
> --
> 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/461d68f4-ea1c-4f30-
> b800-66f92232424d%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/461d68f4-ea1c-4f30-b800-66f92232424d%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CAANG%3DkUQcybLwh4dyfqBApdV%3D9nAT2tho%2Bb9J9E2z_dgPS%3DhxA%40mail.gmail.com.

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

<div dir=3D"ltr">I also agree that we need a flavor of &quot;return&quot; t=
hat basically says &quot;return the result of this continuation, but before=
 you run that, end my frame&quot; effectively.<div><br></div><div>There are=
 a lot of really cool things that enables, state machines being one and the=
 core coroutines paper the second. There are doubtlessly more uses for this=
 feature.</div><div><br></div><div>What it must not be confused with is &qu=
ot;optimization&quot; - this is not an optimization, it&#39;s a longjump wi=
th pre-cleanup, which is fundamentally different from an optimization, sinc=
e when you need it for correctness, you really need it.</div><div><br></div=
><div>In=C2=A0<a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/papers/201=
8/p1063r0.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1063r0.=
pdf</a> , tail return is needed for correctness, and they outline some of w=
hat it takes to make it work. I think a properly designed feature like tail=
 return would be welcome for a number of uses.</div><div><br></div><div>G</=
div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Thu,=
 May 31, 2018 at 1:26 PM, FrankHB1989 <span dir=3D"ltr">&lt;<a href=3D"mail=
to:frankhb1989@gmail.com" target=3D"_blank">frankhb1989@gmail.com</a>&gt;</=
span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Tail call o=
ptimization, as an optimization, is mostly not worth being standardized in =
a general-purposed language. The possibly needed feature here is the guaran=
tees of proper tail calls in several tail contexts.<br><br>Though the diffe=
rences are often ignored by many users, they are actually quite significant=
, and vital for purpose of specification. See <a href=3D"https://stackoverf=
low.com/questions/12045299/what-is-difference-between-tail-calls-and-tail-r=
ecursion" target=3D"_blank">https://stackoverflow.com/<wbr>questions/120452=
99/what-is-<wbr>difference-between-tail-calls-<wbr>and-tail-recursion</a> f=
or more details. Reading thoroughly of Clinger&#39;s paper will be a good s=
tart. See also <a href=3D"https://groups.google.com/d/msg/comp.lang.lisp/Ae=
zzhxTliME/2Zsq7HUn_ssJ" target=3D"_blank">https://groups.google.com/d/<wbr>=
msg/comp.lang.lisp/<wbr>AezzhxTliME/2Zsq7HUn_ssJ</a>.<br><br></div><span cl=
ass=3D"">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/461d68f4-ea1c-4f30-b800-66f92232424d%=
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/461d=
68f4-ea1c-4f30-<wbr>b800-66f92232424d%40isocpp.org</a><wbr>.<br>
</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%3DkUQcybLwh4dyfqBApdV%3D9nAT2th=
o%2Bb9J9E2z_dgPS%3DhxA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3Dk=
UQcybLwh4dyfqBApdV%3D9nAT2tho%2Bb9J9E2z_dgPS%3DhxA%40mail.gmail.com</a>.<br=
 />

--000000000000306582056d7fd7b6--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 31 May 2018 07:02:21 -0700
Raw View
On Thursday, 31 May 2018 05:45:01 PDT Ga=C5=A1per A=C5=BEman wrote:
> What it must not be confused with is "optimization" - this is not an
> optimization, it's a longjump with pre-cleanup, which is fundamentally
> different from an optimization, since when you need it for correctness, y=
ou
> really need it.

You can fix that by using a big lambda that returns the function to be call=
ed=20
by the outer code.

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



--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3805629.hqpMWECrGy%40tjmaciei-mobl1.

.


Author: =?UTF-8?B?R2HFoXBlciBBxb5tYW4=?= <gasper.azman@gmail.com>
Date: Thu, 31 May 2018 15:06:30 +0100
Raw View
--000000000000965fd7056d80faf4
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Thu, May 31, 2018 at 3:02 PM, Thiago Macieira <thiago@macieira.org>
wrote:

> On Thursday, 31 May 2018 05:45:01 PDT Ga=C5=A1per A=C5=BEman wrote:
> > What it must not be confused with is "optimization" - this is not an
> > optimization, it's a longjump with pre-cleanup, which is fundamentally
> > different from an optimization, since when you need it for correctness,
> you
> > really need it.
>
> You can fix that by using a big lambda that returns the function to be
> called
> by the outer code.


And that's how we've been doing it - but it sucks to require a framework
for something that doesn't *technically* require a framework.

I'd be very happy with

tail return LAMBDA EXPRESSION;

That would mean the language would guarantee the expression to be evaluated
immediately, without requiring the calling code to implement the "call
until the return isn't a lambda".

Actually I don't know how to do this unless the function always returns a
variant<std::function<T()>, T>, which necessitates some ugly wrappers.

G

--=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%3DkUCs%2Bygd2%3DwAvTRmvzvAXGM-c0UWvc%3D-bL=
LYoOYrVmnBg%40mail.gmail.com.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Thu, May 31, 2018 at 3:02 PM, Thiago Macieira <span dir=3D"ltr">&lt;=
<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.or=
g</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">=
On Thursday, 31 May 2018 05:45:01 PDT Ga=C5=A1per A=C5=BEman wrote:<br>
&gt; What it must not be confused with is &quot;optimization&quot; - this i=
s not an<br>
&gt; optimization, it&#39;s a longjump with pre-cleanup, which is fundament=
ally<br>
&gt; different from an optimization, since when you need it for correctness=
, you<br>
&gt; really need it.<br>
<br>
</span>You can fix that by using a big lambda that returns the function to =
be called <br>
by the outer code.</blockquote><div><br></div><div>And that&#39;s how we&#3=
9;ve been doing it - but it sucks to require a framework for something that=
 doesn&#39;t *technically* require a framework.</div><div><br></div><div>I&=
#39;d be very happy with</div><div><br></div><div>tail return LAMBDA EXPRES=
SION;</div><div><br></div><div>That would mean the language would guarantee=
 the expression to be evaluated immediately, without requiring the calling =
code to implement the &quot;call until the return isn&#39;t a lambda&quot;.=
</div><div><br></div><div>Actually I don&#39;t know how to do this unless t=
he function always returns a variant&lt;std::function&lt;T()&gt;, T&gt;, wh=
ich necessitates some ugly wrappers.</div><div><br></div><div>G</div><div><=
br></div><div><br></div><div><br></div><div><br></div><div>=C2=A0</div></di=
v></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/CAANG%3DkUCs%2Bygd2%3DwAvTRmvzvAXGM-c=
0UWvc%3D-bLLYoOYrVmnBg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3Dk=
UCs%2Bygd2%3DwAvTRmvzvAXGM-c0UWvc%3D-bLLYoOYrVmnBg%40mail.gmail.com</a>.<br=
 />

--000000000000965fd7056d80faf4--

.


Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Thu, 31 May 2018 14:41:06 -0700 (PDT)
Raw View
------=_Part_6576_410095130.1527802866133
Content-Type: multipart/alternative;
 boundary="----=_Part_6577_662978095.1527802866133"

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



=E5=9C=A8 2018=E5=B9=B45=E6=9C=8831=E6=97=A5=E6=98=9F=E6=9C=9F=E5=9B=9B UTC=
+8=E4=B8=8B=E5=8D=8810:02:26=EF=BC=8CThiago Macieira=E5=86=99=E9=81=93=EF=
=BC=9A
>
> On Thursday, 31 May 2018 05:45:01 PDT Ga=C5=A1per A=C5=BEman wrote:=20
> > What it must not be confused with is "optimization" - this is not an=20
> > optimization, it's a longjump with pre-cleanup, which is fundamentally=
=20
> > different from an optimization, since when you need it for correctness,=
=20
> you=20
> > really need it.=20
>
> You can fix that by using a big lambda that returns the function to be=20
> called=20
> by the outer code.=20
>
> I'm actually not fond of tail call designated by some explicit keywords (=
*syntactic=20
tail calls* in ECMA TC39 words) and any strict subset of the feature to be=
=20
added specifically into the language, but workaround by wrapping a lambda=
=20
seems already defeated the purpose more than that. It is like saying "we do=
=20
not need coroutines at all since we can write state machines." It also=20
interferes the stability of type signatures for API in user code.
=20

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

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/15f7b59d-3322-4186-ab30-f2944442bba9%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>=E5=9C=A8 2018=E5=B9=B45=E6=9C=8831=E6=97=A5=E6=98=
=9F=E6=9C=9F=E5=9B=9B UTC+8=E4=B8=8B=E5=8D=8810:02:26=EF=BC=8CThiago Maciei=
ra=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">O=
n Thursday, 31 May 2018 05:45:01 PDT Ga=C5=A1per A=C5=BEman wrote:
<br>&gt; What it must not be confused with is &quot;optimization&quot; - th=
is is not an
<br>&gt; optimization, it&#39;s a longjump with pre-cleanup, which is funda=
mentally
<br>&gt; different from an optimization, since when you need it for correct=
ness, you
<br>&gt; really need it.
<br>
<br>You can fix that by using a big lambda that returns the function to be =
called=20
<br>by the outer code.
<br>
<br></blockquote><div>I&#39;m actually not fond of tail call designated by =
some explicit keywords (<i>syntactic tail calls</i> in ECMA TC39 words) and=
 any strict subset of the feature to be added specifically into the languag=
e, but workaround by wrapping a lambda seems already defeated the purpose m=
ore than that. It is like saying &quot;we do not need coroutines at all sin=
ce we can write state machines.&quot; It also interferes the stability of t=
ype signatures for API in user code.<br>=C2=A0<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.goo=
gle.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return t=
rue;">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH=
GRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;">kde.org</a=
>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br>
<br>
<br></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/15f7b59d-3322-4186-ab30-f2944442bba9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/15f7b59d-3322-4186-ab30-f2944442bba9=
%40isocpp.org</a>.<br />

------=_Part_6577_662978095.1527802866133--

------=_Part_6576_410095130.1527802866133--

.


Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Thu, 31 May 2018 15:20:41 -0700 (PDT)
Raw View
------=_Part_6801_1426938400.1527805241652
Content-Type: multipart/alternative;
 boundary="----=_Part_6802_575407983.1527805241652"

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



=E5=9C=A8 2018=E5=B9=B45=E6=9C=8830=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC=
+8=E4=B8=8A=E5=8D=889:49:20=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Tuesday, May 29, 2018 at 6:03:05 PM UTC-4, Antonio Perez wrote:
>>
>> I appreciate your feedback. This proposal is based on a rather=20
>> uncontroversial idea: If it's semantically and syntactically valid, a=20
>> program should work when compiled without optimizations enabled (emphasi=
s=20
>> on "semantically valid").
>>
>
> I would find that idea rather controversial, since the distinction betwee=
n=20
> "work" and "not-work" is a matter of resource exhaustion, which is not a=
=20
> standard-defined thing. Also, the standard doesn't recognize the=20
> distinction between "optimized" and "not optimized"; the standard is the=
=20
> standard.
>
> The optimization is surely not fit for mandatory, but there can be=20
alternatives in terms of PTC (proper tail calls). The formal definition (if=
=20
any) would be based on rules about asymptotic computational complexity=20
during evaluation of expressions, in forms which has already been used by=
=20
the library clause for years. Or simply requirements of capability of=20
unbound number of active calls in tail contexts (not so formal, but still=
=20
normative). Once it is required, there is nothing "not optimized" else than=
=20
nonconformance.
=20

> Having written a few programs in semi-resource-constrained environments,=
=20
> there was rarely any expectation that the project would run with no=20
> optimizations enabled. And it wasn't for lack of tail recursion; there we=
re=20
> plenty of other things that drew on those constrained resources.
>
> I don't believe proper tail calls will do much to change things for such=
=20
> people.
>
> Mostly true, but I'm afraid this is not the purpose. PTC is mainly used t=
o=20
avoid the cases that you have reasonably "enough" space resources but you=
=20
still run out of them too easily just because you don't know how many calls=
=20
are supported at runtime (which cannot be predicated in a portable way) -=
=20
yeah, it is sometimes called as *memory leak*. It is better to avoid them=
=20
by default, when there is no significant cost at least.
=20

> Guaranteed elision wasn't added because it freed up developers from=20
> relying on an optimization. It was added because it allowed people to do=
=20
> things that otherwise wouldn't work, like return immobile objects.
>

> Proper tail calls need some motivation like that, where it gives you an=
=20
> ability that would be otherwise impossible.
>
> PTC does essentially quite the same. As the status quo, TCO (tail call=20
optimization) is optional, allowed by as-if rules. It is unspecified that=
=20
the program will be optimized or not. The guarantee allows people to assume=
=20
some basic safety properties without knowledge of implementation details.=
=20
(And I suspect it is a fundamental hole if no other guarantee in the=20
abstract machine semantics allows you do that since arbitrary call would be=
=20
threaten by undefined behavior.) The only difference is that elision=20
interferes observable behavior, so as-if rules are already not sufficient.
=20

> Tail call optimization is different from other types of optimization in=
=20
>> that the functionality of programs is fundamentally affected if tail cal=
l=20
>> optimization doesn't occur. Programmers expect unoptimized programs to r=
un=20
>> slower, and to use a bit more memory, but they accept the tradeoff becau=
se=20
>> the lack of optimization doesn't break valid programs. In this case, it=
=20
>> does break valid programs.=20
>>
>> Standardizing tail call optimization provides programmers with greater=
=20
>> certainty that their code will work, and that it'll be portable. It's no=
t=20
>> just about recursion, either: programmers working on embedded systems of=
ten=20
>> have limited stack space, and the standardization of this optimization w=
ill=20
>> allow them to better design their code to fit the tight memory requireme=
nts=20
>> (for example, by putting calls to memory hungry routines at the end of a=
=20
>> function).
>>
>
> Such programmers already have to carefully plan their compiler options to=
=20
> fit within their environment. So this really would change very little for=
=20
> them.
> =20
>
>>
>> Aside from that, there are many ideas that are best expressed through th=
e=20
>> use of recursion. Making recursion safe to use will make it easier to wr=
ite=20
>> clean and maintainable code.
>>
>
> Recursion already is safe to use. And I hope that you aren't limiting you=
r=20
> thinking on proper tail calls to just recursion.=20
>
I'm afraid that *any *nested calls are not assumed to be safe within C++.=
=20
See above.
=20

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/6e1efc6e-fb73-4b72-b827-5f4cdfd82680%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>=E5=9C=A8 2018=E5=B9=B45=E6=9C=8830=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8A=E5=8D=889:49:20=EF=BC=8CNicol Bolas=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Tuesday, May 29, 2018 at 6:03:05 PM UTC-4, Antonio Perez wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>I appreciat=
e your feedback. This proposal is based on a rather uncontroversial idea: I=
f it&#39;s semantically and syntactically valid, a program should work when=
 compiled without optimizations enabled (emphasis on &quot;semantically val=
id&quot;).</div></div></blockquote><div><br></div><div>I would find that id=
ea rather controversial, since the distinction between &quot;work&quot; and=
 &quot;not-work&quot; is a matter of resource exhaustion, which is not a st=
andard-defined thing. Also, the standard doesn&#39;t recognize the distinct=
ion between &quot;optimized&quot; and &quot;not optimized&quot;; the standa=
rd is the standard.<br></div><div><br></div></div></blockquote><div>The opt=
imization is surely not fit for mandatory, but there can be alternatives in=
 terms of PTC (proper tail calls). The formal definition (if any) would be =
based on rules about asymptotic computational complexity during evaluation =
of expressions, in forms which has already been used by the library clause =
for years. Or simply requirements of capability of unbound number of active=
 calls in tail contexts (not so formal, but still normative). Once it is re=
quired, there is nothing &quot;not optimized&quot; else than nonconformance=
..<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div></div><div>Having written a few programs in semi-resource-con=
strained environments, there was rarely any expectation that the project wo=
uld run with no optimizations enabled. And it wasn&#39;t for lack of tail r=
ecursion; there were plenty of other things that drew on those constrained =
resources.</div><div><br></div><div>I don&#39;t believe proper tail calls w=
ill do much to change things for such people.</div><div><br></div></div></b=
lockquote><div>Mostly true, but I&#39;m afraid this is not the purpose. PTC=
 is mainly used to avoid the cases that you have reasonably &quot;enough&qu=
ot; space resources but you still run out of them too easily just because y=
ou don&#39;t know how many calls are supported at runtime (which cannot be =
predicated in a portable way) - yeah, it is sometimes called as <i>memory l=
eak</i>. It is better to avoid them by default, when there is no significan=
t cost at least.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div></div><div>Guaranteed elision wasn&#39;t added =
because it freed up developers from relying on an optimization. It was adde=
d because it allowed people to do things that otherwise wouldn&#39;t work, =
like return immobile objects.</div></div></blockquote><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>Proper tail ca=
lls need some motivation like that, where it gives you an ability that woul=
d be otherwise impossible.<br></div><div><br></div></div></blockquote><div>=
PTC does essentially quite the same. As the status quo, TCO (tail call=20
optimization) is optional, allowed by as-if rules. It is unspecified=20
that the program will be optimized or not. The guarantee allows people=20
to assume some basic safety properties without knowledge of=20
implementation details. (And I suspect it is a fundamental hole if no=20
other guarantee in the abstract machine semantics allows you do that=20
since arbitrary call would be threaten by undefined behavior.) The only=20
difference is that elision interferes observable behavior, so as-if=20
rules are already not sufficient.<br>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div>Tail call optimization is different from =
other types of optimization in that the functionality of programs is fundam=
entally affected if tail call optimization doesn&#39;t occur. Programmers e=
xpect unoptimized programs to run slower, and to use a bit more memory, but=
 they accept the tradeoff because the lack of optimization doesn&#39;t brea=
k valid programs. In this case, it does break valid programs.=C2=A0</div><d=
iv><br></div><div>Standardizing tail call optimization provides programmers=
 with greater certainty that their code will work, and that it&#39;ll be po=
rtable. It&#39;s not just about recursion, either: programmers working on e=
mbedded systems often have limited stack space, and the standardization of =
this optimization will allow them to better design their code to fit the ti=
ght memory requirements (for example, by putting calls to memory hungry rou=
tines at the end of a function).</div></div></blockquote><div><br></div><di=
v>Such programmers already have to carefully plan their compiler options to=
 fit within their environment. So this really would change very little for =
them.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div><br></div><div>Aside from that, there are many ideas tha=
t are best expressed through the use of recursion. Making recursion safe to=
 use will make it easier to write clean and maintainable code.</div></div><=
/blockquote><div><br></div><div>Recursion already is safe to use. And I hop=
e that you aren&#39;t limiting your thinking on proper tail calls to just r=
ecursion. <br></div></div></blockquote><div>I&#39;m afraid that <i>any </i>=
nested calls are not assumed to be safe within C++. See above.<br>=C2=A0<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/6e1efc6e-fb73-4b72-b827-5f4cdfd82680%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6e1efc6e-fb73-4b72-b827-5f4cdfd82680=
%40isocpp.org</a>.<br />

------=_Part_6802_575407983.1527805241652--

------=_Part_6801_1426938400.1527805241652--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 31 May 2018 17:11:50 -0700 (PDT)
Raw View
------=_Part_7205_392899774.1527811910141
Content-Type: multipart/alternative;
 boundary="----=_Part_7206_1527445467.1527811910142"

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

On Thursday, May 31, 2018 at 6:20:41 PM UTC-4, FrankHB1989 wrote:
>
> =E5=9C=A8 2018=E5=B9=B45=E6=9C=8830=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 U=
TC+8=E4=B8=8A=E5=8D=889:49:20=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>
>> On Tuesday, May 29, 2018 at 6:03:05 PM UTC-4, Antonio Perez wrote:
>>>
>>> I appreciate your feedback. This proposal is based on a rather=20
>>> uncontroversial idea: If it's semantically and syntactically valid, a=
=20
>>> program should work when compiled without optimizations enabled (emphas=
is=20
>>> on "semantically valid").
>>>
>>
>> I would find that idea rather controversial, since the distinction=20
>> between "work" and "not-work" is a matter of resource exhaustion, which =
is=20
>> not a standard-defined thing. Also, the standard doesn't recognize the=
=20
>> distinction between "optimized" and "not optimized"; the standard is the=
=20
>> standard.
>>
>> The optimization is surely not fit for mandatory, but there can be=20
> alternatives in terms of PTC (proper tail calls). The formal definition (=
if=20
> any) would be based on rules about asymptotic computational complexity=20
> during evaluation of expressions, in forms which has already been used by=
=20
> the library clause for years. Or simply requirements of capability of=20
> unbound number of active calls in tail contexts (not so formal, but still=
=20
> normative). Once it is required, there is nothing "not optimized" else th=
an=20
> nonconformance.
>

If proper tail calls are going to be part of the language, then it=20
shouldn't be an "optimization". Why? Because making it an actual feature=20
allows us to do C++-specific things.

For example, the way the OP defined it, it is impossible to have a tail=20
call in a function with non-trivially-destructible types. The C++ model of=
=20
calling functions and returning their results requires that local variables=
=20
be destroyed only *after* the function call returns. If tail calls are an=
=20
"optimization", we can't change that rule willy-nilly. So users have to=20
know a priori that they can't use local variables of other types.

By contrast,if we make it an actual feature through some syntax, then=20
there's no need for such a limitation. We can explicitly say that local=20
variables are destroyed after the tail function's parameters are=20
initialized, but before the tail function is called. Or whatever; there are=
=20
ways to work it out. This kind of thing would make proper tail calls useful=
=20
in many more contexts.

Having written a few programs in semi-resource-constrained environments,=20
>> there was rarely any expectation that the project would run with no=20
>> optimizations enabled. And it wasn't for lack of tail recursion; there w=
ere=20
>> plenty of other things that drew on those constrained resources.
>>
>> I don't believe proper tail calls will do much to change things for such=
=20
>> people.
>>
>> Mostly true, but I'm afraid this is not the purpose.
>

Well, the OP seems to differ, since this was one of their main motivations.

PTC is mainly used to avoid the cases that you have reasonably "enough"=20
> space resources but you still run out of them too easily just because you=
=20
> don't know how many calls are supported at runtime (which cannot be=20
> predicated in a portable way) - yeah, it is sometimes called as *memory=
=20
> leak*. It is better to avoid them by default, when there is no=20
> significant cost at least.
> =20
>
>> Guaranteed elision wasn't added because it freed up developers from=20
>> relying on an optimization. It was added because it allowed people to do=
=20
>> things that otherwise wouldn't work, like return immobile objects.
>>
>
>> Proper tail calls need some motivation like that, where it gives you an=
=20
>> ability that would be otherwise impossible.
>>
>> PTC does essentially quite the same. As the status quo, TCO (tail call=
=20
> optimization) is optional, allowed by as-if rules. It is unspecified that=
=20
> the program will be optimized or not. The guarantee allows people to assu=
me=20
> some basic safety properties without knowledge of implementation details.=
=20
> (And I suspect it is a fundamental hole if no other guarantee in the=20
> abstract machine semantics allows you do that since arbitrary call would =
be=20
> threaten by undefined behavior.) The only difference is that elision=20
> interferes observable behavior, so as-if rules are already not sufficient=
..
>

And that "only difference" is what makes *all the difference*: the standard=
=20
defines observable behavior. Proper tail calls are not observable behavior=
=20
by the abstract model the standard defines, and therefore it cannot define=
=20
them.

Tail call optimization is different from other types of optimization in=20
>>> that the functionality of programs is fundamentally affected if tail ca=
ll=20
>>> optimization doesn't occur. Programmers expect unoptimized programs to =
run=20
>>> slower, and to use a bit more memory, but they accept the tradeoff beca=
use=20
>>> the lack of optimization doesn't break valid programs. In this case, it=
=20
>>> does break valid programs.=20
>>>
>>> Standardizing tail call optimization provides programmers with greater=
=20
>>> certainty that their code will work, and that it'll be portable. It's n=
ot=20
>>> just about recursion, either: programmers working on embedded systems o=
ften=20
>>> have limited stack space, and the standardization of this optimization =
will=20
>>> allow them to better design their code to fit the tight memory requirem=
ents=20
>>> (for example, by putting calls to memory hungry routines at the end of =
a=20
>>> function).
>>>
>>
>> Such programmers already have to carefully plan their compiler options t=
o=20
>> fit within their environment. So this really would change very little fo=
r=20
>> them.
>> =20
>>
>>>
>>> Aside from that, there are many ideas that are best expressed through=
=20
>>> the use of recursion. Making recursion safe to use will make it easier =
to=20
>>> write clean and maintainable code.
>>>
>>
>> Recursion already is safe to use. And I hope that you aren't limiting=20
>> your thinking on proper tail calls to just recursion.=20
>>
> I'm afraid that *any *nested calls are not assumed to be safe within C++.=
=20
> See above.
>

And yet, we do it *all the time*. That seems safe enough to me.

--=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/9e0b2e6e-909c-455b-8a39-f173a6d0d2bc%40isocpp.or=
g.

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

<div dir=3D"ltr">On Thursday, May 31, 2018 at 6:20:41 PM UTC-4, FrankHB1989=
 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">=E5=9C=
=A8 2018=E5=B9=B45=E6=9C=8830=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=
=B8=8A=E5=8D=889:49:20=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, May 29, 2018=
 at 6:03:05 PM UTC-4, Antonio Perez wrote:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div>I appreciate your feedback. This proposal is b=
ased on a rather uncontroversial idea: If it&#39;s semantically and syntact=
ically valid, a program should work when compiled without optimizations ena=
bled (emphasis on &quot;semantically valid&quot;).</div></div></blockquote>=
<div><br></div><div>I would find that idea rather controversial, since the =
distinction between &quot;work&quot; and &quot;not-work&quot; is a matter o=
f resource exhaustion, which is not a standard-defined thing. Also, the sta=
ndard doesn&#39;t recognize the distinction between &quot;optimized&quot; a=
nd &quot;not optimized&quot;; the standard is the standard.<br></div><div><=
br></div></div></blockquote><div>The optimization is surely not fit for man=
datory, but there can be alternatives in terms of PTC (proper tail calls). =
The formal definition (if any) would be based on rules about asymptotic com=
putational complexity during evaluation of expressions, in forms which has =
already been used by the library clause for years. Or simply requirements o=
f capability of unbound number of active calls in tail contexts (not so for=
mal, but still normative). Once it is required, there is nothing &quot;not =
optimized&quot; else than nonconformance.<br></div></div></blockquote><div>=
<br></div><div>If proper tail calls are going to be part of the language, t=
hen it shouldn&#39;t be an &quot;optimization&quot;. Why? Because making it=
 an actual feature allows us to do C++-specific things.</div><div><br></div=
><div>For example, the way the OP defined it, it is impossible to have a ta=
il call in a function with non-trivially-destructible types. The C++ model =
of calling functions and returning their results requires that local variab=
les be destroyed only <i>after</i> the function call returns. If tail calls=
 are an &quot;optimization&quot;, we can&#39;t change that rule willy-nilly=
.. So users have to know a priori that they can&#39;t use local variables of=
 other types.</div><div><br></div><div>By contrast,if we make it an actual =
feature through some syntax, then there&#39;s no need for such a limitation=
.. We can explicitly say that local variables are destroyed after the tail f=
unction&#39;s parameters are initialized, but before the tail function is c=
alled. Or whatever; there are ways to work it out. This kind of thing would=
 make proper tail calls useful in many more contexts.</div><div><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>Havin=
g written a few programs in semi-resource-constrained environments, there w=
as rarely any expectation that the project would run with no optimizations =
enabled. And it wasn&#39;t for lack of tail recursion; there were plenty of=
 other things that drew on those constrained resources.</div><div><br></div=
><div>I don&#39;t believe proper tail calls will do much to change things f=
or such people.</div><div><br></div></div></blockquote><div>Mostly true, bu=
t I&#39;m afraid this is not the purpose.</div></div></blockquote><div><br>=
</div><div>Well, the OP seems to differ, since this was one of their main m=
otivations.<br></div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div>PTC is mainly used to avoid the cases that you =
have reasonably &quot;enough&quot; space resources but you still run out of=
 them too easily just because you don&#39;t know how many calls are support=
ed at runtime (which cannot be predicated in a portable way) - yeah, it is =
sometimes called as <i>memory leak</i>. It is better to avoid them by defau=
lt, when there is no significant cost at least.<br>=C2=A0<br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>Guaranteed=
 elision wasn&#39;t added because it freed up developers from relying on an=
 optimization. It was added because it allowed people to do things that oth=
erwise wouldn&#39;t work, like return immobile objects.</div></div></blockq=
uote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></di=
v><div>Proper tail calls need some motivation like that, where it gives you=
 an ability that would be otherwise impossible.<br></div><div><br></div></d=
iv></blockquote><div>PTC does essentially quite the same. As the status quo=
, TCO (tail call=20
optimization) is optional, allowed by as-if rules. It is unspecified=20
that the program will be optimized or not. The guarantee allows people=20
to assume some basic safety properties without knowledge of=20
implementation details. (And I suspect it is a fundamental hole if no=20
other guarantee in the abstract machine semantics allows you do that=20
since arbitrary call would be threaten by undefined behavior.) The only=20
difference is that elision interferes observable behavior, so as-if=20
rules are already not sufficient.<br></div></div></blockquote><div><br></di=
v><div>And that &quot;only difference&quot; is what makes <i>all the differ=
ence</i>: the standard defines observable behavior. Proper tail calls are n=
ot observable behavior by the abstract model the standard defines, and ther=
efore it cannot define them.</div><div><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div>Tail call optimization is different from other t=
ypes of optimization in that the functionality of programs is fundamentally=
 affected if tail call optimization doesn&#39;t occur. Programmers expect u=
noptimized programs to run slower, and to use a bit more memory, but they a=
ccept the tradeoff because the lack of optimization doesn&#39;t break valid=
 programs. In this case, it does break valid programs.=C2=A0</div><div><br>=
</div><div>Standardizing tail call optimization provides programmers with g=
reater certainty that their code will work, and that it&#39;ll be portable.=
 It&#39;s not just about recursion, either: programmers working on embedded=
 systems often have limited stack space, and the standardization of this op=
timization will allow them to better design their code to fit the tight mem=
ory requirements (for example, by putting calls to memory hungry routines a=
t the end of a function).</div></div></blockquote><div><br></div><div>Such =
programmers already have to carefully plan their compiler options to fit wi=
thin their environment. So this really would change very little for them.<b=
r></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><br></div><div>Aside from that, there are many ideas that are=
 best expressed through the use of recursion. Making recursion safe to use =
will make it easier to write clean and maintainable code.</div></div></bloc=
kquote><div><br></div><div>Recursion already is safe to use. And I hope tha=
t you aren&#39;t limiting your thinking on proper tail calls to just recurs=
ion. <br></div></div></blockquote><div>I&#39;m afraid that <i>any </i>neste=
d calls are not assumed to be safe within C++. See above.<br></div></div></=
blockquote><div><br></div><div>And yet, we do it <i>all the time</i>. That =
seems safe enough to me.<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/9e0b2e6e-909c-455b-8a39-f173a6d0d2bc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9e0b2e6e-909c-455b-8a39-f173a6d0d2bc=
%40isocpp.org</a>.<br />

------=_Part_7206_1527445467.1527811910142--

------=_Part_7205_392899774.1527811910141--

.


Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Thu, 31 May 2018 19:47:57 -0700 (PDT)
Raw View
------=_Part_7881_1207079971.1527821277823
Content-Type: multipart/alternative;
 boundary="----=_Part_7882_992887838.1527821277823"

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



=E5=9C=A8 2018=E5=B9=B46=E6=9C=881=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 UTC+=
8=E4=B8=8A=E5=8D=888:11:50=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Thursday, May 31, 2018 at 6:20:41 PM UTC-4, FrankHB1989 wrote:
>>
>> =E5=9C=A8 2018=E5=B9=B45=E6=9C=8830=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 =
UTC+8=E4=B8=8A=E5=8D=889:49:20=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>>
>>> On Tuesday, May 29, 2018 at 6:03:05 PM UTC-4, Antonio Perez wrote:
>>>>
>>>> I appreciate your feedback. This proposal is based on a rather=20
>>>> uncontroversial idea: If it's semantically and syntactically valid, a=
=20
>>>> program should work when compiled without optimizations enabled (empha=
sis=20
>>>> on "semantically valid").
>>>>
>>>
>>> I would find that idea rather controversial, since the distinction=20
>>> between "work" and "not-work" is a matter of resource exhaustion, which=
 is=20
>>> not a standard-defined thing. Also, the standard doesn't recognize the=
=20
>>> distinction between "optimized" and "not optimized"; the standard is th=
e=20
>>> standard.
>>>
>>> The optimization is surely not fit for mandatory, but there can be=20
>> alternatives in terms of PTC (proper tail calls). The formal definition =
(if=20
>> any) would be based on rules about asymptotic computational complexity=
=20
>> during evaluation of expressions, in forms which has already been used b=
y=20
>> the library clause for years. Or simply requirements of capability of=20
>> unbound number of active calls in tail contexts (not so formal, but stil=
l=20
>> normative). Once it is required, there is nothing "not optimized" else t=
han=20
>> nonconformance.
>>
>
> If proper tail calls are going to be part of the language, then it=20
> shouldn't be an "optimization". Why? Because making it an actual feature=
=20
> allows us to do C++-specific things.
>
> For example, the way the OP defined it, it is impossible to have a tail=
=20
> call in a function with non-trivially-destructible types. The C++ model o=
f=20
> calling functions and returning their results requires that local variabl=
es=20
> be destroyed only *after* the function call returns. If tail calls are an=
=20
> "optimization", we can't change that rule willy-nilly. So users have to=
=20
> know a priori that they can't use local variables of other types.
>
> Well, this is one of the problem if it still relies on as-if rules.
=20

> By contrast,if we make it an actual feature through some syntax, then=20
> there's no need for such a limitation. We can explicitly say that local=
=20
> variables are destroyed after the tail function's parameters are=20
> initialized, but before the tail function is called. Or whatever; there a=
re=20
> ways to work it out. This kind of thing would make proper tail calls usef=
ul=20
> in many more contexts.
>
> We can also rule out non-trivially destructed objects. There is some=20
trade-off.
=20

> Having written a few programs in semi-resource-constrained environments,=
=20
>>> there was rarely any expectation that the project would run with no=20
>>> optimizations enabled. And it wasn't for lack of tail recursion; there =
were=20
>>> plenty of other things that drew on those constrained resources.
>>>
>>> I don't believe proper tail calls will do much to change things for suc=
h=20
>>> people.
>>>
>>> Mostly true, but I'm afraid this is not the purpose.
>>
>
> Well, the OP seems to differ, since this was one of their main motivation=
s.
>
> PTC is mainly used to avoid the cases that you have reasonably "enough"=
=20
>> space resources but you still run out of them too easily just because yo=
u=20
>> don't know how many calls are supported at runtime (which cannot be=20
>> predicated in a portable way) - yeah, it is sometimes called as *memory=
=20
>> leak*. It is better to avoid them by default, when there is no=20
>> significant cost at least.
>> =20
>>
>>> Guaranteed elision wasn't added because it freed up developers from=20
>>> relying on an optimization. It was added because it allowed people to d=
o=20
>>> things that otherwise wouldn't work, like return immobile objects.
>>>
>>
>>> Proper tail calls need some motivation like that, where it gives you an=
=20
>>> ability that would be otherwise impossible.
>>>
>>> PTC does essentially quite the same. As the status quo, TCO (tail call=
=20
>> optimization) is optional, allowed by as-if rules. It is unspecified tha=
t=20
>> the program will be optimized or not. The guarantee allows people to ass=
ume=20
>> some basic safety properties without knowledge of implementation details=
..=20
>> (And I suspect it is a fundamental hole if no other guarantee in the=20
>> abstract machine semantics allows you do that since arbitrary call would=
 be=20
>> threaten by undefined behavior.) The only difference is that elision=20
>> interferes observable behavior, so as-if rules are already not sufficien=
t.
>>
>
> And that "only difference" is what makes *all the difference*: the=20
> standard defines observable behavior. Proper tail calls are not observabl=
e=20
> behavior by the abstract model the standard defines, and therefore it=20
> cannot define them.
>

When we have already decided to add the rules of proper tail calls into the=
=20
standard, we can use them to avoid the doubt on introducing unspecified=20
behavior. The rules should work in same manner as copy elision rules if=20
they would be in the standard. To be more precise, the only difference is=
=20
the reason to add the rules. As-if rules are not sufficient for copy=20
elision because of unspecified treatment to observable behavior; however,=
=20
this does not mean they are sufficient for other features with other=20
concerns, even they are already allowed by as-if rules and even they have=
=20
no effect on well-formedness of programs.

This is certainly not the whole story. Guaranteed or not makes a big=20
difference, like the case of copy elision (in spite of glitches between=20
unspecified elision and as-if rules).

The standard defines rules about *conformance*. There is also undefined=20
behavior. You can rely on the defined observable behavior only with=20
well-defined program semantics and conforming implementations. Proper tail=
=20
calls can be defined in a way to avoid some cases of undefined behavior=20
caused by lack of resources. The one has already allowed by as-if rules=20
does not provide such guarantee, so it is OK to stay implicitly; but this=
=20
is strictly permissive in view of implementators, and strictly weaker in=20
view of users. The big difference on conformance and what users can assume=
=20
is not covered by "only difference" previously mentioned, so it might be=20
confusing, though.


> Tail call optimization is different from other types of optimization in=
=20
>>>> that the functionality of programs is fundamentally affected if tail c=
all=20
>>>> optimization doesn't occur. Programmers expect unoptimized programs to=
 run=20
>>>> slower, and to use a bit more memory, but they accept the tradeoff bec=
ause=20
>>>> the lack of optimization doesn't break valid programs. In this case, i=
t=20
>>>> does break valid programs.=20
>>>>
>>>> Standardizing tail call optimization provides programmers with greater=
=20
>>>> certainty that their code will work, and that it'll be portable. It's =
not=20
>>>> just about recursion, either: programmers working on embedded systems =
often=20
>>>> have limited stack space, and the standardization of this optimization=
 will=20
>>>> allow them to better design their code to fit the tight memory require=
ments=20
>>>> (for example, by putting calls to memory hungry routines at the end of=
 a=20
>>>> function).
>>>>
>>>
>>> Such programmers already have to carefully plan their compiler options=
=20
>>> to fit within their environment. So this really would change very littl=
e=20
>>> for them.
>>> =20
>>>
>>>>
>>>> Aside from that, there are many ideas that are best expressed through=
=20
>>>> the use of recursion. Making recursion safe to use will make it easier=
 to=20
>>>> write clean and maintainable code.
>>>>
>>>
>>> Recursion already is safe to use. And I hope that you aren't limiting=
=20
>>> your thinking on proper tail calls to just recursion.=20
>>>
>> I'm afraid that *any *nested calls are not assumed to be safe within=20
>> C++. See above.
>>
>
> And yet, we do it *all the time*. That seems safe enough to me.
>
I used to think it is safe. But I don't find it sufficient evident now, as=
=20
per the rules in the current standard.

IIRC some of points have been exchanged in=20
https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-discuss=
ion/xphK7zA65nU=20
last year.

=20

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/045e2e6c-00c2-4429-9dc5-f78543832180%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>=E5=9C=A8 2018=E5=B9=B46=E6=9C=881=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=BA=94 UTC+8=E4=B8=8A=E5=8D=888:11:50=EF=BC=8CNicol Bolas=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Thursday, May 31, 2018 at 6:20:41 PM UTC-4, FrankHB1989 wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=E5=9C=A8 2018=E5=
=B9=B45=E6=9C=8830=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8A=E5=8D=
=889:49:20=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, May 29, 2018 at 6:03:05=
 PM UTC-4, Antonio Perez wrote:<blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div>I appreciate your feedback. This proposal is based on a r=
ather uncontroversial idea: If it&#39;s semantically and syntactically vali=
d, a program should work when compiled without optimizations enabled (empha=
sis on &quot;semantically valid&quot;).</div></div></blockquote><div><br></=
div><div>I would find that idea rather controversial, since the distinction=
 between &quot;work&quot; and &quot;not-work&quot; is a matter of resource =
exhaustion, which is not a standard-defined thing. Also, the standard doesn=
&#39;t recognize the distinction between &quot;optimized&quot; and &quot;no=
t optimized&quot;; the standard is the standard.<br></div><div><br></div></=
div></blockquote><div>The optimization is surely not fit for mandatory, but=
 there can be alternatives in terms of PTC (proper tail calls). The formal =
definition (if any) would be based on rules about asymptotic computational =
complexity during evaluation of expressions, in forms which has already bee=
n used by the library clause for years. Or simply requirements of capabilit=
y of unbound number of active calls in tail contexts (not so formal, but st=
ill normative). Once it is required, there is nothing &quot;not optimized&q=
uot; else than nonconformance.<br></div></div></blockquote><div><br></div><=
div>If proper tail calls are going to be part of the language, then it shou=
ldn&#39;t be an &quot;optimization&quot;. Why? Because making it an actual =
feature allows us to do C++-specific things.</div><div><br></div><div>For e=
xample, the way the OP defined it, it is impossible to have a tail call in =
a function with non-trivially-destructible types. The C++ model of calling =
functions and returning their results requires that local variables be dest=
royed only <i>after</i> the function call returns. If tail calls are an &qu=
ot;optimization&quot;, we can&#39;t change that rule willy-nilly. So users =
have to know a priori that they can&#39;t use local variables of other type=
s.</div><div><br></div></div></blockquote><div>Well, this is one of the pro=
blem if it still relies on as-if rules.<br>=C2=A0<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>By contrast,i=
f we make it an actual feature through some syntax, then there&#39;s no nee=
d for such a limitation. We can explicitly say that local variables are des=
troyed after the tail function&#39;s parameters are initialized, but before=
 the tail function is called. Or whatever; there are ways to work it out. T=
his kind of thing would make proper tail calls useful in many more contexts=
..</div><div><br></div></div></blockquote><div>We can also rule out non-triv=
ially destructed objects. There is some trade-off.<br>=C2=A0<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>Having written a=
 few programs in semi-resource-constrained environments, there was rarely a=
ny expectation that the project would run with no optimizations enabled. An=
d it wasn&#39;t for lack of tail recursion; there were plenty of other thin=
gs that drew on those constrained resources.</div><div><br></div><div>I don=
&#39;t believe proper tail calls will do much to change things for such peo=
ple.</div><div><br></div></div></blockquote><div>Mostly true, but I&#39;m a=
fraid this is not the purpose.</div></div></blockquote><div><br></div><div>=
Well, the OP seems to differ, since this was one of their main motivations.=
<br></div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>PTC is mainly used to avoid the cases that you have reasonabl=
y &quot;enough&quot; space resources but you still run out of them too easi=
ly just because you don&#39;t know how many calls are supported at runtime =
(which cannot be predicated in a portable way) - yeah, it is sometimes call=
ed as <i>memory leak</i>. It is better to avoid them by default, when there=
 is no significant cost at least.<br>=C2=A0<br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div></div><div>Guaranteed elision wasn&=
#39;t added because it freed up developers from relying on an optimization.=
 It was added because it allowed people to do things that otherwise wouldn&=
#39;t work, like return immobile objects.</div></div></blockquote><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>Proper =
tail calls need some motivation like that, where it gives you an ability th=
at would be otherwise impossible.<br></div><div><br></div></div></blockquot=
e><div>PTC does essentially quite the same. As the status quo, TCO (tail ca=
ll=20
optimization) is optional, allowed by as-if rules. It is unspecified=20
that the program will be optimized or not. The guarantee allows people=20
to assume some basic safety properties without knowledge of=20
implementation details. (And I suspect it is a fundamental hole if no=20
other guarantee in the abstract machine semantics allows you do that=20
since arbitrary call would be threaten by undefined behavior.) The only=20
difference is that elision interferes observable behavior, so as-if=20
rules are already not sufficient.<br></div></div></blockquote><div><br></di=
v><div>And that &quot;only difference&quot; is what makes <i>all the differ=
ence</i>: the standard defines observable behavior. Proper tail calls are n=
ot observable behavior by the abstract model the standard defines, and ther=
efore it cannot define them.</div></div></blockquote><div><br>When we have =
already decided to add the rules of proper tail calls into the standard, we=
 can use them to avoid the doubt on introducing unspecified behavior. The r=
ules should work in same manner as copy elision rules if they would be in t=
he standard. To be more precise, the only difference is the reason to add t=
he rules. As-if rules are not sufficient for copy elision because of unspec=
ified treatment to observable behavior; however, this does not mean they ar=
e sufficient for other features with other concerns, even they are already =
allowed by as-if rules and even they have no effect on well-formedness of p=
rograms.<br><br>This is certainly not the whole story. Guaranteed or not ma=
kes a big difference, like the case of copy elision (in spite of glitches b=
etween unspecified elision and as-if rules).<br><br>The standard defines ru=
les about <i>conformance</i>. There is also undefined behavior. You can rel=
y on the defined observable behavior only with well-defined program semanti=
cs and conforming implementations. Proper tail calls can be defined in a wa=
y to avoid some cases of undefined behavior caused by lack of resources. Th=
e one has already allowed by as-if rules does not provide such guarantee, s=
o it is OK to stay implicitly; but this is strictly permissive in view of i=
mplementators, and strictly weaker in view of users. The big difference on =
conformance and what users can assume is not covered by &quot;only differen=
ce&quot; previously mentioned, so it might be confusing, though.<br><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Tail call optimization=
 is different from other types of optimization in that the functionality of=
 programs is fundamentally affected if tail call optimization doesn&#39;t o=
ccur. Programmers expect unoptimized programs to run slower, and to use a b=
it more memory, but they accept the tradeoff because the lack of optimizati=
on doesn&#39;t break valid programs. In this case, it does break valid prog=
rams.=C2=A0</div><div><br></div><div>Standardizing tail call optimization p=
rovides programmers with greater certainty that their code will work, and t=
hat it&#39;ll be portable. It&#39;s not just about recursion, either: progr=
ammers working on embedded systems often have limited stack space, and the =
standardization of this optimization will allow them to better design their=
 code to fit the tight memory requirements (for example, by putting calls t=
o memory hungry routines at the end of a function).</div></div></blockquote=
><div><br></div><div>Such programmers already have to carefully plan their =
compiler options to fit within their environment. So this really would chan=
ge very little for them.<br></div><div>=C2=A0</div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div><br></div><div>Aside from that, there=
 are many ideas that are best expressed through the use of recursion. Makin=
g recursion safe to use will make it easier to write clean and maintainable=
 code.</div></div></blockquote><div><br></div><div>Recursion already is saf=
e to use. And I hope that you aren&#39;t limiting your thinking on proper t=
ail calls to just recursion. <br></div></div></blockquote><div>I&#39;m afra=
id that <i>any </i>nested calls are not assumed to be safe within C++. See =
above.<br></div></div></blockquote><div><br></div><div>And yet, we do it <i=
>all the time</i>. That seems safe enough to me.<br></div></div></blockquot=
e><div>I used to think it is safe. But I don&#39;t find it sufficient evide=
nt now, as per the rules in the current standard.<br><br>IIRC some of point=
s have been exchanged in https://groups.google.com/a/isocpp.org/forum/?from=
groups#!topic/std-discussion/xphK7zA65nU last year.<br><br>=C2=A0<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/045e2e6c-00c2-4429-9dc5-f78543832180%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/045e2e6c-00c2-4429-9dc5-f78543832180=
%40isocpp.org</a>.<br />

------=_Part_7882_992887838.1527821277823--

------=_Part_7881_1207079971.1527821277823--

.