<?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: Lazier functional programming, part 2</title>
	<atom:link href="http://conal.net/blog/posts/lazier-functional-programming-part-2/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog/posts/lazier-functional-programming-part-2</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Sat, 26 Sep 2020 21:06:12 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<item>
		<title>By: Douglas McClean</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-764</link>
		<dc:creator><![CDATA[Douglas McClean]]></dc:creator>
		<pubDate>Thu, 23 Dec 2010 01:03:01 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-764</guid>
		<description><![CDATA[&lt;p&gt;@Paul,
I thought so too at first, but now I think I understand why that isn&#039;t the case. If you alternate between taking steps to evaluate f &#092;bot and taking steps to evaluate g &#092;bot, one of three things will happen.&lt;/p&gt;

&lt;p&gt;Either the partial answers you start to get will differ at some point (in which case you are done), or you will get to the end of both without encountering a difference (in which case you are done), or you will keep evaluating forever (in which case the answer was &#092;bot anyway).&lt;/p&gt;

&lt;p&gt;(Is this the gist of it? Or am I missing a different reason?)&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>@Paul,
I thought so too at first, but now I think I understand why that isn&#8217;t the case. If you alternate between taking steps to evaluate f &#92;bot and taking steps to evaluate g &#92;bot, one of three things will happen.</p>

<p>Either the partial answers you start to get will differ at some point (in which case you are done), or you will get to the end of both without encountering a difference (in which case you are done), or you will keep evaluating forever (in which case the answer was &#92;bot anyway).</p>

<p>(Is this the gist of it? Or am I missing a different reason?)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-763</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Wed, 22 Sep 2010 20:24:27 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-763</guid>
		<description><![CDATA[&lt;p&gt;Make that &lt;em&gt;laxer&lt;/em&gt; &lt;code&gt;if-then-else&lt;/code&gt; and &lt;code&gt;either&lt;/code&gt;.  Just fixed module name.&lt;/p&gt;

&lt;p&gt;Thanks to Luke Palmer for the suggestion, via Twitter.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;luqui: &quot;@conal, lazier?  Not laxer?&quot;.&lt;/p&gt;
  
  &lt;p&gt;conal: @luqui For the module name?  &quot;Laxer&quot; would be more fitting than &quot;Lazier&quot;, wouldn&#039;t it?&lt;/p&gt;
  
  &lt;p&gt;luqui: @conal, well according to the motivating blog posts, yes. I&#039;m wondering why you went to the trouble to find a good term then didn&#039;t use it.&lt;/p&gt;
  
  &lt;p&gt;conal: @luqui simple reason: i forgot.  just fixed.  thanks!&lt;/p&gt;
&lt;/blockquote&gt;
]]></description>
		<content:encoded><![CDATA[<p>Make that <em>laxer</em> <code>if-then-else</code> and <code>either</code>.  Just fixed module name.</p>

<p>Thanks to Luke Palmer for the suggestion, via Twitter.</p>

<blockquote>
  <p>luqui: &#8220;@conal, lazier?  Not laxer?&#8221;.</p>
  
  <p>conal: @luqui For the module name?  &#8220;Laxer&#8221; would be more fitting than &#8220;Lazier&#8221;, wouldn&#8217;t it?</p>
  
  <p>luqui: @conal, well according to the motivating blog posts, yes. I&#8217;m wondering why you went to the trouble to find a good term then didn&#8217;t use it.</p>
  
  <p>conal: @luqui simple reason: i forgot.  just fixed.  thanks!</p>
</blockquote>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-762</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Wed, 22 Sep 2010 19:41:56 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-762</guid>
		<description><![CDATA[&lt;p&gt;The new version of the &lt;a href=&quot;http://hackage.haskell.org/package/lub&quot; rel=&quot;nofollow&quot;&gt;lub package&lt;/a&gt; has modules for glb and for lazier &#039;if-then-else&#039; and &#039;either&#039;.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>The new version of the <a href="http://hackage.haskell.org/package/lub" rel="nofollow">lub package</a> has modules for glb and for lazier &#8216;if-then-else&#8217; and &#8216;either&#8217;.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David Sankel</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-761</link>
		<dc:creator><![CDATA[David Sankel]]></dc:creator>
		<pubDate>Wed, 22 Sep 2010 17:42:50 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-761</guid>
		<description><![CDATA[&lt;p&gt;Thanks. That clears it up. For those interested, I&#039;ve asked &lt;a href=&quot;http://comments.gmane.org/gmane.comp.lang.haskell.cafe/81029&quot; rel=&quot;nofollow&quot;&gt;haskell-cafe&lt;/a&gt; for more information on that particular optimization.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Thanks. That clears it up. For those interested, I&#8217;ve asked <a href="http://comments.gmane.org/gmane.comp.lang.haskell.cafe/81029" rel="nofollow">haskell-cafe</a> for more information on that particular optimization.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-760</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Tue, 21 Sep 2010 22:28:46 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-760</guid>
		<description><![CDATA[&lt;p&gt;David:  Ah, thanks.  Now I get the ambiguity.  I&#039;ll try to clarify.&lt;/p&gt;

&lt;p&gt;Suppose you define &lt;code&gt;h = eitherL f g&lt;/code&gt; (for some functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt;), and then apply &lt;code&gt;h&lt;/code&gt; to several &lt;code&gt;Either&lt;/code&gt;-valued arguments.
Then under GHC or GHCi, the work of computing &lt;code&gt;f ⊥ ⊓ g ⊥&lt;/code&gt; will be done just once, not repeatedly.&lt;/p&gt;

&lt;p&gt;Now suppose instead that &lt;code&gt;eitherL&lt;/code&gt; were defined as&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;eitherL f g x = &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;f ⊥ ⊓ g ⊥&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; ⊔ &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;either&lt;/span&gt;&lt;/a&gt; f g x&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;and again, define &lt;code&gt;h = eitherL f g&lt;/code&gt; (for some functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt;).
In this case &lt;code&gt;f ⊥ ⊓ g ⊥&lt;/code&gt; will get redundantly computed every time h is applied, because it is expressed within the scope of the &quot;&lt;code&gt;λ x → ...&lt;/code&gt;&quot; (after desugaring).&lt;/p&gt;

&lt;p&gt;The same sort of operational difference holds between the two following denotationally-equivalent expressions:&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;const&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;nthPrime &lt;span style=&quot;color: red;&quot;&gt;100000&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;
&#160;
  _ -&gt; nthPrime &lt;span style=&quot;color: red;&quot;&gt;100000&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>David:  Ah, thanks.  Now I get the ambiguity.  I&#8217;ll try to clarify.</p>

<p>Suppose you define <code>h = eitherL f g</code> (for some functions <code>f</code> and <code>g</code>), and then apply <code>h</code> to several <code>Either</code>-valued arguments.
Then under GHC or GHCi, the work of computing <code>f ⊥ ⊓ g ⊥</code> will be done just once, not repeatedly.</p>

<p>Now suppose instead that <code>eitherL</code> were defined as</p>

<p><div>
<pre class="haskell">eitherL f g x = <span style="color: green;">&#40;</span>f ⊥ ⊓ g ⊥<span style="color: green;">&#41;</span> ⊔ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either" rel="nofollow"><span style="font-weight: bold;">either</span></a> f g x</pre>
</div></p>

<p>and again, define <code>h = eitherL f g</code> (for some functions <code>f</code> and <code>g</code>).
In this case <code>f ⊥ ⊓ g ⊥</code> will get redundantly computed every time h is applied, because it is expressed within the scope of the &#8220;<code>λ x → ...</code>&#8221; (after desugaring).</p>

<p>The same sort of operational difference holds between the two following denotationally-equivalent expressions:</p>

<p><div>
<pre class="haskell"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const" rel="nofollow"><span style="font-weight: bold;">const</span></a> <span style="color: green;">&#40;</span>nthPrime <span style="color: red;">100000</span><span style="color: green;">&#41;</span>
&nbsp;
  _ -&gt; nthPrime <span style="color: red;">100000</span></pre>
</div></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David Sankel</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-759</link>
		<dc:creator><![CDATA[David Sankel]]></dc:creator>
		<pubDate>Tue, 21 Sep 2010 18:30:45 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-759</guid>
		<description><![CDATA[&lt;p&gt;I guess the thing that&#039;s tripping me up is that I don&#039;t know what is being allowed to compute (who is computing?) in the sentence &quot;Note in the either definition that the argument ordering allows computing (f ⊥ ⊓ g ⊥) just once and reusing the result for different values of the third argument&quot;. Maybe the subject here is a Haskell interpreter with certain assumed optimizations (or lack of)?&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>I guess the thing that&#8217;s tripping me up is that I don&#8217;t know what is being allowed to compute (who is computing?) in the sentence &#8220;Note in the either definition that the argument ordering allows computing (f ⊥ ⊓ g ⊥) just once and reusing the result for different values of the third argument&#8221;. Maybe the subject here is a Haskell interpreter with certain assumed optimizations (or lack of)?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-758</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Tue, 21 Sep 2010 17:09:18 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-758</guid>
		<description><![CDATA[&lt;blockquote&gt;
  &lt;p&gt;Couldn&#039;t an evaluator easily detect ( f ⊥ ⊓ g ⊥ ) as a common subexpression in two different applications of eitherL&#039; f g?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What do you mean by an &quot;evaluator&quot; in this question?
Something that structurally analyzes and transforms thunks at run time?&lt;/p&gt;

&lt;p&gt;If you&#039;re asking about compilers, then my understanding is a compiler could perform the same code transformation that I applied, and that GHC intentionally does not, so as to avoid space leaks.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<blockquote>
  <p>Couldn&#8217;t an evaluator easily detect ( f ⊥ ⊓ g ⊥ ) as a common subexpression in two different applications of eitherL&#8217; f g?</p>
</blockquote>

<p>What do you mean by an &#8220;evaluator&#8221; in this question?
Something that structurally analyzes and transforms thunks at run time?</p>

<p>If you&#8217;re asking about compilers, then my understanding is a compiler could perform the same code transformation that I applied, and that GHC intentionally does not, so as to avoid space leaks.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David Sankel</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-757</link>
		<dc:creator><![CDATA[David Sankel]]></dc:creator>
		<pubDate>Tue, 21 Sep 2010 15:08:26 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-757</guid>
		<description><![CDATA[&lt;p&gt;Dimtar&#039;s implementation,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;eitherL&#039; f g x = ( f ⊥ ⊓ g ⊥ ) ⊔ either f g x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;, seems to generally have the same properties as your implementation.&lt;/p&gt;

&lt;p&gt;On the other hand, I&#039;m not certain if it &quot;allows computing ( f ⊥ ⊓ g ⊥ ) just once and reusing the result for different values of the third argument&quot;. Couldn&#039;t an evaluator easily detect ( f ⊥ ⊓ g ⊥ ) as a common subexpression in two different applications of &lt;code&gt;eitherL&#039; f g&lt;/code&gt;?&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Dimtar&#8217;s implementation,</p>

<pre><code>eitherL' f g x = ( f ⊥ ⊓ g ⊥ ) ⊔ either f g x
</code></pre>

<p></p>

<p>, seems to generally have the same properties as your implementation.</p>

<p>On the other hand, I&#8217;m not certain if it &#8220;allows computing ( f ⊥ ⊓ g ⊥ ) just once and reusing the result for different values of the third argument&#8221;. Couldn&#8217;t an evaluator easily detect ( f ⊥ ⊓ g ⊥ ) as a common subexpression in two different applications of <code>eitherL' f g</code>?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-756</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Mon, 20 Sep 2010 21:16:07 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-756</guid>
		<description><![CDATA[&lt;p&gt;Paul: No.  I meant the definitions in the post as actual, computable, ideal implementations, except that I left out some class constraints, which I&#039;ll add in an edit.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Paul: No.  I meant the definitions in the post as actual, computable, ideal implementations, except that I left out some class constraints, which I&#8217;ll add in an edit.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Brauner</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2#comment-755</link>
		<dc:creator><![CDATA[Paul Brauner]]></dc:creator>
		<pubDate>Mon, 20 Sep 2010 10:04:53 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=194#comment-755</guid>
		<description><![CDATA[&lt;p&gt;So, if I understand, the ideal version cannot be reached effectively without solving the halting problem. The best you can do is to approximate it as much as you want by choosing a timeout as long as you want on the computation of (f ⊥ ⊓ g ⊥). Am I right?&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>So, if I understand, the ideal version cannot be reached effectively without solving the halting problem. The best you can do is to approximate it as much as you want by choosing a timeout as long as you want on the computation of (f ⊥ ⊓ g ⊥). Am I right?</p>
]]></content:encoded>
	</item>
</channel>
</rss>
