<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-2844521419334459144.post6468563818101495929..comments</id><updated>2009-05-10T01:35:22.128-07:00</updated><title type='text'>Comments on Muad`Dib: Tail Call Optimization doesn't exist in Haskell</title><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://muaddibspace.blogspot.com/feeds/6468563818101495929/comments/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default'/><link rel='alternate' type='text/html' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html'/><author><name>Muad`Dib</name><uri>http://www.blogger.com/profile/01896828471974774438</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2844521419334459144.post-5274665827268829240</id><published>2008-08-25T13:57:00.000-07:00</published><updated>2008-08-25T13:57:00.000-07:00</updated><title type='text'>dibblego: You are jumping to a false conclusion, I...</title><content type='html'>dibblego: You are jumping to a false conclusion, I hope my follow up post should explain my message clearer.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/5274665827268829240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/5274665827268829240'/><link rel='alternate' type='text/html' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html?showComment=1219697820000#c5274665827268829240' title=''/><author><name>Muad`Dib</name><uri>http://www.blogger.com/profile/01896828471974774438</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17333351345163345233'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html' ref='tag:blogger.com,1999:blog-2844521419334459144.post-6468563818101495929' source='http://www.blogger.com/feeds/2844521419334459144/posts/default/6468563818101495929' type='text/html'/></entry><entry><id>tag:blogger.com,1999:blog-2844521419334459144.post-1746464043218063977</id><published>2008-08-25T02:38:00.000-07:00</published><updated>2008-08-25T02:38:00.000-07:00</updated><title type='text'>wren nailed it. It seems you don't understand why,...</title><content type='html'>wren nailed it. It seems you don't understand why, so here is a simple proof.&lt;BR/&gt;&lt;BR/&gt;Haskell has Data.List.foldl' (and foldl' runs a tail call in constant stack) -QED&lt;BR/&gt;&lt;BR/&gt;Have a nice day.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/1746464043218063977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/1746464043218063977'/><link rel='alternate' type='text/html' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html?showComment=1219657080000#c1746464043218063977' title=''/><author><name>dibblego</name><uri>http://www.blogger.com/profile/17206456907461293947</uri><email>noreply@blogger.com</email></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html' ref='tag:blogger.com,1999:blog-2844521419334459144.post-6468563818101495929' source='http://www.blogger.com/feeds/2844521419334459144/posts/default/6468563818101495929' type='text/html'/></entry><entry><id>tag:blogger.com,1999:blog-2844521419334459144.post-9198396452008804618</id><published>2008-08-24T13:30:00.000-07:00</published><updated>2008-08-24T13:30:00.000-07:00</updated><title type='text'>[0] wren@xenobia:~/test $ cat NoTCO.java ; javac N...</title><content type='html'>[0] wren@xenobia:~/test $ cat NoTCO.java ; javac NoTCO.java ; java NoTCOclass NoTCO {&lt;BR/&gt;                // The int is a lie&lt;BR/&gt;                static int f(int x) { int y = f(x); return y; }&lt;BR/&gt;&lt;BR/&gt;                public static void main(String[] args) {&lt;BR/&gt;                                System.out.println( NoTCO.f(3));&lt;BR/&gt;                }&lt;BR/&gt;}&lt;BR/&gt;Exception in thread "main" java.lang.StackOverflowError&lt;BR/&gt;        at NoTCO.f(NoTCO.java:3)&lt;BR/&gt;        at NoTCO.f(NoTCO.java:3)&lt;BR/&gt;        [...repeat 1022 more times]&lt;BR/&gt;[0] wren@xenobia:~/test $</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/9198396452008804618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/9198396452008804618'/><link rel='alternate' type='text/html' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html?showComment=1219609800000#c9198396452008804618' title=''/><author><name>wren</name><uri>http://www.blogger.com/profile/05766067924472271354</uri><email>noreply@blogger.com</email></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html' ref='tag:blogger.com,1999:blog-2844521419334459144.post-6468563818101495929' source='http://www.blogger.com/feeds/2844521419334459144/posts/default/6468563818101495929' type='text/html'/></entry><entry><id>tag:blogger.com,1999:blog-2844521419334459144.post-3643665274268603256</id><published>2008-08-24T10:45:00.000-07:00</published><updated>2008-08-24T10:45:00.000-07:00</updated><title type='text'>wren: Almost everything you said is accurate and c...</title><content type='html'>wren: Almost everything you said is accurate and correct, It also happens mostly you just repeated what I wrote. Anyway, I've written the exact (let f x = f x in f 3) function in java, along with a lazy evaluator (one which doesn't detect or optimize tail calls), and it doesn't stack overflow, (I've posted it on this site incase you like to see it).</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/3643665274268603256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/3643665274268603256'/><link rel='alternate' type='text/html' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html?showComment=1219599900000#c3643665274268603256' title=''/><author><name>Muad`Dib</name><uri>http://www.blogger.com/profile/01896828471974774438</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17333351345163345233'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html' ref='tag:blogger.com,1999:blog-2844521419334459144.post-6468563818101495929' source='http://www.blogger.com/feeds/2844521419334459144/posts/default/6468563818101495929' type='text/html'/></entry><entry><id>tag:blogger.com,1999:blog-2844521419334459144.post-2806997901367011379</id><published>2008-08-23T18:32:00.000-07:00</published><updated>2008-08-23T18:32:00.000-07:00</updated><title type='text'>Haskell very much does have tail call elimination,...</title><content type='html'>Haskell very much does have tail call elimination, any claims to the contrary are &lt;A HREF="http://www.reddit.com/comments/6xnk5/ive_got_two_weeks_of_vacation_coming_up_should_i/c055b9w" REL="nofollow"&gt;demonstrably&lt;/A&gt; &lt;A HREF="http://cgi.cse.unsw.edu.au/~dons/blog/2008/05/16#fast" REL="nofollow"&gt;false&lt;/A&gt;. Your stack overflow issues have nothing to do with tail call elimination. You've said this yourself, though you seem not to have followed the reasoning to conclusion.&lt;BR/&gt;&lt;BR/&gt;This is just a canonical issue with accumulator functions in lazy languages. All of your tail calls to &lt;B&gt;cat'&lt;/B&gt; as you construct that accumulator are eliminated perfectly fine. The problem is that you end up with a million element thunk at the end. When you pull on that thunk there are no tail calls to eliminate.&lt;BR/&gt;&lt;BR/&gt;The expression for your accumulator is: &lt;B&gt;(((((((...(0 + 1) + 2) + 3)... + 1000000)&lt;/B&gt;. (N.B. it is not &lt;B&gt;(0 + (1 +...)))&lt;/B&gt;!) The ultimate call to &lt;B&gt;seq acc&lt;/B&gt; will tail call the topmost &lt;B&gt;(+)&lt;/B&gt;, reusing the stack frame used by &lt;B&gt;seq&lt;/B&gt;. But from there, since &lt;B&gt;(+)&lt;/B&gt; is strict in its arguments it must evaluate the left hand expression before it can return. This is repeated a million times as you descend. But none of those are tail calls and so the problem has nothing whatsoever to do with GHC's eliminating tail calls.&lt;BR/&gt;&lt;BR/&gt;You repeat the same problem with your Peano integers since your definition of &lt;B&gt;plus&lt;/B&gt; requires evaluating the left-hand argument to WHNF and the left-hand argument is the one with a million-1 depth call stack. Try having your definition count down on the right operand instead. Now, &lt;B&gt;cat'&lt;/B&gt; works perfectly fine! Of course &lt;B&gt;cat&lt;/B&gt; will stack overflow, because now it has the same problem as &lt;B&gt;cat'&lt;/B&gt; did with the old definition of &lt;B&gt;plus&lt;/B&gt;; you've just exchanged which definition works in synch with the pattern of thunks.&lt;BR/&gt;&lt;BR/&gt;The well known solution to this canonical interaction between accumulators and laziness is to strictly evaluate the accumulator at each step. What this does is amortize the call stack for evaluating the accumulator across all the recursive calls. The strictness call can't be eliminated because its result is needed for the recursive call, but the recursive call can be eliminated because the result of the callee is the same as the result of the caller. Thus you have a call stack depth of at most two (or rather, one plus whatever depth is needed to bring the accumulator back to WHNF). &lt;BR/&gt;&lt;BR/&gt;Your infinite loops chirp away happily &lt;I&gt;precisely because&lt;/I&gt; GHC does tail call elimination. If it did not then those functions would cause a stack overflow. Try writing those exact functions in Java and watch them explode. (Alas C is no longer a good example since the GHC folks cracked GCC open and added in TCO for everyone.) "Tail call elimination" means only that the current stack frame can be reused if the last action of the current function is to call another function. Because GHC does indeed do tail call elimination the frame for the first call to &lt;B&gt;f&lt;/B&gt; can be reused when making the second call to &lt;B&gt;f&lt;/B&gt;, and that frame can be reused when making the third call to &lt;B&gt;f&lt;/B&gt;, etc. In a language without TCO each one of those calls would require an additional stack frame until you overflow.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/2806997901367011379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2844521419334459144/6468563818101495929/comments/default/2806997901367011379'/><link rel='alternate' type='text/html' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html?showComment=1219541520000#c2806997901367011379' title=''/><author><name>wren</name><uri>http://www.blogger.com/profile/05766067924472271354</uri><email>noreply@blogger.com</email></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://muaddibspace.blogspot.com/2008/08/tail-call-optimization-doesnt-exist-in.html' ref='tag:blogger.com,1999:blog-2844521419334459144.post-6468563818101495929' source='http://www.blogger.com/feeds/2844521419334459144/posts/default/6468563818101495929' type='text/html'/></entry></feed>