<?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:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>briancarper.net (λ) (Tag: Lambda Calculus)</title><link>http://briancarper.net/tag/50/lambda-calculus</link><description>Some guy's blog about programming and Linux and cows.</description><item><title>Church Numerals in Clojure</title><link>http://briancarper.net/blog/church-numerals-in-clojure</link><guid>http://briancarper.net/blog/church-numerals-in-clojure</guid><pubDate>Wed, 16 Sep 2009 02:14:30 -0700</pubDate><description>&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Church_numerals&quot;&gt;Church Numerals&lt;/a&gt; are a way of encoding natural numbers using lambda expressions.  A number &lt;code&gt;n&lt;/code&gt; is represented by a function that composes another function &lt;code&gt;f&lt;/code&gt; around its argument &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;n&lt;/code&gt; times.  So:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;0 ≡ λf.λx. x
1 ≡ λf.λx. f x
2 ≡ λf.λx. f (f x)
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These can be implemented very easily in Lisps and other languages with first-class functions.  In Clojure, this would be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;0 ≡ (fn [f] (fn [x] x))
1 ≡ (fn [f] (fn [x] (f x)))
2 ≡ (fn [f] (fn [x] (f (f x))))
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The insane thing is that you can do arithmetic on these things using nothing but more anonymous functions.  It's lambdas all the way down.  &lt;/p&gt;

&lt;p&gt;Once you understand this, your brain will explode, and hopefully little bits of it will land next to the remnants of my own brain to keep it company.&lt;/p&gt;

&lt;p&gt;So based on the Wikipedia article, here are some functions that convert numbers to and from Church encoding, and then some functions to do basic arithmetic on Church numerals.  I understand this down to &lt;code&gt;exp&lt;/code&gt; (via lots of pencil and paper expansions) but I gave up understanding at &lt;code&gt;pred&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defn church
  &quot;Convert a natural number to a Church numeral.&quot;
  [n]
  (loop [n n, acc (fn [f] (fn [x] x))]
    (if (zero? n)
      acc
      (recur (dec n)
             (fn [f]
               (fn [x]
                 (f ((acc f) x))))))))

(defn unchurch
  &quot;Convert a Church numeral to a plain integer.&quot;
  [n]
  ((n inc) 0))


(def plus
     (fn [m]
       (fn [n]
         (fn [f]
           (fn [x]
             ((m f) ((n f) x)))))))

(def mult 
     (fn [m]
       (fn [n]
         (fn [f]
          (n (m f))))))

(def exp
     (fn [m]
       (fn [n]
         (n m))))

(defn pred [n]
  (fn [f]
    (fn [x]
      (((n (fn [g]
             (fn [h]
               (h (g f)))))
        (fn [u] x))
       (fn [u] u)))))

(def sub
     (fn [m]
       (fn [n]
         ((n pred) m))))

(def is-zero?
     (fn [n]
       ((n (fn [x] 'FALSE)) 'TRUE)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And this somehow actually works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;user&amp;gt; (unchurch (fn [f] (fn [x] (f (f (f (f (f (f (f x))))))))))
7
user&amp;gt; (unchurch (church 7))
7
user&amp;gt; (unchurch ((plus (church 2)) (church 3)))
5
user&amp;gt; (unchurch ((mult (church 2)) (church 3)))
6
user&amp;gt; (unchurch ((exp (church 2)) (church 3)))
8
user&amp;gt; (unchurch ((sub (church 7)) (church 3)))
4
user&amp;gt; (is-zero? (church 0))
TRUE
user&amp;gt; (is-zero? (church 7))
FALSE
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the kind of thing I wish I'd studied more in college.  I covered some cool stuff, some small amount of theory of computation and whatnot, but not nearly enough of this.  Not enough functional programming, not enough Lispy goodness.&lt;/p&gt;

&lt;p&gt;A lot of people say all programmers should learn assembler language so you understand what's happening at a low level.  But shouldn't it be just as important to learn lambda calculus?  It's another kind of low level, a very important one at that.&lt;/p&gt;</description></item></channel></rss>

