<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Conal Elliott &#187; puzzle</title>
	<atom:link href="http://conal.net/blog/tag/puzzle/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Thu, 25 Jul 2019 18:15:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2F&amp;language=en_US&amp;category=text&amp;title=Conal+Elliott&amp;description=Inspirations+%26amp%3B+experiments%2C+mainly+about+denotative%2Ffunctional+programming+in+Haskell&amp;tags=blog" type="text/html" />
	<item>
		<title>Lazier functional programming, part 2</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-2</link>
		<comments>http://conal.net/blog/posts/lazier-functional-programming-part-2#comments</comments>
		<pubDate>Sun, 19 Sep 2010 19:34:42 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[non-strictness]]></category>
		<category><![CDATA[puzzle]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=194</guid>
		<description><![CDATA[In Lazier functional programming, part 1, I suggested that some of the standard tools of lazy functional programming are not as lazy as they might be, including even if-then-else. Generalizing from boolean conditionals, I posed the puzzle of how to define a lazier either function, which encapsulates case analysis for sum types. The standard definition: [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Lazier functional programming, part 2

Tags: non-strictness, puzzle

URL: http://conal.net/blog/posts/lazier-functional-programming-part-2/

-->

<!-- references -->

<!-- teaser -->

<p>In <em><a href="http://conal.net/blog/posts/lazier-functional-programming-part-1/" title="blog post">Lazier functional programming, part 1</a></em>, I suggested that some of the standard tools of lazy functional programming are not as lazy as they might be, including even <code>if-then-else</code>.
Generalizing from boolean conditionals, I posed the puzzle of how to define a lazier <code>either</code> function, which encapsulates case analysis for sum types.
The standard definition:</p>

<pre><code>data Either a b = Left a | Right b

either :: (a → c) → (b → c) → Either a b → c
either f g (Left  x) = f x
either f g (Right y) = g y
</code></pre>

<p>The <a href="http://conal.net/blog/posts/lazier-functional-programming-part-1#comments" title="blog post comments">comments to part 1</a> fairly quickly converged to something close to the laxer definition I had in mind:</p>

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

<p>which is a simple generalization of <a href="http://lukepalmer.wordpress.com/" title="Luke Palmer's blog">Luke Palmer</a>&#8216;s laxer if-then-else (reconstructed from memory):</p>

<pre><code>bool c a b = (a ⊓ b) ⊔ (if c then a else b)
</code></pre>

<!--
**Edits**:

* 2010-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-194"></span></p>

<p>My thanks to <a href="http://conal.net/blog/posts/lazier-functional-programming-part-1/#comment-57228">Dave</a> for &#8220;laxer&#8221; as a denotational alternative to the operational term &#8220;lazier&#8221;.</p>

<p>Note in the <code>either</code> definition that the argument ordering allows computing <code>(f ⊥ ⊓ g ⊥)</code> just once and reusing the result for different values of the third argument.
Similarly,</p>

<pre><code>cond :: a → a → Bool → a
cond a b = const (a ⊓ b) ⊔ (λ c → if c then a else b)
</code></pre>

<p>Let&#8217;s look at some examples:</p>

<pre><code>cond 6 8 ⊥ ≡ (6 ⊓ 8) ⊔ ⊥ ≡ 6 ⊓ 8 ≡ ⊥

cond 7 7 ⊥ ≡ (7 ⊓ 7) ⊔ ⊥ ≡ 7 ⊓ 7 ≡ 7

cond (3,4) (4,5) ⊥ ≡ ((3,4) ⊓ (4,5)) ⊔ ⊥ ≡ (⊥,⊥)

cond (3,4) (3,5) ⊥ ≡ ((3,4) ⊓ (3,5)) ⊔ ⊥ ≡ (3,⊥)

cond [2,3,5] [1,3] ⊥ ≡ ([2,3,5] ⊓ [1,3]) ⊔ ⊥ ≡ ⊥ : 3 : ⊥
</code></pre>

<p>These results are more useful than they might at first appear.
Monotonicity implies that the following information-inequalities also hold for an <em>arbitrary</em> boolean <code>c</code>:</p>

<pre><code>cond 6 8 c ⊒ ⊥
cond 7 7 c ⊒ 7
cond (3,4) (4,5) c ⊒ (⊥,⊥)
cond (3,4) (3,5) c ⊒ (3,⊥)
cond [2,3,5] [1,3] c ⊒ (⊥ : 3 : ⊥)
</code></pre>

<p>In other words, given only <code>a</code> and <code>b</code>, we can already start extracting some information about the value of <code>cond a b c</code>.
If <code>c</code> takes a long time to compute (forever in the extreme case), we may be able to get some useful information out of <code>cond</code> before <code>cond</code> gets any information out of <code>c</code>.
Moreover, the presence of &#8220;⊔&#8221; hints at parallelization.
Evaluation of <code>a ⊓ b</code> can proceed in one thread, while another computes the standard conditional.</p>

<p>At the function level,</p>

<pre><code>cond 6 8 ⊒ const ⊥
cond 7 7 ⊒ const 7
cond (3,4) (4,5) ⊒ const (⊥,⊥)
cond (3,4) (3,5) ⊒ const (3,⊥)
cond [2,3,5] [1,3] ⊒ const (⊥ : 3 : ⊥)
</code></pre>

<p>This observation is handy when <code>cond</code> is partially applied to two arguments and the resulting function is reused.
We can even compute <code>a ⊓ b</code> once and share the results among many calls.</p>

<p>These same considerations apply more generally to the laxer <code>either</code> definition above.</p>

<p>Does the definition of <code>either</code> above really satisfy the conditions of the puzzle, and how did I come up with it?
A key insight is that monotonicity implies the following two inequalities for all <code>a</code> and <code>b</code>:</p>

<pre><code>eitherL f g ⊥ ⊑ eitherL f g (Left  a)
eitherL f g ⊥ ⊑ eitherL f g (Right b)
</code></pre>

<p>Consistency with the defining equations then imply that</p>

<pre><code>eitherL f g (Left  a) ≡ f a
eitherL f g (Right b) ≡ g b
</code></pre>

<p>so</p>

<pre><code>eitherL f g ⊥ ⊑ f a
eitherL f g ⊥ ⊑ g b
</code></pre>

<p>and hence</p>

<pre><code>eitherL f g ⊥ ⊑ f a ⊓ g b
</code></pre>

<p>Specializing to <code>a ≡ b ≡ ⊥</code> gives us an single <em>least</em> of these upper bounds:</p>

<pre><code>eitherL f g ⊥ ⊑ f ⊥ ⊓ g ⊥
</code></pre>

<p>similarly to Albert&#8217;s reasoning for the similar case of <code>if-then-else</code>.</p>

<p>I asked for a information-<em>maximal</em> version of <code>eitherL</code> so as to get as much information out with as little information in, in the spirit of lax (non-strict) functional programming.
For the maximal version, choose equality:</p>

<pre><code>eitherL f g ⊥ ≡ f ⊥ ⊓ g ⊥
</code></pre>

<p>There are three fairly simple proofs remaining, namely that (a) this equality holds for the definition of <code>eitherL</code> above, (b) the use of (⊔) is legitimate in that definition, and (c) the definition as a whole is consistent with the defining equations.</p>

<p>Finally, note that lub (⊔) is used in a restricted way here.
In this use <code>u ⊔ v</code>, not only are the arguments <code>u</code> and <code>v</code> information-compatible (the semantic pre-condition of lub), but also, <code>u ⊑ v</code>.
This property shows up in several applications of lub, and I suspect it can be useful in efficient implementation.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=194&amp;md5=cbbd939393868e2b2a71aff945476105"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/lazier-functional-programming-part-2/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Flazier-functional-programming-part-2&amp;language=en_GB&amp;category=text&amp;title=Lazier+functional+programming%2C+part+2&amp;description=In+Lazier+functional+programming%2C+part+1%2C+I+suggested+that+some+of+the+standard+tools+of+lazy+functional+programming+are+not+as+lazy+as+they+might+be%2C+including+even+if-then-else.+Generalizing...&amp;tags=non-strictness%2Cpuzzle%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Lazier functional programming, part 1</title>
		<link>http://conal.net/blog/posts/lazier-functional-programming-part-1</link>
		<comments>http://conal.net/blog/posts/lazier-functional-programming-part-1#comments</comments>
		<pubDate>Sun, 12 Sep 2010 00:57:43 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[non-strictness]]></category>
		<category><![CDATA[puzzle]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=190</guid>
		<description><![CDATA[This post is inspired by a delightful insight from Luke Palmer. I&#8217;ll begin with some motivation, and then propose a puzzle. Consider the following definition of our familiar conditional: ifThenElse :: Bool → a → a → a ifThenElse True t f = t ifThenElse False t f = f In a strict language, where [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- 

Title: Lazier functional programming, part 1

Tags: non-strictness, puzzle

URL: http://conal.net/blog/posts/lazier-functional-programming-part-1/

-->

<!-- references -->

<!-- teaser -->

<p>This post is inspired by a delightful insight from <a href="http://lukepalmer.wordpress.com/" title="Luke Palmer's blog">Luke Palmer</a>.
I&#8217;ll begin with some motivation, and then propose a puzzle.</p>

<p>Consider the following definition of our familiar conditional:</p>

<pre><code>ifThenElse :: Bool → a → a → a
ifThenElse True  t f = t
ifThenElse False t f = f
</code></pre>

<p>In a strict language, where there are only two boolean values, these two clauses have a straightforward reading.
(The reading is less straightforward when patterns overlap, as mentioned in <em><a href="http://conal.net/blog/posts/lazier-function-definitions-by-merging-partial-values/" title="blog post">Lazier function definitions by merging partial values</a></em>.)
In a non-strict language like Haskell, there are <em>three</em> distinct boolean values, not two.
Besides <code>True</code> and <code>False</code>, <code>Bool</code> also has a value ⊥, pronounced &#8220;bottom&#8221; for being at the bottom of the information ordering.
For an illustration and explanation of information ordering, see <em><a href="http://conal.net/blog/posts/merging-partial-values/" title="blog post">Merging partial values</a></em>.</p>

<p><em>Note:</em> In Haskell code, ⊥ is sometimes denoted by &#8220;<code>undefined</code>&#8220;, which can be confusing, because the meaning is defined precisely.
There are <em>many</em> other ways to denote ⊥ in Haskell, and it is impossible to determine whether or not an arbitrary Haskell expression denotes ⊥.
I&#8217;ll generally use &#8220;⊥&#8221; in place of &#8220;<code>undefined</code>&#8221; in this post, as well as for the corresponding semantic value.</p>

<p>The two-clause definition above only addresses two of the three possible boolean values explicitly.
What, if anything, does it say <em>indirectly</em> about the meaning of an application like &#8220;<code>ifThenElse ⊥ 3 5</code>&#8220;?</p>

<p>The Haskell language standard gives an operational answer to this question.
Clauses are examined, using pattern matching to select a clause and instantiate that clause&#8217;s variables.
In case more than one clause matches, the earlier one is chosen.</p>

<p>Pattern matching has three possible outcomes:</p>

<ul>
<li>A single substitution, providing variable bindings that specialize the patterns in a clause&#8217;s left-hand side (LHS) to coincide with the actual call.  The matching uses semantic, not syntactic, equality and can require forcing evaluation of previously unevaluated thunks (delayed computations).</li>
<li>Proof of the nonexistence of such a substitution.</li>
<li>Neither conclusion, due to an error or nontermination during evaluation.</li>
</ul>

<p>In this example, the effort to match <code>True</code> against ⊥ leads to the third outcome.
For Haskell as currently defined, the result of the application in such a case is then defined to be ⊥ also.
Which is to say that <code>ifThenElse</code> is <em>strict</em> (in its first argument).</p>

<p>So strictness is the Haskell answer, but is it really the answer we want?
Are there alternatives that might better fit the spirit of non-strict functional programming?</p>

<!--
**Edits**:

* 2010-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-190"></span></p>

<p><em>Note:</em> Haskell is often referred to as a &#8220;lazy language&#8221;, while a more precise description is that Haskell has non-strict semantics, typically with a <em>lazy</em> implementation.
I think of programming languages and libraries (at least ones I like using) as having a single semantics, amenable to various implementations.
(Haskell falls somewhat short, as explained in <em><a href="http://conal.net/blog/posts/notions-of-purity-in-haskell/" title="blog post">Notions of purity in Haskell</a></em>.)
Sadly, I don&#8217;t know a pleasant comparative form to mean &#8220;less strict&#8221;, so I&#8217;m using the more familiar term &#8220;lazier&#8221; in this post&#8217;s title.
Suggestions welcome.</p>

<h3>Sums</h3>

<p>Now consider a broader example, taken from the standard <a href="http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Prelude.html">Haskell prelude</a>, namely <a href="http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Prelude.html#t:Either">sum types</a> and corresponding <a href="http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Prelude.html#v:either">case analysis</a>:</p>

<pre><code>data Either a b = Left a | Right b

either :: (a → c) → (b → c) → Either a b → c
either f g (Left  x) = f x
either f g (Right y) = g y
</code></pre>

<p>Again, these two clauses have a clear and direct reading for strict languages, but in a non-strict language like Haskell, there is a third element of <code>Either a b</code> not explicitly addressed, namely ⊥.
Again, Haskell&#8217;s current definition says that <code>either f g ⊥ == ⊥</code>, i.e., <code>either f g</code> is always <em>strict</em>.</p>

<h3>Products</h3>

<p>Most types can be built up from sums and products.
Since we&#8217;ve looked at sums already, let&#8217;s now consider products.
And rather than n-ary products, just look at binary products and the unit type (a sort of nullary product).</p>

<pre><code>fu :: () → Int
fu () = 2

fp :: (a,b) → Int
fp (x,y) = 3
</code></pre>

<p>Again, these clauses only capture the non-⊥ part of their domains explicitly.
And again, the Haskell specification says that these functions are strict.</p>

<p>Here&#8217;s a less trivial example:</p>

<pre><code>q :: Bool → (Int,Int) → Int
q b (x,y) = if b then 3 else x
</code></pre>

<p>Haskell semantics says that <code>q True</code> is strict, rather than being equivalent to the non-strict function <code>const 3</code>.</p>

<h3>Lazier functional programming</h3>

<p>Given that we&#8217;re enjoying some of the benefits of a non-strict language and programming paradigm (as described, e.g., in <em><a href="http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html" title="Paper by John Hughes">Why Functional Programming Matters</a></em>), we might enjoy more if we can loosen up some of the strictness of pattern-based definitions.</p>

<p>What might a less-strict interpretation be?
Let&#8217;s take the definition of <code>either</code> above.</p>

<p>I&#8217;d require any interpretation to satisfy a two conditions:</p>

<ul>
<li>The meaning is consistent with the direct explicit readings of the clauses.
When read as equations, those clauses are <em>true</em> of the meaning of <code>either</code>.</li>
<li>The meaning of <code>either f g</code> must be <em>information-monotonic</em>, i.e., more information in leads to more (and consistent) information out.</li>
</ul>

<p>For an interpretation that is <em>ideal</em> for non-strict programming, I&#8217;ll add a third condition:</p>

<ul>
<li>Information-wise, the interpretation is <em>maximal</em> among all meanings that satisfy the first two conditions, i.e., it&#8217;s <em>minimally strict</em>.</li>
</ul>

<h3>A puzzle</h3>

<p>I&#8217;ll end this post with a puzzle: what is a minimally strict interpretation of the definition of <code>either</code> above?
Backing up,</p>

<ul>
<li>Is there a meaning for <code>either</code> that satisfies these three conditions?</li>
<li>If so, is there exactly one such meaning?</li>
<li>If so, what is that meaning, and how can it be obtained and implemented systematically?</li>
</ul>

<p>Edit: *Warning: spoilers ahead in the comments.  I encourage you to play with the puzzle on your own before reading on.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=190&amp;md5=eea4605160e2ad95fb294409c41ed71e"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/lazier-functional-programming-part-1/feed</wfw:commentRss>
		<slash:comments>21</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Flazier-functional-programming-part-1&amp;language=en_GB&amp;category=text&amp;title=Lazier+functional+programming%2C+part+1&amp;description=This+post+is+inspired+by+a+delightful+insight+from+Luke+Palmer.+I%26%238217%3Bll+begin+with+some+motivation%2C+and+then+propose+a+puzzle.+Consider+the+following+definition+of+our+familiar+conditional%3A+ifThenElse...&amp;tags=non-strictness%2Cpuzzle%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
