{"id":137,"date":"2006-08-30T08:33:54","date_gmt":"2006-08-30T08:33:54","guid":{"rendered":"http:\/\/scientopia.org\/blogs\/goodmath\/2006\/08\/30\/the-genius-of-alonzo-church-rerun\/"},"modified":"2006-08-30T08:33:54","modified_gmt":"2006-08-30T08:33:54","slug":"the-genius-of-alonzo-church-rerun","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2006\/08\/30\/the-genius-of-alonzo-church-rerun\/","title":{"rendered":"The Genius of Alonzo Church (rerun)"},"content":{"rendered":"<p>I&#8217;m on vacation this week, so I&#8217;m posting reruns of some of the better articles from when Goodmath\/Badmath was on Blogger. Todays is a combination of two short posts on numbers and control booleans in &lambda; calculus.<br \/>\nSo, now, time to move on to doing interesting stuff with lambda calculus. To<br \/>\nstart with, for convenience, I&#8217;ll introduce a bit of syntactic sugar to let us<br \/>\nname functions. This will make things easier to read as we get to complicated<br \/>\nstuff.<br \/>\nTo introduce a *global* function (that is a function that we&#8217;ll use throughout our lambda calculus introduction without including its declaration in every expression), we&#8217;ll use a definition like the following:<br \/>\n*square  &equiv; &lambda; x . x &times; x*<br \/>\nThis declares a function named &#8220;square&#8221;, whose definition is &#8220;*&lambda; x . x&times;x*&#8221;. If we had an expression &#8220;square 4&#8221;, the definition above means that it would effectively be treated as if the expression were: &#8220;*(&lambda; square . square 4)(&lambda; x . x&times;x)*&#8221;.<br \/>\nNumbers in Lambda Calculus<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\nIn some of the examples, I used numbers and arithmetic operations. But numbers don&#8217;t really exist in lambda calculus; all we really have are functions! So we need to invent some way of <em>creating<\/em> numbers using functions. Fortunately, Alonzo Church, the genius who invented the lambda calculus worked out how to do that. His version of numbers-as-functions are called <em>Church Numerals<\/em>.<br \/>\nIn Church numerals, all numbers are functions with two parameters:<br \/>\n* Zero &equiv; *&lambda; s z . z*<br \/>\n* One &equiv; *&lambda; s z . s z*<br \/>\n* Two &equiv; *&lambda; s z . s (s z)*<br \/>\n* Three &equiv; *&lambda; s z . s (s (s z))*<br \/>\n* Any natural number &#8220;n&#8221;, is represented by a Church numeral which is a function which applies its first parameter to its second parameter &#8220;n&#8221; times.<br \/>\nA good way of understanding this is to think of  &#8220;z&#8221; as being a a name for a zero-value, and &#8220;s&#8221; as a name for a successor function. So zero is a function which just returns the &#8220;0&#8221; value; one is a function which applies the successor function  once to zero; two is a function which applies successor to the successor of zero, etc. It&#8217;s just the Peano arithmetic definition of numbers transformed into lambda calculus.<br \/>\nBut the really cool thing is what comes next. If we want to do addition, x + y, we need to write a function with four parameters; the two numbers to add; and the &#8220;s&#8221; and &#8220;z&#8221; values we want in the resulting number:<br \/>\nadd &equiv; *&lambda; s z x y .  x s (y s z)*<br \/>\nLet&#8217;s curry that, to separate the two things that are going on. First, it&#8217;s taking two parameters which are the two values we need to add; second, it needs to normalize things so that the two values being added end up sharing the same binding of the zero and successor values.<br \/>\nadd_curry &equiv; &lambda; x y. (&lambda; s z . (x s (y s z)))<br \/>\nLook at that for a moment; what that says is, to add x and y: create the church numeral &#8220;y&#8221; using the parameters &#8220;s&#8221; and &#8220;z&#8221;. Then **apply x** to that new church numeral y. That is: a number is a function <em>which adds itself to another number<\/em>.<br \/>\nLet&#8217;s look a tad closer, and run through the evaluation of 2 + 3:<br \/>\nadd_curry (&lambda; s z . s (s z)) (&lambda; s z . s (s (s z)))<br \/>\nTo make things easier, let&#8217;s alpha 2 and 3, so that &#8220;2&#8221; uses &#8220;s2&#8221; and &#8220;z2&#8221;, and 3 uses &#8220;s3&#8221; and &#8220;z3&#8221;;<br \/>\nadd_curry  (&lambda; s2 z2 . s2 (s2 z2)) (&lambda; s3 z3 . s3 (s3 (s3 z3)))<br \/>\nNow, let&#8217;s do replace &#8220;add_curry&#8221; with its definition:<\/p>\n<p>(&lambda; x y .(&lambda; s z. (x s y s z))) (&lambda; s2 z2 . s2 (s2 z2)) (&lambda; s3 z3 . s3 (s3 (s3 z3)))<br \/>\nNow, let&#8217;s do a beta on add:<\/p>\n<p>&lambda; s z . (&lambda; s2 z2 . s2 (s2 z2)) s (&lambda; s3 z3 . s3 (s3 (s3 z3)) s z)<br \/>\nAnd now let&#8217;s beta the church numeral for three. This basically just &#8220;normalizes&#8221; three: it replaces the successor and zero function in the definition of  three with the successor and zero functions from the parameters to add.<br \/>\n&lambda; s z . (&lambda; s2 z2 . s2 (s2 z2)) s  (s (s (s z)))<br \/>\nNow.. Here comes the really neat part. Beta again, this time on the lambda for two. Look at what we&#8217;re going to be doing here: two is a function which takes two parameters: a successor function, and zero function. To add two and three, we&#8217;re using the successor function from add function; and we&#8217;re using the result of evaluating three *as the value of the zero!* for two:<br \/>\n&lambda; s z . s (s (s (s (s z))))<br \/>\nAnd we have our result: the church numeral for five!<br \/>\nChoice in Lambda Calculus<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\nNow that we have numbers in our Lambda calculus, there are only two things missing before we can express arbitrary computations: a way of expressing choice, and a way of expressing repetition. So now I&#8217;ll talk about booleans and choice; and then next post I&#8217;ll explain repetition and recursion.<br \/>\nWe&#8217;d like to be able to write choices as if\/then\/else expressions, like we have in most programming languages. Following the basic pattern of the church numerals, where a number is expressed as a function that adds itself to another number, we&#8217;ll express true and false values as functions that perform  an if-then-else operation on their parameters. These are sometimes called *Church booleans*. (Of course, also invented by Alonzo Church.)<br \/>\n* TRUE &equiv; &lambda; t f . t<br \/>\n*  FALSE &equiv; &lambda; t f . f<br \/>\nSo, now we can write an &#8220;if&#8221; function, whose first parameter is a condition expression, second parameter is the expression to evaluate if the condition was true, and third parameter is the expression to evaluate if the condition  is false.<br \/>\n* IfThenElse &equiv; *&lambda; cond t f . cond t f*<br \/>\nFor the boolean values to be useful, we also need to be able to do the usual logical operations:<br \/>\n* BoolAnd &equiv; *&lambda; x y .x y FALSE*<br \/>\n* BoolOr &equiv; *&lambda; x y. x TRUE y*<br \/>\n* BoolNot &equiv; *&lambda; x . x FALSE TRUE*<\/p>\n<p>Now, let&#8217;s just walk through those a bit. Let&#8217;s first take a look at BoolAnd. We&#8217;ll try evaluating &#8220;*BoolAnd TRUE FALSE*&#8221;:<br \/>\n* Expand the TRUE and FALSE definitions: &#8220;*BoolAnd (&lambda; t f . t) (&lambda; t f . f)*&#8221;<br \/>\n* Alpha the true and false: &#8220;*BoolAnd (&lambda; tt tf . tt) (&lambda; ft ff . ff)*&#8221;<br \/>\n* Now, expand BoolAnd: *(&lambda; t f. t f FALSE) (&lambda; tt tf . tt) (&lambda; ft ff . ff)*<br \/>\n* And beta: *(&lambda; tt tf.tt) (&lambda; ft ff. ff) FALSE*<br \/>\n* Beta again: *(&lambda; xf yf . yf)*<br \/>\nAnd we have the result: *BoolAnd TRUE FALSE = FALSE*. Now let&#8217;s look at &#8220;*BoolAnd FALSE TRUE*&#8221;:<br \/>\n* *BoolAnd (&lambda; t f . f) (&lambda; t f .t)*<br \/>\n* Alpha: *BoolAnd (&lambda; ft ff . ff) (&lambda; tt tf . tt)*<br \/>\n* Expand BoolAnd: *(&lambda; x y .x y FALSE) (lambda ft ff . ff) (lambda tt  tf . tt)*<br \/>\n* Beta: *(&lambda; ft ff . ff) (lambda tt tf . tt) FALSE<\/code><br \/>\n* Beta again: FALSE<br \/>\nSo *BoolAnd FALSE TRUE = FALSE*. Finally, *BoolAnd TRUE TRUE*:<br \/>\n* Expand the two trues: *BoolAnd (&lambda; t f . t) (&lambda; t f . t)*<br \/>\n* Alpha: *BoolAnd (&lambda; xt xf . xt) (&lambda; yt yf . yt)*<br \/>\n* Expand BoolAnd: *(&lambda; x y . x y FALSE) (&lambda; xt xf . xt) (&lambda; yt yf . yt)*<br \/>\n* Beta: *(&lambda; xt xf . xt) (&lambda; yt yf . yt) FALSE*<br \/>\n* Beta: (&lambda;  yt  yf . yt)<\/code><br \/>\nSo *BoolAnd TRUE TRUE = TRUE*.<br \/>\nThe other booleans work in much the same way.<br \/>\nSo by the genius of Alonzo church, we have *almost* everything we need in order to write programs in &lambda; calculus.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m on vacation this week, so I&#8217;m posting reruns of some of the better articles from when Goodmath\/Badmath was on Blogger. Todays is a combination of two short posts on numbers and control booleans in &lambda; calculus. So, now, time to move on to doing interesting stuff with lambda calculus. To start with, for convenience, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[24,32],"tags":[],"class_list":["post-137","post","type-post","status-publish","format-standard","hentry","category-goodmath","category-lambda-calculus"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4lzZS-2d","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/137","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=137"}],"version-history":[{"count":0,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/137\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=137"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}