<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 7, 2015, at 12:30 PM, Mark Lacey &lt;<a href="mailto:mark.lacey@apple.com" class="">mark.lacey@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 7, 2015, at 10:58 AM, Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Dec 5, 2015, at 10:52 AM, Joe Groff &lt;<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Dec 5, 2015, at 10:45 AM, T.J. Usiyan &lt;<a href="mailto:griotspeak@gmail.com" class="">griotspeak@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I did paint ARC as the sole culprit, didn't I? It makes sense that there are other complications and it is interesting to note that ARC isn't the the primary reason.<div class=""><br class=""></div><div class=""><div class="gmail_extra"><div class="gmail_quote">On Sat, Dec 5, 2015 at 9:00 PM, Joe Groff&nbsp;<span dir="ltr" class="">&lt;<a href="mailto:jgroff@apple.com" target="_blank" class="">jgroff@apple.com</a>&gt;</span>&nbsp;wrote:<blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div class="" style="word-wrap: break-word;"><div class=""><br class=""></div><div class="">- only allowing self-recursive tail calls, which avoid some of the stack and memory management problems with arbitrary tail calls,</div><div class="">- only allowing tail calls between functions in the same module, so that the compiler has enough information to use the tail-callable convention only where needed,</div><div class="">- only allowing tail calls between functions in the same module or external functions marked with a '@tail_callable' attribute.</div><font color="#888888" class=""><br class=""></font></div></blockquote><div class=""><br class=""></div><div class="">Even if none of these can be supported immediately, there is a case for adding the attribute with the note that there are almost no supported cases. Guaranteed support for self recursive tail calls, even if that is all we added, would be a huge addition, in my opinion.&nbsp;</div><div class=""><br class=""></div><div class="">I don't know how useful the third option would be but the second case is compelling. I am thinking of parser combinators in particular being a case where the second option could help.</div></div></div></div></div></div></blockquote></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">This seems like a reasonable evolution path. Getting only self-tail-calls working is indeed much simpler, and can likely be implemented mostly in SILGen by jumping to the entry block, without any supporting backend work. Arbitrary tail calls can be supported in the fullness of time.</div></div></blockquote><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">One small thing: for completeness, any tail call proposal would have to describe how it interacts with `defer`. As currently specified, `defer` would have to block tail calling, since the deferred blocks occur after the return expression is evaluated. </div></div></blockquote><div class=""><br class=""></div><div class="">It seems like this could also be handled by passing continuations that should be run on the return paths of callees. The continuation a function passes to its callee would wrap the continuation passed to it by its caller, so they would get executed in the original order. That’s an ABI change though, and a potentially expensive one.</div></div></div></div></blockquote><div><br class=""></div><div>Yeah, that's an interesting idea. It's possibly useful to have defers run after the tail call converges (though arguably you're probably better off just writing the loop version at this point).</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">We’ve considered doing something like this as an optimization to enable more proper tail calls in other cases (e.g. for the ARC case where you release after return). This would be done by cloning callees, and adding a new parameter. It’s not clear how worthwhile it would be to pursue this, and how expensive it would be in terms of code bloat.</div></div></div></div></blockquote><br class=""></div><div>For ARC stuff it seems to me we can ensure all parameters are callee-consumed @owned or @in, and move any non-argument cleanups before the tail call, which eliminates the need for any continuation to be passed.</div><div><br class=""></div><div>-Joe</div><br class=""></body></html>