<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: This Function is Not Tail Recursive</title>
	<atom:link href="http://codemonkeyism.com/function-tail-recursive/feed/" rel="self" type="application/rss+xml" />
	<link>http://codemonkeyism.com/function-tail-recursive/</link>
	<description></description>
	<lastBuildDate>Tue, 03 Jan 2012 15:08:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Stefan Plantikow</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-308220</link>
		<dc:creator>Stefan Plantikow</dc:creator>
		<pubDate>Tue, 20 Jul 2010 17:58:05 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-308220</guid>
		<description>In practice I live by the following definition: It&#039;s tail recursive if there is no return point in the function that requires the current stack frame to be kept around until the recursive call returns.  Beyond this one only needs to know if one&#039;s compiler is clever enough to actually notice this and do something smart about it (like turning the tail recursive function application into a loop).  

Oh, and it has about nothing to do with being parallelizable except that tail-recursive functions often tend to be referentially transparent, too, and therefore are memoizable (can be cached).</description>
		<content:encoded><![CDATA[<p>In practice I live by the following definition: It&#8217;s tail recursive if there is no return point in the function that requires the current stack frame to be kept around until the recursive call returns.  Beyond this one only needs to know if one&#8217;s compiler is clever enough to actually notice this and do something smart about it (like turning the tail recursive function application into a loop).  </p>
<p>Oh, and it has about nothing to do with being parallelizable except that tail-recursive functions often tend to be referentially transparent, too, and therefore are memoizable (can be cached).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-308166</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Tue, 20 Jul 2010 11:16:30 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-308166</guid>
		<description>@littleli: Funny, first comment on that link says

&lt;blockquote&gt;Interesting stuff John. It would be interesting to see some examples that would benefit from such optimization. Am I correct that the following code could use this feature to achieve better performance? int f(int i) { return i==1 ? 1 : i + f(i-1); } Do you think if javac compiler could such optimizations automatically for the regular Java language.
&lt;/blockquote&gt;

&lt;b&gt;Q.E.D.&lt;/b&gt;</description>
		<content:encoded><![CDATA[<p>@littleli: Funny, first comment on that link says</p>
<blockquote><p>Interesting stuff John. It would be interesting to see some examples that would benefit from such optimization. Am I correct that the following code could use this feature to achieve better performance? int f(int i) { return i==1 ? 1 : i + f(i-1); } Do you think if javac compiler could such optimizations automatically for the regular Java language.
</p></blockquote>
<p><b>Q.E.D.</b></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: littleli</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-308153</link>
		<dc:creator>littleli</dc:creator>
		<pubDate>Tue, 20 Jul 2010 09:54:09 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-308153</guid>
		<description>There is also a great post from John Rose about tail calls support in JVM http://blogs.sun.com/jrose/entry/tail_calls_in_the_vm and I hope there is something on the way to Java 7 that is going to be useful.</description>
		<content:encoded><![CDATA[<p>There is also a great post from John Rose about tail calls support in JVM <a href="http://blogs.sun.com/jrose/entry/tail_calls_in_the_vm" rel="nofollow">http://blogs.sun.com/jrose/entry/tail_calls_in_the_vm</a> and I hope there is something on the way to Java 7 that is going to be useful.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-308116</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Tue, 20 Jul 2010 05:33:16 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-308116</guid>
		<description>@Paul: If I need to decided between tail recursion and local mutability, it&#039;s not automatic that tail recursion ist better. Like tail recursion being a hammer to solve all problems because it&#039;s fast.</description>
		<content:encoded><![CDATA[<p>@Paul: If I need to decided between tail recursion and local mutability, it&#8217;s not automatic that tail recursion ist better. Like tail recursion being a hammer to solve all problems because it&#8217;s fast.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Phillips</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-308082</link>
		<dc:creator>Paul Phillips</dc:creator>
		<pubDate>Tue, 20 Jul 2010 02:04:04 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-308082</guid>
		<description>@stephan: He&#039;s demonstrating it was slower than iterating over a mutable structure, not that it&#039;s slower than unoptimized recursion.  This leaves you with no apparent point.  I can&#039;t think of any scenario in scala where transforming a tail call into a jump could slow it down compared to not doing so.</description>
		<content:encoded><![CDATA[<p>@stephan: He&#8217;s demonstrating it was slower than iterating over a mutable structure, not that it&#8217;s slower than unoptimized recursion.  This leaves you with no apparent point.  I can&#8217;t think of any scenario in scala where transforming a tail call into a jump could slow it down compared to not doing so.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-308019</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Mon, 19 Jul 2010 20:13:36 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-308019</guid>
		<description>@Douglas: Or because tail-recursion is slower - see

http://debasishg.blogspot.com/2008/10/to-tail-recurse-or-not.html</description>
		<content:encoded><![CDATA[<p>@Douglas: Or because tail-recursion is slower &#8211; see</p>
<p><a href="http://debasishg.blogspot.com/2008/10/to-tail-recurse-or-not.html" rel="nofollow">http://debasishg.blogspot.com/2008/10/to-tail-recurse-or-not.html</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Douglas</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307999</link>
		<dc:creator>Douglas</dc:creator>
		<pubDate>Mon, 19 Jul 2010 18:59:12 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307999</guid>
		<description>@stephan: it is certainly possible to write a compiler/interpreter which does not perform tail call optimisation on any of your examples. One reason to do so might be to output full stack traces, including those frames which could be discarded through tail call optimisation to aid debugging. So, whether a tail call is made is very much influenced by the compiler.

However, the ease with which a function may be optimised is, as you say, a property of the function itself.</description>
		<content:encoded><![CDATA[<p>@stephan: it is certainly possible to write a compiler/interpreter which does not perform tail call optimisation on any of your examples. One reason to do so might be to output full stack traces, including those frames which could be discarded through tail call optimisation to aid debugging. So, whether a tail call is made is very much influenced by the compiler.</p>
<p>However, the ease with which a function may be optimised is, as you say, a property of the function itself.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307966</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Mon, 19 Jul 2010 18:22:05 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307966</guid>
		<description>@dude: Might be, but I don&#039;t think so :-)

Your comment sounds like it depends on a compiler if a function has tail recursiveness. It doesn&#039;t.</description>
		<content:encoded><![CDATA[<p>@dude: Might be, but I don&#8217;t think so :-)</p>
<p>Your comment sounds like it depends on a compiler if a function has tail recursiveness. It doesn&#8217;t.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: dude</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307960</link>
		<dc:creator>dude</dc:creator>
		<pubDate>Mon, 19 Jul 2010 18:10:30 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307960</guid>
		<description>@stephan: I think you just misunderstood what I said and then just rephrased my point :)</description>
		<content:encoded><![CDATA[<p>@stephan: I think you just misunderstood what I said and then just rephrased my point :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307948</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Mon, 19 Jul 2010 17:55:21 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307948</guid>
		<description>@Dude: Tail recursion has nothing to do with compilers. Compilers can use the fact that a function is tail recursive and optimize. But the connection is not the other way round.</description>
		<content:encoded><![CDATA[<p>@Dude: Tail recursion has nothing to do with compilers. Compilers can use the fact that a function is tail recursive and optimize. But the connection is not the other way round.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307936</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Mon, 19 Jul 2010 17:43:15 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307936</guid>
		<description>@Paul: Thanks for this example, haven&#039;t tested @tailrec myself.</description>
		<content:encoded><![CDATA[<p>@Paul: Thanks for this example, haven&#8217;t tested @tailrec myself.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Phillips</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307924</link>
		<dc:creator>Paul Phillips</dc:creator>
		<pubDate>Mon, 19 Jul 2010 17:28:32 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307924</guid>
		<description>Not only is there @tailrec, but these days it&#039;s very specific about how you blew it.  Since there&#039;s no preview and I have no idea what markup options I have this will probably be a mess, but:

&lt;code&gt;
scala&gt; import annotation._
import annotation._

scala&gt; @tailrec def fac(n: Int): Int = if (n==0) 1 else n * fac(n-1)
:8: error: could not optimize @tailrec annotated method: it contains a recursive call not in tail position
       @tailrec def fac(n: Int): Int = if (n==0) 1 else n * fac(n-1)
                    ^
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>Not only is there @tailrec, but these days it&#8217;s very specific about how you blew it.  Since there&#8217;s no preview and I have no idea what markup options I have this will probably be a mess, but:</p>
<p><code><br />
scala&gt; import annotation._<br />
import annotation._</p>
<p>scala&gt; @tailrec def fac(n: Int): Int = if (n==0) 1 else n * fac(n-1)<br />
:8: error: could not optimize @tailrec annotated method: it contains a recursive call not in tail position<br />
       @tailrec def fac(n: Int): Int = if (n==0) 1 else n * fac(n-1)<br />
                    ^<br />
</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Anders Pearson</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307918</link>
		<dc:creator>Anders Pearson</dc:creator>
		<pubDate>Mon, 19 Jul 2010 17:19:51 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307918</guid>
		<description>One of the nice things about lisp-like languages (or any non-infix one, really) is that the mistake would&#039;ve been obvious from the beginning since instead of &quot;n * fac(n -1)&quot; it would be written &quot;(* n (fac (- n 1)))&quot; and you would clearly see that there&#039;s another function outside fac.</description>
		<content:encoded><![CDATA[<p>One of the nice things about lisp-like languages (or any non-infix one, really) is that the mistake would&#8217;ve been obvious from the beginning since instead of &#8220;n * fac(n -1)&#8221; it would be written &#8220;(* n (fac (- n 1)))&#8221; and you would clearly see that there&#8217;s another function outside fac.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: dude</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307909</link>
		<dc:creator>dude</dc:creator>
		<pubDate>Mon, 19 Jul 2010 17:06:39 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307909</guid>
		<description>Tail recursion is a compiler optimization, so what matters isn&#039;t whether or not the last call is a simply function call or a function call as part of a bigger expression, but rather if the compiler can optimize a tail recursive call out of the code _period_.

Scala specifically, due to limitations of the JVM, cannot optimize away the example code you provided -- very true. And it&#039;s almost certainly better to write it the second way to be sure.

Just wanted to point out that it&#039;s the compilers job to make it tail recursive in the first place, and so it&#039;s ability to do that will vary by language.</description>
		<content:encoded><![CDATA[<p>Tail recursion is a compiler optimization, so what matters isn&#8217;t whether or not the last call is a simply function call or a function call as part of a bigger expression, but rather if the compiler can optimize a tail recursive call out of the code _period_.</p>
<p>Scala specifically, due to limitations of the JVM, cannot optimize away the example code you provided &#8212; very true. And it&#8217;s almost certainly better to write it the second way to be sure.</p>
<p>Just wanted to point out that it&#8217;s the compilers job to make it tail recursive in the first place, and so it&#8217;s ability to do that will vary by language.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307876</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Mon, 19 Jul 2010 16:12:54 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307876</guid>
		<description>@Brian: Sorry, I did not write what I&#039;ve meant.

I&#039;ve meant &lt;code&gt;h(f,g)&lt;/code&gt; then f and g are parallelizeable.</description>
		<content:encoded><![CDATA[<p>@Brian: Sorry, I did not write what I&#8217;ve meant.</p>
<p>I&#8217;ve meant <code>h(f,g)</code> then f and g are parallelizeable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brian Hurt</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307871</link>
		<dc:creator>Brian Hurt</dc:creator>
		<pubDate>Mon, 19 Jul 2010 16:05:01 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307871</guid>
		<description>Tail recursive functions are not necessarily parallelizeable- consider fold_left (aka reduce, for you lispers).  It&#039;s easier to determine if pure functions can be parallelized or not, as the dependencies are explicitly stated as data dependencies.  But if a function f uses as an input the output of function g, then f and g are (generally) not parallelizable.</description>
		<content:encoded><![CDATA[<p>Tail recursive functions are not necessarily parallelizeable- consider fold_left (aka reduce, for you lispers).  It&#8217;s easier to determine if pure functions can be parallelized or not, as the dependencies are explicitly stated as data dependencies.  But if a function f uses as an input the output of function g, then f and g are (generally) not parallelizable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307862</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Mon, 19 Jul 2010 15:42:09 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307862</guid>
		<description>Perhaps Scala @tailrec should also be mentioned.</description>
		<content:encoded><![CDATA[<p>Perhaps Scala @tailrec should also be mentioned.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Coglan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307860</link>
		<dc:creator>James Coglan</dc:creator>
		<pubDate>Mon, 19 Jul 2010 15:39:59 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307860</guid>
		<description>Perhaps a better way to think of it is that a function is tail recursive if its return value is just the return value of the recursive call. Trying to figure out what the last operation is can be slightly unintuitive, but figuring out that the value of the recursive call gets passed straight through to the original function&#039;s caller is slightly easier to grasp.</description>
		<content:encoded><![CDATA[<p>Perhaps a better way to think of it is that a function is tail recursive if its return value is just the return value of the recursive call. Trying to figure out what the last operation is can be slightly unintuitive, but figuring out that the value of the recursive call gets passed straight through to the original function&#8217;s caller is slightly easier to grasp.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: stephan</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307859</link>
		<dc:creator>stephan</dc:creator>
		<pubDate>Mon, 19 Jul 2010 15:38:06 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307859</guid>
		<description>@Nick: Thx for the comment - left it out of the article because I&#039;ve blogged about that in the linked post.

Probably it&#039;s better to have the information here too - so thanks.</description>
		<content:encoded><![CDATA[<p>@Nick: Thx for the comment &#8211; left it out of the article because I&#8217;ve blogged about that in the linked post.</p>
<p>Probably it&#8217;s better to have the information here too &#8211; so thanks.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nick Wiedenbrueck</title>
		<link>http://codemonkeyism.com/function-tail-recursive/comment-page-1/#comment-307853</link>
		<dc:creator>Nick Wiedenbrueck</dc:creator>
		<pubDate>Mon, 19 Jul 2010 15:15:52 +0000</pubDate>
		<guid isPermaLink="false">http://codemonkeyism.com/?p=1840#comment-307853</guid>
		<description>Haven&#039;t read the article, but that would be quite embarrassing.

Anyway, just wanted to add, that tail recursion generally is more efficient than non-tail recursive functions, because ressources don&#039;t have to be maintained over the recursive calls - at least in theory. On the JVM there will be created a new stack frame on each call, because tail recursion is not supported very well. On the other hand, the Scala compiler has tail call optimization and basically would turn the calls into a while loop.

Read my blog post on this topic, if you like http://stronglytypedblog.blogspot.com/2009/08/scala-tail-recursion.html</description>
		<content:encoded><![CDATA[<p>Haven&#8217;t read the article, but that would be quite embarrassing.</p>
<p>Anyway, just wanted to add, that tail recursion generally is more efficient than non-tail recursive functions, because ressources don&#8217;t have to be maintained over the recursive calls &#8211; at least in theory. On the JVM there will be created a new stack frame on each call, because tail recursion is not supported very well. On the other hand, the Scala compiler has tail call optimization and basically would turn the calls into a while loop.</p>
<p>Read my blog post on this topic, if you like <a href="http://stronglytypedblog.blogspot.com/2009/08/scala-tail-recursion.html" rel="nofollow">http://stronglytypedblog.blogspot.com/2009/08/scala-tail-recursion.html</a></p>
]]></content:encoded>
	</item>
</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk (user agent is rejected)
Database Caching 4/30 queries in 0.047 seconds using disk

Served from: codemonkeyism.com @ 2012-02-09 02:51:43 -->
