<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Recursion Fail</title>
	<atom:link href="http://braincrater.wordpress.com/2008/04/11/recursion-fail/feed/" rel="self" type="application/rss+xml" />
	<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/</link>
	<description>Thoughts from my splattered grey matter.</description>
	<lastBuildDate>Fri, 02 Sep 2011 16:26:44 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Justin</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-25</link>
		<dc:creator><![CDATA[Justin]]></dc:creator>
		<pubDate>Fri, 11 Jul 2008 06:41:14 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-25</guid>
		<description><![CDATA[Python _doesn&#039;t_, however, allow multi-line anonymous functions.]]></description>
		<content:encoded><![CDATA[<p>Python _doesn&#8217;t_, however, allow multi-line anonymous functions.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: bradenshep</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-24</link>
		<dc:creator><![CDATA[bradenshep]]></dc:creator>
		<pubDate>Fri, 11 Jul 2008 03:08:28 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-24</guid>
		<description><![CDATA[I&#039;m definitely not dons. His blog is &lt;a href=&quot;http://cgi.cse.unsw.edu.au/~dons/blog&quot; rel=&quot;nofollow&quot;&gt;here&lt;/a&gt;. 

As to how to traverse a tree or other nonlinear structure, there are two answers. The first is that the Functor instance decides on the order. The other is that it usually doesn&#039;t matter, due to purity. If the traversal has no side effects, the order of evaluation doesn&#039;t matter. Whole parts of it (up to and including the entire traversal) may in fact never be executed, or may be optimized away.

And so, the standard instance of Functor for a binary tree like mine is:
&lt;code&gt;instance Functor Tree where
    fmap _ Empty       = Empty
    fmap f (Node a l r) = Node (f a) (fmap f l) (fmap f r)&lt;/code&gt;
which appears &lt;i&gt;a priori&lt;/i&gt; to implement a preorder traversal. On a second look, though, since Haskell is non-strict, no particular order is guaranteed. However, the order is guaranteed to be fixed, since purity means it will have the same result every time you call it.]]></description>
		<content:encoded><![CDATA[<p>I&#8217;m definitely not dons. His blog is <a href="http://cgi.cse.unsw.edu.au/~dons/blog" rel="nofollow">here</a>. </p>
<p>As to how to traverse a tree or other nonlinear structure, there are two answers. The first is that the Functor instance decides on the order. The other is that it usually doesn&#8217;t matter, due to purity. If the traversal has no side effects, the order of evaluation doesn&#8217;t matter. Whole parts of it (up to and including the entire traversal) may in fact never be executed, or may be optimized away.</p>
<p>And so, the standard instance of Functor for a binary tree like mine is:<br />
<code>instance Functor Tree where<br />
    fmap _ Empty       = Empty<br />
    fmap f (Node a l r) = Node (f a) (fmap f l) (fmap f r)</code><br />
which appears <i>a priori</i> to implement a preorder traversal. On a second look, though, since Haskell is non-strict, no particular order is guaranteed. However, the order is guaranteed to be fixed, since purity means it will have the same result every time you call it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: web design</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-23</link>
		<dc:creator><![CDATA[web design]]></dc:creator>
		<pubDate>Fri, 11 Jul 2008 02:21:50 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-23</guid>
		<description><![CDATA[dons, how would you abstract out a data structure traversal where at each step we make a decision where to go next? (For lists, you have two choices: stop, or next element. For binary trees, you can go to either child or stop. Etc.)]]></description>
		<content:encoded><![CDATA[<p>dons, how would you abstract out a data structure traversal where at each step we make a decision where to go next? (For lists, you have two choices: stop, or next element. For binary trees, you can go to either child or stop. Etc.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: bradenshep</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-22</link>
		<dc:creator><![CDATA[bradenshep]]></dc:creator>
		<pubDate>Thu, 10 Jul 2008 17:09:00 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-22</guid>
		<description><![CDATA[@ DeepBlue

It can&#039;t. Try-every-path exhaustive searches are described using the list monad. As an example, finding Pythagorean triples with a given perimeter.

triples n = [ (a,b, c) &#124; a &lt;- [1..n], b &lt;- [1..a], let c = n - a - b, a^2 + b^2 == c^2 ]

This is a list comprehension, which is syntactic sugar for the list monad.

In the case of an alpha-beta AI, I now know that you can&#039;t quite use a list comprehension, as they model an exhaustive search. One that short-circuits certain paths when they become too unfavourable can be defined using a similar monad, though obviously the syntax won&#039;t be as short as list comprehensions, since you also need to specify the cutoff for an unfavourable result, a possible short-circuiting if the best possible value has already been seen, etc. The code &lt;a href=&quot;http://www.haskell.org/haskellwiki/Principal_variation_search&quot; rel=&quot;nofollow&quot;&gt;here&lt;/a&gt; gives a working alpha-beta and short-circuiting model.]]></description>
		<content:encoded><![CDATA[<p>@ DeepBlue</p>
<p>It can&#8217;t. Try-every-path exhaustive searches are described using the list monad. As an example, finding Pythagorean triples with a given perimeter.</p>
<p>triples n = [ (a,b, c) | a &lt;- [1..n], b &lt;- [1..a], let c = n &#8211; a &#8211; b, a^2 + b^2 == c^2 ]</p>
<p>This is a list comprehension, which is syntactic sugar for the list monad.</p>
<p>In the case of an alpha-beta AI, I now know that you can&#8217;t quite use a list comprehension, as they model an exhaustive search. One that short-circuits certain paths when they become too unfavourable can be defined using a similar monad, though obviously the syntax won&#8217;t be as short as list comprehensions, since you also need to specify the cutoff for an unfavourable result, a possible short-circuiting if the best possible value has already been seen, etc. The code <a href="http://www.haskell.org/haskellwiki/Principal_variation_search" rel="nofollow">here</a> gives a working alpha-beta and short-circuiting model.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: bradenshep</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-21</link>
		<dc:creator><![CDATA[bradenshep]]></dc:creator>
		<pubDate>Thu, 10 Jul 2008 16:38:06 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-21</guid>
		<description><![CDATA[@pozorvlak, sean, eddie:

I&#039;m well-aware that Perl, Python and similar have a fully general map (and filter/grep and fold/reduce/etc) function. Even more so, Perl has full-strength lexical closures. It&#039;s pretty close to an acceptable functional language (indeed, see Higher Order Perl). Unfortunately the function call overhead (due mostly to list-flattening) makes it rather a slow one. (Does Python have closures (not just lambdas)? I don&#039;t know it as well as I do Perl. Ruby?)

@ pozorvlak:
Any loop, or equivalently, any linear recursion, can be written using foldr. Since, as I say, the various standard HOFs cover most linear recursion patterns, see these redefinitions in terms of foldr:

map f = foldr (\x xs -&gt; f x : xs ) []
filter f = foldr (\x xs -&gt; if p x then x:xs else xs) []
length = foldr (\_ n -&gt; n+1) 0

@ Rick:

I&#039;m not mainly concerned with performance, though of course an optimizing compiler such as GHC has to work a lot less hard to know what map means than to analyze a custom linear recursion, and so is more likely to optimize a map, and more effective at doing so.

I feel that the crux of the article was in fact code readability, both in the eye of the programmer and the reader. I came from an imperative background too, and so as I said in the main article, I found it hard to reason in terms of higher-order functions when I first came to Haskell. When I was reading someone else&#039;s code, I always had to pause and think about what foldr or map meant. Now that I&#039;ve become more accustomed to Haskell, I don&#039;t hesitate anymore: they are perfectly natural. 

If this seems to demand more of the programmer than explicit recursion, I understand the point. But to someone who doesn&#039;t know English very well, reading this comment would be difficult. To a fluent speaker, its meaning is plain. I used several English idioms (crux of the article, accustomed to something, to see a point), and while I could have written them more explicitly, it would come at the cost of making the post harder to read for one fluent in English. So I believe it to be with the use of higher-order functions compared to explicit recursion. If someone writes a map explicitly, the reader needs to double-check that the stop condition is the same, that the recursion pattern really is that of map. &quot;map&quot; guarantees all of those things.]]></description>
		<content:encoded><![CDATA[<p>@pozorvlak, sean, eddie:</p>
<p>I&#8217;m well-aware that Perl, Python and similar have a fully general map (and filter/grep and fold/reduce/etc) function. Even more so, Perl has full-strength lexical closures. It&#8217;s pretty close to an acceptable functional language (indeed, see Higher Order Perl). Unfortunately the function call overhead (due mostly to list-flattening) makes it rather a slow one. (Does Python have closures (not just lambdas)? I don&#8217;t know it as well as I do Perl. Ruby?)</p>
<p>@ pozorvlak:<br />
Any loop, or equivalently, any linear recursion, can be written using foldr. Since, as I say, the various standard HOFs cover most linear recursion patterns, see these redefinitions in terms of foldr:</p>
<p>map f = foldr (\x xs -&gt; f x : xs ) []<br />
filter f = foldr (\x xs -&gt; if p x then x:xs else xs) []<br />
length = foldr (\_ n -&gt; n+1) 0</p>
<p>@ Rick:</p>
<p>I&#8217;m not mainly concerned with performance, though of course an optimizing compiler such as GHC has to work a lot less hard to know what map means than to analyze a custom linear recursion, and so is more likely to optimize a map, and more effective at doing so.</p>
<p>I feel that the crux of the article was in fact code readability, both in the eye of the programmer and the reader. I came from an imperative background too, and so as I said in the main article, I found it hard to reason in terms of higher-order functions when I first came to Haskell. When I was reading someone else&#8217;s code, I always had to pause and think about what foldr or map meant. Now that I&#8217;ve become more accustomed to Haskell, I don&#8217;t hesitate anymore: they are perfectly natural. </p>
<p>If this seems to demand more of the programmer than explicit recursion, I understand the point. But to someone who doesn&#8217;t know English very well, reading this comment would be difficult. To a fluent speaker, its meaning is plain. I used several English idioms (crux of the article, accustomed to something, to see a point), and while I could have written them more explicitly, it would come at the cost of making the post harder to read for one fluent in English. So I believe it to be with the use of higher-order functions compared to explicit recursion. If someone writes a map explicitly, the reader needs to double-check that the stop condition is the same, that the recursion pattern really is that of map. &#8220;map&#8221; guarantees all of those things.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: DeepBlue</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-19</link>
		<dc:creator><![CDATA[DeepBlue]]></dc:creator>
		<pubDate>Thu, 10 Jul 2008 15:06:52 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-19</guid>
		<description><![CDATA[It&#039;s not clear to me how alpha-beta pruning can be expressed as a fold.  Could you comment more about this?  Thank you!]]></description>
		<content:encoded><![CDATA[<p>It&#8217;s not clear to me how alpha-beta pruning can be expressed as a fold.  Could you comment more about this?  Thank you!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: eddie</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-17</link>
		<dc:creator><![CDATA[eddie]]></dc:creator>
		<pubDate>Thu, 10 Jul 2008 12:07:22 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-17</guid>
		<description><![CDATA[python does have a map() , filter() and apply() functions, and you can use then instead of recursion, too]]></description>
		<content:encoded><![CDATA[<p>python does have a map() , filter() and apply() functions, and you can use then instead of recursion, too</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rick</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-16</link>
		<dc:creator><![CDATA[Rick]]></dc:creator>
		<pubDate>Thu, 10 Jul 2008 06:12:41 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-16</guid>
		<description><![CDATA[&gt; It’s been a Haskell programming rule of mine for a long time that explicit recursion is an admission of failure. 

This is an interesting point. I can appreciate the code minimization benefits of this approach, but it seems like you are implying (without saying it) that there are some performance reasons why higher order functions are better choices than explicit recursions. 

If this is true (and correct me if I misunderstood), I&#039;d be interested to know a little more about this. Are there any references that talk about this from a performance perspective ? This is the first time I&#039;ve come across the idea of higher order functions out performing explicit recursions.

I come from a java-shop background, and one of the things stressed there is code-readability. I&#039;ve always found that mentally digesting folds in someone else is code is tricky compared with explicit recursions (especially for newbies like you said), 
so if there wasn&#039;t a performance benefit in writing recursions with folds, wouldn&#039;t the readability trump the code minimization ?

Interested to hear your comments. Thanks,

Rick]]></description>
		<content:encoded><![CDATA[<p>&gt; It’s been a Haskell programming rule of mine for a long time that explicit recursion is an admission of failure. </p>
<p>This is an interesting point. I can appreciate the code minimization benefits of this approach, but it seems like you are implying (without saying it) that there are some performance reasons why higher order functions are better choices than explicit recursions. </p>
<p>If this is true (and correct me if I misunderstood), I&#8217;d be interested to know a little more about this. Are there any references that talk about this from a performance perspective ? This is the first time I&#8217;ve come across the idea of higher order functions out performing explicit recursions.</p>
<p>I come from a java-shop background, and one of the things stressed there is code-readability. I&#8217;ve always found that mentally digesting folds in someone else is code is tricky compared with explicit recursions (especially for newbies like you said),<br />
so if there wasn&#8217;t a performance benefit in writing recursions with folds, wouldn&#8217;t the readability trump the code minimization ?</p>
<p>Interested to hear your comments. Thanks,</p>
<p>Rick</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: sean</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-15</link>
		<dc:creator><![CDATA[sean]]></dc:creator>
		<pubDate>Thu, 10 Jul 2008 05:22:57 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-15</guid>
		<description><![CDATA[perldoc -f map]]></description>
		<content:encoded><![CDATA[<p>perldoc -f map</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Shane</title>
		<link>http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-14</link>
		<dc:creator><![CDATA[Shane]]></dc:creator>
		<pubDate>Wed, 09 Jul 2008 23:55:56 +0000</pubDate>
		<guid isPermaLink="false">http://braincrater.wordpress.com/2008/04/11/recursion-fail/#comment-14</guid>
		<description><![CDATA[I&#039;m glad you didn&#039;t suggest people strive to write in terms of maps or folds right off the bat.  I remember writing lots of code that were doing folds, but it was only after I had written them and refactored them that I could put them into folds.  So I just wanted to compliment you on the article and the advice.  I believe it is sound, and it provides a low-grade slope for people to move up toward higher order functions.  It worked for me.]]></description>
		<content:encoded><![CDATA[<p>I&#8217;m glad you didn&#8217;t suggest people strive to write in terms of maps or folds right off the bat.  I remember writing lots of code that were doing folds, but it was only after I had written them and refactored them that I could put them into folds.  So I just wanted to compliment you on the article and the advice.  I believe it is sound, and it provides a low-grade slope for people to move up toward higher order functions.  It worked for me.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
