<?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: Integral Calculus in Haskell</title>
	<atom:link href="http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/feed/" rel="self" type="application/rss+xml" />
	<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/</link>
	<description>Secrets revealed.</description>
	<lastBuildDate>Fri, 10 Apr 2009 06:28:13 -0500</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: solrize</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-12</link>
		<dc:creator>solrize</dc:creator>
		<pubDate>Fri, 10 Apr 2009 06:28:13 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-12</guid>
		<description>You might like John Hughes&#039; famous article &quot;Why Functional Programming Matters&quot;, which goes over a few examples like this.  It was written in the 1980&#039;s and uses Miranda, an older language that Haskell is descended from, that should be easy to understand.  You should be able to find it online easily.</description>
		<content:encoded><![CDATA[<p>You might like John Hughes&#8217; famous article &#8220;Why Functional Programming Matters&#8221;, which goes over a few examples like this.  It was written in the 1980&#8217;s and uses Miranda, an older language that Haskell is descended from, that should be easy to understand.  You should be able to find it online easily.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Leon Smith</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-11</link>
		<dc:creator>Leon Smith</dc:creator>
		<pubDate>Fri, 10 Apr 2009 04:04:41 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-11</guid>
		<description>@Joe Fredette:   nothing symbolic here:  it&#039;s a purely numerical technique.   It could be improved a bit by using the trapezoidal or Simpson&#039;s Rule.    I second the AD suggestion,  obviously. :-)

@Jake McArthur and jberryman:   very erudite comments.   One big thing about learning Haskell well is learning when there will be thunks versus when concrete values will be produced.

Basically,  common situations where evaluation will be forced,  avoiding the creation of thunks,  is on conditional branches,  pattern matching,  and uses of &quot;seq&quot; and friends.</description>
		<content:encoded><![CDATA[<p>@Joe Fredette:   nothing symbolic here:  it&#8217;s a purely numerical technique.   It could be improved a bit by using the trapezoidal or Simpson&#8217;s Rule.    I second the AD suggestion,  obviously. <img src='http://iam.elbenshira.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>@Jake McArthur and jberryman:   very erudite comments.   One big thing about learning Haskell well is learning when there will be thunks versus when concrete values will be produced.</p>
<p>Basically,  common situations where evaluation will be forced,  avoiding the creation of thunks,  is on conditional branches,  pattern matching,  and uses of &#8220;seq&#8221; and friends.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Leon Smith</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-10</link>
		<dc:creator>Leon Smith</dc:creator>
		<pubDate>Fri, 10 Apr 2009 03:51:15 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-10</guid>
		<description>Nicely done.  :-)  Part of me was hoping for something a little bit more:   you should take the time and effort to learn about Automatic Differentiation.   

You are spot-on when you say that it&#039;s important to understand how your compiler works.    I must admit,  Haskell is a challenging one in this regard,  but I have a reasonably good understanding at this point,  although my understanding of GHC pales in comparison to certain other compilers for other languages.    Keep at it!</description>
		<content:encoded><![CDATA[<p>Nicely done.  <img src='http://iam.elbenshira.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   Part of me was hoping for something a little bit more:   you should take the time and effort to learn about Automatic Differentiation.   </p>
<p>You are spot-on when you say that it&#8217;s important to understand how your compiler works.    I must admit,  Haskell is a challenging one in this regard,  but I have a reasonably good understanding at this point,  although my understanding of GHC pales in comparison to certain other compilers for other languages.    Keep at it!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jake McArthur</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-9</link>
		<dc:creator>Jake McArthur</dc:creator>
		<pubDate>Fri, 10 Apr 2009 03:32:28 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-9</guid>
		<description>Your sum parameter accumulates thunks because you don&#039;t need it until the end. That is, for each recursive call, it might grow something like this:

0
0+(f 0)*0.0001
0+(f 0)*0.0001+(f 0.0001)*0.0001
0+(f 0)*0.0001+(f 0.0001)*0.0001+(f 0.0002)*0.0001
0+(f 0)*0.0001+(f 0.0001)*0.0001+(f 0.0002)*0.0001+(f 0.0003)*0.0001
0+(f 0)*0.0001+(f 0.0001)*0.0001+(f 0.0002)*0.0001+(f 0.0003)*0.0001+(f 0.0004)*0.0001

and so on. This is what overflows your stack. (Notice the similarities to a function that is not tail recursive!)

There are ways to avoid this problem, but since GHC&#039;s strictness analyzer can tell what&#039;s going on anyway it&#039;s easiest to just use optimizations.</description>
		<content:encoded><![CDATA[<p>Your sum parameter accumulates thunks because you don&#8217;t need it until the end. That is, for each recursive call, it might grow something like this:</p>
<p>0<br />
0+(f 0)*0.0001<br />
0+(f 0)*0.0001+(f 0.0001)*0.0001<br />
0+(f 0)*0.0001+(f 0.0001)*0.0001+(f 0.0002)*0.0001<br />
0+(f 0)*0.0001+(f 0.0001)*0.0001+(f 0.0002)*0.0001+(f 0.0003)*0.0001<br />
0+(f 0)*0.0001+(f 0.0001)*0.0001+(f 0.0002)*0.0001+(f 0.0003)*0.0001+(f 0.0004)*0.0001</p>
<p>and so on. This is what overflows your stack. (Notice the similarities to a function that is not tail recursive!)</p>
<p>There are ways to avoid this problem, but since GHC&#8217;s strictness analyzer can tell what&#8217;s going on anyway it&#8217;s easiest to just use optimizations.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: jberryman</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-8</link>
		<dc:creator>jberryman</dc:creator>
		<pubDate>Fri, 10 Apr 2009 00:46:40 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-8</guid>
		<description>@Elben Shira: what Jake M means is that the compiler only evaluates the &#039;x&#039; and &#039;b&#039; parameters with each iteration because it has to in order to perform the comparison and continue the computation. The other parameters aren&#039;t evaluated at all until the very end because you haven&#039;t needed to evaluate them! So they exist as &#039;thunks&#039; (a computation that has yet to be evaluated). Look at &lt;code&gt;seq&lt;/code&gt; to add strictness.</description>
		<content:encoded><![CDATA[<p>@Elben Shira: what Jake M means is that the compiler only evaluates the &#8216;x&#8217; and &#8216;b&#8217; parameters with each iteration because it has to in order to perform the comparison and continue the computation. The other parameters aren&#8217;t evaluated at all until the very end because you haven&#8217;t needed to evaluate them! So they exist as &#8216;thunks&#8217; (a computation that has yet to be evaluated). Look at <code>seq</code> to add strictness.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Elben Shira</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-7</link>
		<dc:creator>Elben Shira</dc:creator>
		<pubDate>Fri, 10 Apr 2009 00:08:42 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-7</guid>
		<description>@Jake McArthur: you are right, my ignorance is the problem, not GHC, but I&#039;m not sure what you mean by &quot;the other parameters are not forced until the end.&quot; Can you provide an example?</description>
		<content:encoded><![CDATA[<p>@Jake McArthur: you are right, my ignorance is the problem, not GHC, but I&#8217;m not sure what you mean by &#8220;the other parameters are not forced until the end.&#8221; Can you provide an example?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Justin Grant</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-6</link>
		<dc:creator>Justin Grant</dc:creator>
		<pubDate>Thu, 09 Apr 2009 23:22:48 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-6</guid>
		<description>Your stack overflows are probably due to the code exceeding the limits in the Double type.

You may want to look at this in Lisp too. Here&#039;s the equivalent code in Lisp --&gt; http://jng.imagine27.com/articles/2009-04-09-161839_integral%20calculus_in_lisp.html

Lisp itself is really just a calculus too(lambda calculus) implemented as a programming language that has the same syntax. This lends well to many types of math coding. There is little to translate.</description>
		<content:encoded><![CDATA[<p>Your stack overflows are probably due to the code exceeding the limits in the Double type.</p>
<p>You may want to look at this in Lisp too. Here&#8217;s the equivalent code in Lisp &#8211;&gt; <a href="http://jng.imagine27.com/articles/2009-04-09-161839_integral%20calculus_in_lisp.html" rel="nofollow">http://jng.imagine27.com/articles/2009-04-09-161839_integral%20calculus_in_lisp.html</a></p>
<p>Lisp itself is really just a calculus too(lambda calculus) implemented as a programming language that has the same syntax. This lends well to many types of math coding. There is little to translate.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jake McArthur</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-5</link>
		<dc:creator>Jake McArthur</dc:creator>
		<pubDate>Thu, 09 Apr 2009 22:14:55 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-5</guid>
		<description>&quot;Thinking about and writing programs recursively may be more elegant and easier to understand, but then we are putting our trust on the compiler for optimizations, which is scary if we don’t understand how the compiler works.&quot;

This is a common misconception for newbies to the language. In reality, we aren&#039;t really putting any trust in the compiler to perform certain optimizations. It&#039;s just a matter of understanding Haskell&#039;s evaluation model.

In this case, you believed that making a function tail recursive should prevent stack overflows, but you didn&#039;t realize that laziness can play a factor here. The guards in your integrateGen function only force two parameters to evaluate. The other parameters are not forced until the very end. Without realizing, you have defeated the purpose of tail recursion by creating a long chain of unevaluated thunks instead of accumulating a result as you go, a stack overflow.

The reason that optimizations fixed this is because GHC&#039;s strictness analyzer figured out that the result will always be evaluted at the end anyway, so it causes the binary to go ahead and evaluate it earlier.</description>
		<content:encoded><![CDATA[<p>&#8220;Thinking about and writing programs recursively may be more elegant and easier to understand, but then we are putting our trust on the compiler for optimizations, which is scary if we don’t understand how the compiler works.&#8221;</p>
<p>This is a common misconception for newbies to the language. In reality, we aren&#8217;t really putting any trust in the compiler to perform certain optimizations. It&#8217;s just a matter of understanding Haskell&#8217;s evaluation model.</p>
<p>In this case, you believed that making a function tail recursive should prevent stack overflows, but you didn&#8217;t realize that laziness can play a factor here. The guards in your integrateGen function only force two parameters to evaluate. The other parameters are not forced until the very end. Without realizing, you have defeated the purpose of tail recursion by creating a long chain of unevaluated thunks instead of accumulating a result as you go, a stack overflow.</p>
<p>The reason that optimizations fixed this is because GHC&#8217;s strictness analyzer figured out that the result will always be evaluted at the end anyway, so it causes the binary to go ahead and evaluate it earlier.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joe Fredette (jfredett)</title>
		<link>http://iam.elbenshira.com/archives/151_integral-calculus-in-haskell/comment-page-1/#comment-4</link>
		<dc:creator>Joe Fredette (jfredett)</dc:creator>
		<pubDate>Thu, 09 Apr 2009 21:57:17 +0000</pubDate>
		<guid isPermaLink="false">http://iam.elbenshira.com/?p=151#comment-4</guid>
		<description>Nifty, you might try using Haskell&#039;s Algebraic datatypes to do some kind of symbolic integration, since if you could lift basic math operations into some kind of datatype, then integration symbolically ought to become a series of pattern matches which break down an equation and apply basic rules. 

You might also be interested in Conal Elliot&#039;s Automatic Differentiation stuff, it&#039;s on his blog, some others have done Computer-Algebra type stuff. 

Very neat!</description>
		<content:encoded><![CDATA[<p>Nifty, you might try using Haskell&#8217;s Algebraic datatypes to do some kind of symbolic integration, since if you could lift basic math operations into some kind of datatype, then integration symbolically ought to become a series of pattern matches which break down an equation and apply basic rules. </p>
<p>You might also be interested in Conal Elliot&#8217;s Automatic Differentiation stuff, it&#8217;s on his blog, some others have done Computer-Algebra type stuff. </p>
<p>Very neat!</p>
]]></content:encoded>
	</item>
</channel>
</rss>

