<?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>LAMBDAPHONE &#187; LambdaCalculus</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/lambdacalculus/feed/" rel="self" type="application/rss+xml" />
	<link>http://coder.bsimmons.name/blog</link>
	<description>fragmentary ideas  ䷿  intellectual what-nots  ䷷  and haskell programming  ䷴</description>
	<lastBuildDate>Sun, 29 Jan 2012 17:24:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Do Applicative Functors generalize the S &amp; K Combinators?</title>
		<link>http://coder.bsimmons.name/blog/2011/01/do-applicative-functors-generalize-the-s-k-combinators/</link>
		<comments>http://coder.bsimmons.name/blog/2011/01/do-applicative-functors-generalize-the-s-k-combinators/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 17:44:02 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[Applicative]]></category>
		<category><![CDATA[combinator]]></category>
		<category><![CDATA[LambdaCalculus]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[theory]]></category>
		<category><![CDATA[TypeSystem]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=519</guid>
		<description><![CDATA[<p>If the title hasn't scared you off yet, here's the story: I was hacking on someone else's <a href="http://hackage.haskell.org/package/fclabels-0.11.1.1">code</a> on the plane and trying to wrap my head around some <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Applicative.html#t:Applicative"><code>Applicative</code> class</a> code; in particular the code in question&#8230; <a href="http://coder.bsimmons.name/blog/2011/01/do-applicative-functors-generalize-the-s-k-combinators/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>If the title hasn't scared you off yet, here's the story: I was hacking on someone else's <a href="http://hackage.haskell.org/package/fclabels-0.11.1.1">code</a> on the plane and trying to wrap my head around some <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Applicative.html#t:Applicative"><code>Applicative</code> class</a> code; in particular the code in question used the Applicative instance for ((->) a) i.e. functions. This turned my brain to cream-of-wheat and I had to take a break.</p>
<p>If you aren't familiar with <strong>Applicative Functors</strong>, they are somewhere in between the familiar and simple <code>Functor</code> class and the <code>Monad</code> class; an abstraction for function application with a context. Check out <a href="http://www.haskell.org/haskellwiki/Applicative_functor">here</a> for more.<br />
<span id="more-519"></span><br />
Away from the computer I got out a pad of paper and went about trying to figure out how the <code>< *></code> method was defined over functions. Here are the types:</p>
<blockquote><p><em>The polymorphic type:</em><br />
<code>(< *>) :: (Applicative f) => f (a -> b) -> f a -> f b </code></p>
<p><em>Substitute <code>(x -> ...)</code> for <code>f</code> to get the type for the functions instance:</em><br />
<code>(< *>) :: (x -> a -> b) -> (x -> a) -> (x -> b)</code> </p></blockquote>
<p>You can try defining the instance from the type definition; there seems to be only one sensical way. When I did it I was struck by something: the definition for the function above <em>is the same as the S combinator in the SKI combinator calculus!</em></p>
<p>At that point I started looking for other connections to combinatory logic, and quickly noticed that <em>the class method pure was essentially the K combinator!</em>. Here is the actual instance definition:</p>
<blockquote><pre>instance Applicative ((->) a) where
        pure = const
        (< *>) f g x = f x (g x)</pre>
</blockquote>
<p>For those not familiar, the <strong>SK(I) Combinator Calculus</strong> is a formal system for modelling computation, much like the lambda calculus; one can express any computable function using only the three (actually only S and K are necessary) symbols and parentheses. I've written about and <a href="http://coder.bsimmons.name/blog/2010/09/designing-a-module-for-combinatory-logic-in-haskell/">implemented the combinator calculus</a>, and you can read more on the <a href="http://en.wikipedia.org/wiki/SKI_combinator_calculus">wikipedia page</a>.</p>
<h3>Exploring the Connection</h3>
<p>It's pretty astounding to me that the only two methods required to define an Applicative instance turn out to be sufficient (the details of haskell's type system aside) to define a complete combinator base, <em>capable of expressing any computable function.</em></p>
<p>At first I wondered whether this connection was the brainchild of some clever haskeller who defined the (->) instance, and therefore somewhat artificial. But it turns out that the definitions for <code>pure</code> and <code>(< *>)</code> fall out quit naturally from the type definitions. So naturally in fact that we can use <a href="http://hackage.haskell.org/package/djinn/">djinn</a> to automatically derive their definitions!:</p>
<blockquote><p><em>Djinn></em> ? (< *>) :: (x -> a -> b) -> (x -> a) -> (x -> b)<br />
(< *>) :: (x -> a -> b) -> (x -> a) -> x -> b<br />
(< *>) a b c = a c (b c)<br />
<em>Djinn></em> ? pure :: a -> (x -> a)<br />
pure :: a -> x -> a<br />
pure a _ = a
</p></blockquote>
<p>Observe how the function definitions above could have been pulled right from an explanation of the S and K combinators.</p>
<p>Now let's play with this in GHCi. We'll first define our S and K combinators as the Applicative methods (giving type hints to keep the typechecker happy), then define the I combinator in terms of S and K, then we'll express a Church numeral:</p>
<blockquote><p>
<em>Prelude></em><code> :m + Control.Applicative </code><br />
<em>Prelude Control.Applicative></em> <code>let s = (< *>) :: (x -> b -> c) -> (x -> b) -> (x -> c)</code><br />
<em>Prelude Control.Applicative></em><code> let k = pure :: a -> (x -> a)</code><br />
<em>Prelude Control.Applicative></em> <code>let i = s k k</code><br />
<em>Prelude Control.Applicative></em><br />
<em>Prelude Control.Applicative></em> <code>let two = s (s (k s) k) i</code><br />
<em>Prelude Control.Applicative></em><br />
<em>Prelude Control.Applicative></em> <code>two ('x':) []</code><br />
<strong>"xx"</strong></p></blockquote>
<p>In the last last line above we sort of "render" the church numeral by applying it to a function and value that will construct a list; remember that church numerals represent integers as <em>n-fold function composition</em>; in the lambda calculus the numerical represenatations are more straightforward: <code>two = \f x-> f (f x)</code>, but the idea is the same.</p>
<h3>Conclusion</h3>
<p>It makes a lot of sense that a general type class meant to aid programming in an "applicative" style would have some similarity with the combinator calculus (in which <em>even data</em> is function application), but I thought it was pretty exciting to see such a fundamental computer science concept seemingly emerge naturally out of a library designed to solve a very high-level problem.</p>
<p><del datetime="2011-01-02T18:02:15+00:00">I have no idea whether these observations are novel or old and obvious</del>, but would love to hear from anyone who has any thoughts on this.</p>
<p><strong>EDIT:</strong> After taking a closer look at <a href="http://www.soi.city.ac.uk/~ross/papers/Applicative.html">Conor McBride and Ross Paterson's paper</a> on Applicative Functor's, I see now that he labels his ((->) a) instance methods with "S" and "K", but does not explore the subject further. So I'm leaning towards obvious.</p>
<p>Thanks for reading :)</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2011/01/do-applicative-functors-generalize-the-s-k-combinators/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>The Gift of Inconsistency</title>
		<link>http://coder.bsimmons.name/blog/2010/07/the-gift-of-inconsistency/</link>
		<comments>http://coder.bsimmons.name/blog/2010/07/the-gift-of-inconsistency/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 23:35:23 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[EsotericLanguages]]></category>
		<category><![CDATA[LambdaCalculus]]></category>
		<category><![CDATA[laziness]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[theory]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=453</guid>
		<description><![CDATA[<p>Computer science is a fascinating and maddening thing. Even the most seemingly-esoteric topics turn out to be fundamental. Go out to the fringes of CS and you find yourself smack in the middle of <a href="http://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems#Minds_and_machines">Philosophy</a>. You try to understand&#8230; <a href="http://coder.bsimmons.name/blog/2010/07/the-gift-of-inconsistency/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>Computer science is a fascinating and maddening thing. Even the most seemingly-esoteric topics turn out to be fundamental. Go out to the fringes of CS and you find yourself smack in the middle of <a href="http://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems#Minds_and_machines">Philosophy</a>. You try to understand a single point and you suddenly find yourself embracing everything. </p>
<p>So this post comes from that infinitely-recursive rabbit hole of wikipedia topics I&#8217;ve been falling down for the last few weeks, and you can probably expect a few more like this one; I&#8217;ll try to keep focused.</p>
<p>We begin (as do All Good Things) with the <a href="http://en.wikipedia.org/wiki/Untyped_lambda_calculus">Untyped Lambda Calculus</a>:<br />
<span id="more-453"></span></p>
<h2>The System</h2>
<p>The lambda calculus, invented by <a href="http://en.wikipedia.org/wiki/Alonzo_Church">Alonzo Church</a>, is a formal system for modeling functional computation and logic. It has an extraordinarily simple set of semantics, has no notion of data as a separate idea, and yet (as was proven later) is Turing complete. It serves as the skeleton and sinew of the Lisp and Scheme programming languages.</p>
<p>At its invention it seems that the system sat right at the crossroads of formal logic, mathematics and computational theory and could embrace all three fields. But it quickly became apparent that there were apparent flaws with the Lambda Calculus as a universal system.</p>
<h2>The Paradox</h2>
<p>In 1935 it was shown that the lambda calculus was <em>logically inconsistent</em> by the <a href="http://en.wikipedia.org/wiki/Kleene%E2%80%93Rosser_paradox">Kleene–Rosser paradox</a>. The &#8220;paradox&#8221; is an apparently self-contradictory lambda expression, and goes like this:</p>
<p>We have a lambda calculus expression we will call <code>'k'</code>, which takes an argument, applies it to to itself, and negates (the ¬ symbol) the result (for some undefined, logical definition of &#8220;negate&#8221;). </p>
<blockquote><p>
k = λx.( ¬ (x x))
</p></blockquote>
<p>Okay, no problem. But look what happens when we apply the function <code>'k'</code> to itself:</p>
<blockquote><p>
k k = λx.( ¬ (x x)) k<br />
k k = ¬ (k k)
</p></blockquote>
<p>After we reduce the expression, we seem to be saying that <code>(k k)</code> is equal to the opposite of itself, a self-contradictory statement.</p>
<p>To address this apparent shortcoming of his system, Church went on to define a <a href="http://en.wikipedia.org/wiki/Simply_typed_lambda_calculus">typed lambda calculus</a>. This new system differentiated between function types and simple terms in order to disallow these kinds of problematic expressions.</p>
<p>But as with many paradoxes, this one was really an issue of perspective&#8230;</p>
<h2>The Foundation</h2>
<p>Church&#8217;s new &#8220;Simply Typed Lambda Calculus&#8221; had an interesting property that the untyped lambda calculus didn&#8217;t have: the <a href="http://en.wikipedia.org/wiki/Strongly_normalizing">normalization property</a>.</p>
<p>This more restricted version of the Lambda Calculus was &#8220;strongly normalizing&#8221;, meaning that any expression could be reduced to some <em>normal form</em> (i.e. a form that cannot be reduced further) through some sequence of rewrite/reduction steps. In programming terms, this means that every expression in the <em>typed</em> lambda calculus is <em>guaranteed to terminate</em>.</p>
<p>That sounds pretty damn useful until you realize that this interesting property also makes Church&#8217;s new typed version of his system <em>not Turing complete</em>! </p>
<p>To prove this is so, consider this: imagine you encoded a program in the typed lambda calculus; it searched for (and halted) when it found an integer that was greater than two, and was <em>not</em> the sum of two primes. </p>
<p>Merely being able to encode such a function would imply the function halted, thus disproving <a href="http://en.wikipedia.org/wiki/Goldbach%27s_conjecture">Goldbach&#8217;s conjecture</a>, one of the great open problems of mathematics. All without even needing to evaluate said expression! The function referred to is of course not expressible in the typed lambda calculus.</p>
<p>It turns out that an apparent logical contradiction was actual the essential secret to computation.</p>
<h3>Embracing Inconsistency</h3>
<p>When you think of the LC as a model of computation, rather than a framework for logical assertions, the Kleene–Rosser paradox becomes what we might call the &#8220;Kleene–Rosser useless function&#8221;. </p>
<p>Let&#8217;s go ahead and express a nearly identical paradox in <a href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29">haskell</a>:</p>
<blockquote><p>
k :: (Num a) => a<br />
k = negate k
</p></blockquote>
<p>Haskell has no notion of mutability, so what we are saying here is &#8220;k is the negation of itself&#8221;. No logical fallacies or great existential questions here, just an infinite loop (and not a very useful one)! </p>
<p>Let&#8217;s express another similar &#8220;paradox&#8221;, one we can actually <em>use</em>:</p>
<blockquote><p>
babble :: [ String ]<br />
babble = &#8220;blah&#8221; : babble
</p></blockquote>
<p>How can a list be equal to itself with an extra element added? Doesn&#8217;t that imply a paradox? Well I know the runtime isn&#8217;t swayed by that argument, producing an infinite stream of &#8220;blah&#8221;s. We can even <em>use</em> this stream because of haskell&#8217;s lazy evaluation strategy.</p>
<p>But note: it isn&#8217;t laziness that lets us get away with defining paradoxes; it just allows us to make use of some more blatant paradoxical expressions without them blowing up in our faces as soon as we call them.</p>
<h3>Conclusion and Further Thoughts</h3>
<p>Interestingly, there are quite a number of non-turing complete programming languages (or language subsets) that have been created both for theoretical purposes and for practical use. <a href="http://en.wikipedia.org/wiki/Charity_%28programming_language%29">Here</a> <a href="http://en.wikipedia.org/wiki/BlooP_and_FlooP">are</a> <a href="http://www-fp.cs.st-andrews.ac.uk/hume/index.shtml">a few</a>. They seem to owe their existence and usefulness to an environment of turing complete systems.</p>
<p>So does this mean that formal logic is Turing Incomplete? Let me know your thoughts, and please let me know if I harmed any knowledge in the making of this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/07/the-gift-of-inconsistency/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk
Database Caching 8/15 queries in 0.034 seconds using disk

Served from: coder.bsimmons.name @ 2012-02-05 12:26:17 -->
