{"id":427,"date":"2012-09-15T00:14:51","date_gmt":"2012-09-14T14:14:51","guid":{"rendered":"http:\/\/juliangamble.com\/blog\/?p=427"},"modified":"2013-12-27T10:56:23","modified_gmt":"2013-12-26T23:56:23","slug":"the-little-schemer-in-clojure-chapter-9-lambda-the-ultimate-deriving-the-y-combinator","status":"publish","type":"post","link":"https:\/\/juliangamble.com\/blog\/2012\/09\/15\/the-little-schemer-in-clojure-chapter-9-lambda-the-ultimate-deriving-the-y-combinator\/","title":{"rendered":"The Little Schemer in Clojure &#8211; Chapter 9 &#8211; Lambda The Ultimate (Deriving the Y-Combinator)"},"content":{"rendered":"<p><em>This is the ninth chapter of a series of posts about porting\u00a0<a href=\"http:\/\/www.ccs.neu.edu\/home\/matthias\/BTLS\/\">The Little Schemer<\/a>\u00a0to Clojure. You may wish to\u00a0<a href=\"http:\/\/juliangamble.com\/blog\/2012\/07\/20\/the-little-schemer-in-clojure\/\">read the intro<\/a>.<\/em><\/p>\n<p>So far we&#8217;ve covered\u00a0<a href=\"http:\/\/juliangamble.com\/blog\/2012\/07\/20\/the-little-schemer-in-clojure-chapter-1\/\">flat data structures<\/a>,\u00a0<a href=\"http:\/\/juliangamble.com\/blog\/2012\/07\/29\/the-little-schemer-in-clojure-chapter-2\/\">reading flat data structures<\/a>,\u00a0<a href=\"http:\/\/juliangamble.com\/blog\/2012\/08\/03\/the-little-schemer-in-clojure-chapter-3\/\">creating data structures<\/a>,\u00a0<a href=\"http:\/\/juliangamble.com\/blog\/2012\/08\/10\/the-little-schemer-in-clojure-chapter-4-numbers-games\/\">creating a numeric tower<\/a>, working with\u00a0<a href=\"http:\/\/juliangamble.com\/blog\/2012\/08\/17\/the-little-schemer-in-clojure-chapter-5-the-multichapter-chapter\/\">multiple occurrences of a match in the list<\/a>, \u00a0<a href=\"http:\/\/juliangamble.com\/blog\/2012\/08\/19\/the-little-schemer-in-clojure-chapter-6-oh-my-gawd-its-full-of-stars\/\">changing our functions to work with nested lists<\/a>,\u00a0<a href=\"http:\/\/juliangamble.com\/blog\/2012\/08\/31\/the-little-schemer-in-clojure-chapter-7-shadows\/\">building a numerical expression evaluator<\/a>\u00a0and <a href=\"http:\/\/juliangamble.com\/blog\/2012\/09\/07\/the-little-schemer-in-clojure-chapter-8-friends-and-relations\/\">performing analysis on sets and numeric functions<\/a>.<\/p>\n<p>This chapter is one of the high points of the whole book. You may have heard of Paul Graham&#8217;s VC fund, <a href=\"http:\/\/ycombinator.com\/\">YCombinator<\/a> &#8211; in this session we&#8217;ll not only explain the programming concept of the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Fixed-point_combinator#Y_combinator\">YCombinator<\/a> &#8211; we&#8217;ll derive it in Clojure.<\/p>\n<p>Ok &#8211; so before we get started &#8211; what is it? What is this YCombinator concept everyone is so excited about? Here goes. <em>The YCombinator is a way to do recursion in a language that doesn&#8217;t support recursion<\/em>. Instead recursion is defined as a set of rewrite rules.<\/p>\n<p>&#8220;What?&#8221; I hear you saying. &#8220;All the languages I use have recursion, is this just some old hack that people used in the 60&#8217;s before they had real languages? Why should I get excited about that?&#8221; Fair enough. On it&#8217;s own its utility is limited, but it becomes a conceptual building block for lazy functional data structures &#8211; which are one of the things that people get excited about in Clojure &#8211; and something we don&#8217;t see in curly brace languages.<\/p>\n<p>So anyway &#8211; let&#8217;s get started.<\/p>\n<p>We&#8217;ll start with the <code>rember-f<\/code> function. This takes a list of items, an addition atom and a comparison function. The point is to demonstrate passing functions around.<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n;demonstrating passing functions around\r\n(def rember-f\r\n  (fn &#x5B;test? a l]\r\n    (cond\r\n      (null? l) '()\r\n      true (cond\r\n             (test? (first l) a) (rest l)\r\n             true (cons (first l) (rember-f test? a (rest l)))))))\r\n\r\n(println (rember-f = '(pop corn) '(lemonade (pop corn) and (cake))))\r\n;\/\/=&gt;(lemonade and (cake))\r\n<\/pre>\n<p>So we passed in the equals function (<code>=<\/code>) and it was used to test equality with the other item passed in.<\/p>\n<p>Now we&#8217;ll rewrite the <code>rember-f<\/code> function to remove the second conditional:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def rember-f\r\n  (fn &#x5B;test? a l]\r\n    (cond\r\n      (null? l) '()\r\n      (test? (first l) a) (rest l)\r\n      true (cons (first l) (rember-f test? a (rest l))))))\r\n\r\n(println (rember-f = '(pop corn) '(lemonade (pop corn) and (cake))))\r\n;\/\/=&gt;(lemonade and (cake))\r\n<\/pre>\n<p>Now we&#8217;re going to start looking at writing functions to be curried. By currying we&#8217;re referring to the Mathematician <a href=\"http:\/\/en.wikipedia.org\/wiki\/Haskell_Curry\">Haskell Curry<\/a> &#8211; for whom this is named. The idea of currying a function is that you can pass in fewer than all the functions required for the function to execute, and still pass the result around as a function (now with fewer arguments).<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def eq?-c\r\n  (fn &#x5B;a]\r\n    (fn &#x5B;x]\r\n      (= x a))))\r\n\r\n(println (eq?-c 'lemonade))\r\n=&gt; (println (eq?-c 'lemonade))\r\n#&lt;Chapter9LambdaTheUltimate$eq_QMARK__c$fn__974 Chapter9LambdaTheUltimate$eq_QMARK__c$fn__974@2a2a2ae9&gt;\r\n(println ((eq?-c 'lemonade) 'coke))\r\n;\/\/=&gt; false\r\n(println ((eq?-c 'lemonade) 'lemonade))\r\n;\/\/=&gt; true\r\n\r\n(def eq?-salad (eq?-c 'salad))\r\n\r\n(println (eq?-salad 'tuna))\r\n;\/\/=&gt;false\r\n(println (eq?-salad 'salad))\r\n;\/\/=&gt;true\r\n\r\n<\/pre>\n<p>Ok &#8211; taking that principle to the next level &#8211; can we curry our <code>rember-f<\/code> function? Here goes:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def rember-f\r\n  (fn &#x5B;test?]\r\n    (fn &#x5B;a l]\r\n      (cond\r\n        (null? l) '()\r\n        (test? (first l) a) (rest l)\r\n        true (cons (first l) ((rember-f test?) a (rest l)))))))\r\n\r\n(println ((rember-f =) 'tuna '(tuna salad is good)))\r\n;\/\/=&gt;(salad is good)\r\n\r\n(def rember-eq? (rember-f =))\r\n(println (rember-eq? 'tuna '(tuna salad is good)))\r\n;\/\/=&gt;(salad is good)\r\n<\/pre>\n<p>That was so much fun, we&#8217;ll do it again with something similar, the <code>insertL-f<\/code> function.<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def insertL-f\r\n  (fn &#x5B;test?]\r\n    (fn &#x5B;new old l]\r\n      (cond\r\n        (null? l) '()\r\n        (test? (first l) old) (cons new (cons old (rest l)))\r\n        true (cons (first l) ((insertL-f test?) new old (rest l)))))))\r\n\r\n(println ((insertL-f =) 'creamy 'latte '(a hot cup of latte)))\r\n<\/pre>\n<p>One more time! Let&#8217;s look at <code>insertR-f<\/code>:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def insertR-f\r\n  (fn &#x5B;test?]\r\n    (fn &#x5B;new old l]\r\n      (cond\r\n        (null? l) '()\r\n        (test? (first l) old) (cons old (cons new (rest l)))\r\n        true (cons (first l) ((insertR-f test?) new old (rest l)))))))\r\n\r\n(println ((insertR-f =) 'cake 'cheese '(new york cheese)))\r\n<\/pre>\n<p>Ok &#8211; so you&#8217;ve probably noticed that <code>insertR<\/code> and <code>insertL<\/code> are quite similar except for a piece of code in the middle. Now we&#8217;re going to try and replace these two functions with a single function <code>insert-g<\/code>, that gets another function argument passed in for the difference. We&#8217;ll call the functions we insert <code>seqL<\/code> and <code>seqR<\/code>. Here goes:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def seqL\r\n  (fn &#x5B;new old l]\r\n    (cons new (cons old l))))\r\n\r\n(def seqR\r\n  (fn &#x5B;new old l]\r\n    (cons old (cons new l))))\r\n\r\n(def insert-g\r\n  (fn &#x5B;seqarg]\r\n    (fn &#x5B;new old l]\r\n      (cond\r\n        (null? l) '()\r\n        (= (first l) old) (seqarg new old (rest l))\r\n        true (cons (first l) ((insert-g seqarg) new old (rest l)))))))\r\n\r\n(def insertL (insert-g seqL))\r\n(println (insertL 'creamy 'latte '(a hot cup of latte)))\r\n;\/\/=&gt;(a hot cup of creamy latte)\r\n(def insertR (insert-g seqR))\r\n(println (insertR 'cake 'cheese '(new york cheese)))\r\n;\/\/=&gt;(new york cheese cake)\r\n<\/pre>\n<p>Ok &#8211; what if we do that again &#8211; but don&#8217;t pass in <code>seqL<\/code> as a named function &#8211; just implement it in the definition of <code>insertL<\/code>?<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def insertL\r\n  (insert-g\r\n    (fn &#x5B;new old l]\r\n      (cons new (cons old l)))))\r\n(println (insertL 'creamy 'latte '(a hot cup of latte)))\r\n;\/\/=&gt;(a hot cup of creamy latte)\r\n<\/pre>\n<p>You can argue that this is better as we don&#8217;t have to remember as many function names.<\/p>\n<p>Now we&#8217;ll look at the <code>subst<\/code> function from <a href=\"The Little Schemer in Clojure \u2013 Chapter 3 \u2013 Cons the Magnificent\">Chapter 3<\/a>.<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def subst\r\n  (fn &#x5B;new old l]\r\n    (cond\r\n      (null? l) '()\r\n      (= (first l) old) (cons new (rest l))\r\n      true (cons (first l) (subst new old (rest l))))))\r\n\r\n(println (subst 'espresso 'latte '(a hot cup of latte)))\r\n;\/\/=&gt;(a hot cup of espresso)\r\n<\/pre>\n<p>So what we notice is that <code>subst<\/code> is quite close to <code>insertL<\/code> and <code>insertR<\/code>. So now we can write a new seq function for <code>insert-g<\/code>. Then we can plug it into a new definition of <code>subst<\/code>:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def seqS\r\n  (fn &#x5B;new old l]\r\n    (cons new l)))\r\n\r\n(def subst (insert-g seqS))\r\n\r\n(println (subst 'espresso 'latte '(a hot cup of latte)))\r\n;\/\/&gt;(a hot cup of espresso)\r\n<\/pre>\n<p>Cool &#8211; now we can use this technique on the <code>rember<\/code> function:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def seqrem\r\n  (fn &#x5B;new old l]\r\n    l))\r\n\r\n(def rember\r\n  (fn &#x5B;a l]\r\n    ((insert-g seqrem) nil a l)))\r\n\r\n(println (rember 'hot '(a hot cup of espresso)))\r\n;\/\/=&gt;(a cup of espresso)\r\n<\/pre>\n<p>It&#8217;s time for another <em>Commandment<\/em>. The Tenth Commandment states that you should &#8220;<strong>Abstract functions with common structures into a single function<\/strong>&#8220;. This is kind of like extract method &#8211; except that you pass the method in as a closure.<\/p>\n<p>Now we&#8217;ll go back to the value function from Chapter 7.<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def number_?\r\n  (fn &#x5B;a]\r\n    (cond\r\n      (null? a) false\r\n      (number? a) true\r\n      true false)))\r\n\r\n(def first-sub-exp\r\n  (fn &#x5B;aexp]\r\n    (first (rest aexp))))\r\n\r\n(def second-sub-exp\r\n  (fn &#x5B;aexp]\r\n    (first (rest (rest aexp)))))\r\n\r\n(def operator\r\n  (fn &#x5B;aexp]\r\n    (first aexp)))\r\n\r\n(use 'clojure.math.numeric-tower)\r\n\r\n(def value\r\n  (fn &#x5B;aexp]\r\n    (cond\r\n      (number_? aexp) aexp\r\n      (= (operator aexp) '+) (+ (value (first-sub-exp aexp)) (value  (second-sub-exp aexp)))\r\n      (= (operator aexp) '*) (* (value (first-sub-exp aexp)) (value (second-sub-exp aexp)))\r\n      (= (operator aexp) 'exp) (expt (value (first-sub-exp aexp)) (value (second-sub-exp aexp))))))\r\n\r\n(println (value '(+ 1 1)))\r\n;\/\/=&gt;2\r\n<\/pre>\n<p>Now we&#8217;ll simplify this down by using a function to take a symbol and return a function:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def atom-to-function\r\n  (fn &#x5B;x]\r\n    (cond\r\n      (= x '+ ) +\r\n      (= x '* ) *\r\n      (= x 'exp ) expt )))\r\n\r\n(def value\r\n  (fn &#x5B;aexp]\r\n    (cond\r\n      (number_? aexp) aexp\r\n      true ((atom-to-function (operator aexp))\r\n             (value (first-sub-exp aexp))\r\n             (value (second-sub-exp aexp))))))\r\n\r\n(println (value '(+ 1 1)))\r\n;\/\/=&gt; 2\r\n<\/pre>\n<p>So that was a bit shorter.<\/p>\n<p>Now we&#8217;ll look at <code>subset?<\/code> and <code>intersect?<\/code> from <a href=\"http:\/\/juliangamble.com\/blog\/2012\/09\/07\/the-little-schemer-in-clojure-chapter-8-friends-and-relations\/\">Chapter 8<\/a>.<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def member?\r\n  (fn &#x5B;a lat]\r\n    (cond\r\n      (null? lat) false\r\n      true (or\r\n        (= (first lat) a)\r\n        (member? a (rest lat)))) ))\r\n\r\n(def subset?\r\n  (fn &#x5B;set1 set2]\r\n    (cond\r\n      (null? set1) true\r\n      true (and\r\n             (member? (first set1) set2)\r\n             (subset? (rest set1) set2)))))\r\n(println (subset? '(a b c) '(b c d)))\r\n;\/\/=&gt;false\r\n(println (subset? '(b c) '(b c d)))\r\n;\/\/=&gt;true\r\n\r\n(def intersect?\r\n  (fn &#x5B;set1 set2]\r\n    (cond\r\n      (null? set1) false\r\n      true (or\r\n             (member? (first set1) set2)\r\n             (intersect? (rest set1) set2)))))\r\n\r\n(println (intersect? '(a b c) '(b c d)))\r\n;\/\/=&gt;true\r\n<\/pre>\n<p>What we notice is that these two functions only differ in their use of and true and or nil. We can try and abstract them as we&#8217;ve done before.<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def set-f?\r\n  (fn &#x5B;logical? const]\r\n    (fn &#x5B;set1 set2]\r\n      (cond\r\n        (null? set1) const\r\n        true (logical?\r\n               (member? (first set1) set2)\r\n               ((set-f? logical? const) (rest set1) set2))))))\r\n\r\n;(def subset? (set-f? and true))\r\n;(def intersect? (set-f? or nil))\r\n; note - doesn't work yet\r\n<\/pre>\n<p>But this doesn&#8217;t work. (This is where a light bulb comes on and we start learning). We need to redefine the and and or functions for the functions we&#8217;re using:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def and-prime\r\n  (fn &#x5B;x y]\r\n    (and x y)))\r\n\r\n(def or-prime\r\n  (fn &#x5B;x y]\r\n    (or x y)))\r\n; still doesn't work\r\n\r\n(def or-prime\r\n  (fn &#x5B;x set1 set2]\r\n    (or x (intersect? (rest set1) set2))))\r\n\r\n(def and-prime\r\n  (fn &#x5B;x set1 set2]\r\n    (and x (subset? (rest set1) set2))))\r\n\r\n(def set-f?\r\n  (fn &#x5B;logical? const]\r\n    (fn &#x5B;set1 set2]\r\n      (cond\r\n        (null? set1) const\r\n        true (logical?\r\n               (member? (first set1) set2)\r\n               set1 set2)))))\r\n\r\n(def intersect? (set-f? or-prime false))\r\n(def subset? (set-f? and-prime true))\r\n\r\n(println (intersect?  '(toasted banana bread) '(breakfast toasted banana bread with butter for breakfast)))\r\n;\/\/=&gt;true\r\n(println (subset? '(banana butter) '(breakfast toasted banana bread with butter for breakfast)))\r\n;\/\/=&gt;true\r\n<\/pre>\n<p>The tricky thing there was the recursive use and definition of <code>intersect?<\/code> ie assuming we could use a function before we had defined it in one function, and then using that function to define <code>insersect?<\/code> &#8211; somewhat brain bending!<\/p>\n<p>You can see we wrote <code>set-f<\/code> to accept <code>and-prime<\/code> and <code>or-prime<\/code> as functions passed in as arguments.<\/p>\n<p>Ok &#8211; so we&#8217;re all warmed up with passing functions around as arguments. Let&#8217;s get on with this Y Combinator derivation. We&#8217;ll start with multirember from <a href=\"http:\/\/juliangamble.com\/blog\/2012\/08\/17\/the-little-schemer-in-clojure-chapter-5-the-multichapter-chapter\/\">Chapter 5<\/a>. We&#8217;ll simplify it to remove the redundant <code>cond<\/code>:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def multirember\r\n  (fn &#x5B;a lat]\r\n    (cond\r\n      (null? lat) '()\r\n      (= (first lat) a) (multirember a (rest lat))\r\n      true (cons (first lat) (multirember a (rest lat))))))\r\n\r\n(println (multirember 'breakfast '(breakfast toasted banana bread with butter for breakfast)))\r\n;\/\/=&gt;(toasted banana bread with butter for)\r\n<\/pre>\n<p>Too easy. Now we&#8217;ll curry this function to return a function that removes a particular list member:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def mrember-curry\r\n  (fn &#x5B;l]\r\n    (multirember 'curry l)))\r\n\r\n(println (mrember-curry '(curry chicken with curry rice)))\r\n;\/\/=&gt;(chicken with rice)\r\n<\/pre>\n<p>Again we&#8217;ve done this before &#8211; not too hard. Now we&#8217;ll rewrite mrember-curry in full without currying it:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def mrember-curry\r\n  (fn &#x5B;l]\r\n    (cond\r\n      (null? l) '()\r\n      (= (first l) 'curry) (mrember-curry (rest l))\r\n      true (cons (first l) (mrember-curry (rest l))))))\r\n\r\n(println (mrember-curry '(curry chicken with curry rice)))\r\n;\/\/=&gt;(chicken with rice)\r\n<\/pre>\n<p>Now let&#8217;s curry the function above <em>again<\/em> with an argument that the curried function can be applied to:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def curry-maker\r\n  (fn &#x5B;future]\r\n    (fn &#x5B;l]\r\n      (cond\r\n        (null? l) '()\r\n        (= (first l) 'curry) ((curry-maker future) (rest l))\r\n        true (cons (first l) ((curry-maker future) (rest l)))))))\r\n\r\n(def mrember-curry (curry-maker 0))\r\n;\/\/=&gt;(chicken with rice)\r\n<\/pre>\n<p>Ok so why did we bother with that one? We&#8217;ll its like how we replaced <code>insertL<\/code> with <code>insert-g<\/code> &#8211; except we applied it to a function that already returns functions.<\/p>\n<p>Let&#8217;s look at how we use it. We can use <code>curry-maker<\/code> to define <code>mrember-curry<\/code> with <code>curry-maker<\/code>.<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def mrember-curry\r\n  (curry-maker curry-maker))\r\n\r\n(println (mrember-curry '(curry chicken with curry rice)))\r\n;\/\/=&gt;(chicken with rice)\r\n<\/pre>\n<p>Ok &#8211; that wasn&#8217;t a big deal &#8211; we replaced a zero value with another function. Let&#8217;s apply it further. We&#8217;ll use this zero replacement in <code>curry-maker<\/code> to write a function <code>function-maker<\/code>:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def function-maker\r\n  (fn &#x5B;future]\r\n    (fn &#x5B;l]\r\n      (cond\r\n        (null? l) '()\r\n        (= (first l) 'curry) ((future future) (rest l))\r\n        true (cons (first l) ((future future) (rest l)))))))\r\n\r\n;for yielding mrember-curry when applied to a fcuntion\r\n\r\n;\r\n(def mrember-curry\r\n  (function-maker function-maker))\r\n(println (mrember-curry '(curry chicken with curry rice)))\r\n;\/\/=&gt;(chicken with rice)\r\n<\/pre>\n<p>Ok &#8211; we&#8217;re about half way there. Now for any internal expression inside a function, we can wrap it in an applied <code>lamdba<\/code> (<code>fn<\/code> in clojure) and still have it return the same result. We&#8217;ll do that for our function-maker function.<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def function-maker\r\n  (fn &#x5B;future]\r\n    (fn &#x5B;l]\r\n      (cond\r\n        (null? l) '()\r\n        (= (first l) 'curry) ((fn &#x5B;arg] ((future future) arg)) (rest l))\r\n        true (cons (first l) ((fn &#x5B;arg] ((future future) arg)) (rest l)))))))\r\n\r\n(def mrember-curry\r\n  (function-maker function-maker))\r\n(println (mrember-curry '(curry chicken with curry rice)))\r\n;\/\/=&gt;(chicken with rice)\r\n<\/pre>\n<p>Ok &#8211; that all still works ok.<\/p>\n<p>Now &#8211; our <code>function-maker<\/code> is in a way double-curried. What if we curry it again?<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def function-maker\r\n  (fn &#x5B;future]\r\n    ((fn &#x5B;recfun]\r\n      (fn &#x5B;l]\r\n        (cond\r\n          (null? l) '()\r\n          (= (first l) 'curry) (recfun (rest l))\r\n        true (cons (first l) ((future future))))))\r\n    (fn &#x5B;arg] ((future future) arg)))))\r\n;abstraction above to remove l\r\n; just take my word on this for now\r\n<\/pre>\n<p>Now we&#8217;ll split our triple-curried function into two functions:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def M\r\n  (fn &#x5B;recfun]\r\n    (fn &#x5B;l]\r\n      (cond\r\n        (null? l) '()\r\n        (= (first l) 'curry) (recfun (rest l))\r\n        true (cons (first l) (recfun (rest l)))))))\r\n\r\n(def function-maker\r\n  (fn &#x5B;future]\r\n    (M (fn &#x5B;arg]\r\n         ((future future) arg)))))\r\n<\/pre>\n<p>Now we&#8217;ll refactor <code>mrember-curry<\/code> without an explicit reference to <code>function-maker<\/code>:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n;Now we'll change this\r\n(def mrember-curry\r\n  (function-maker function-maker))\r\n;to this\r\n(def mrember-curry\r\n  ((fn &#x5B;future]\r\n     (M (fn &#x5B;arg]\r\n          ((future future) arg))))\r\n    (fn &#x5B;future]\r\n      (M (fn &#x5B;arg]\r\n           ((future future) arg))))))\r\n\r\n<\/pre>\n<p>This is where the book recommends you take a rest. We&#8217;ll push on.<\/p>\n<p>Now we&#8217;ll refactor this definition by allowing you to pass in M as a function:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def Y\r\n  (fn &#x5B;M]\r\n    ((fn &#x5B;future]\r\n       (M (fn &#x5B;arg]\r\n            ((future future) arg))))\r\n      (fn &#x5B;future]\r\n        (M (fn &#x5B;arg]\r\n             ((future future) arg)))))))\r\n\r\n(def mrember-curry (Y M))\r\n\r\n(println (mrember-curry '(curry chicken with curry rice)))\r\n;\/\/=&gt;(chicken with rice)\r\n<\/pre>\n<p>That wasn&#8217;t too bad. We just used the y-combinator on the <code>mrember<\/code> function. Now we&#8217;ll do it for <code>length<\/code>:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n;using add1 from chapter 7 not chapter 4\r\n(def add1\r\n  (fn &#x5B;n]\r\n    (cons '() n)))\r\n\r\n; now we'll look at using the y-combinator to look at the length of a list\r\n(def L\r\n  (fn &#x5B;recfun]\r\n    (fn &#x5B;l]\r\n      (cond\r\n        (null? l) '()\r\n        true (add1 (recfun (rest l)))))))\r\n\r\n(def length (Y L))\r\n\r\n(println (length '(curry chicken with curry rice)))\r\n;\/\/=&gt;(() () () () ()) ie 5\r\n<\/pre>\n<p>Now we&#8217;ll do it again, but won&#8217;t pass in a definition for <code>L<\/code> &#8211; but just use the definition inline:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def add1\r\n  (fn &#x5B;n]\r\n    (+ 1 n)))\r\n\r\n;just for the sake of it - we'll rewrite length without the L function\r\n(def length\r\n  (Y\r\n    (fn &#x5B;recfun]\r\n      (fn &#x5B;l]\r\n        (cond\r\n          (null? l) 0\r\n          true (add1 (recfun (rest l))))))))\r\n\r\n(println (length '(curry chicken with curry rice)))\r\n;\/\/=&gt;5\r\n<\/pre>\n<p>Now we&#8217;ll rewrite <code>length<\/code> without <code>Y<\/code> or <code>L<\/code>:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def length\r\n  ((fn &#x5B;M]\r\n     ((fn &#x5B;future]\r\n        (M (fn &#x5B;arg]\r\n             ((future future) arg))))\r\n     (fn &#x5B;future]\r\n       (M (fn &#x5B;arg]\r\n            ((future future) arg))))))\r\n    (fn &#x5B;recfun]\r\n      (fn &#x5B;l]\r\n        (cond\r\n          (null? l) 0\r\n          true (add1 (recfun (rest l))))))))\r\n\r\n(println (length '(curry chicken with curry rice)))\r\n;\/\/=&gt;5\r\n<\/pre>\n<p>Ok that ends the Chapter &#8211; but we want to take this thing to the next level. Let&#8217;s use the ycombinator to start defining a lazy function:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n;building a pair with an S-expression and a thunk leads to a stream\r\n(def first$ first)\r\n\r\n(def second$\r\n  (fn &#x5B;str]\r\n    ((second str))))\r\n\r\n; careful re use of first and second here - as yet undefined!\r\n\r\n(def build\r\n  (fn &#x5B;a b]\r\n    (cond\r\n      true (cons a (cons b '())))))\r\n\r\n(def str-maker\r\n  (fn &#x5B;next n]\r\n    (build n (fn &#x5B;] (str-maker next (next n))))))\r\n\r\n(def int_ (str-maker add1 0))\r\n\r\n(def even (str-maker (fn &#x5B;n] (+ 2 n)) 0))\r\n\r\n;sub1 from chapter 4\r\n(def sub1\r\n  (fn &#x5B;n]\r\n    (- n 1)))\r\n\r\n(def frontier\r\n  (fn &#x5B;str n]\r\n    (cond\r\n      (zero? n) '()\r\n      true (cons (first$ str) (frontier (second$ str) (sub1 n))))))\r\n\r\n(frontier int_ 10)\r\n;\/\/=&gt;(0 1 2 3 4 5 6 7 8 9)\r\n<\/pre>\n<p>So that got us the creation of a lazy data structure for a basic example. Now let&#8217;s try a more interesting one:<\/p>\n<pre class=\"brush: clojure; title: ; notranslate\" title=\"\">\r\n(def Q\r\n  (fn &#x5B;str n]\r\n    (cond\r\n      (zero? (rem (first$ str) n)) (Q (second$ str) n)\r\n      true (build (first$ str) (fn &#x5B;] (Q (second$ str) n))))))\r\n; note new function call rem - re new primitve\r\n\r\n(def P\r\n  (fn &#x5B;str]\r\n    (build (first$ str) (fn &#x5B;] (P (Q str (first$ str)))))))\r\n\r\n(frontier (P (second$ (second$ int_))) 10)\r\n;\/\/=&gt;(2 3 5 7 11 13 17 19 23 29)\r\n<\/pre>\n<p>What an interesting stream of numbers!<\/p>\n<p>That&#8217;s enough for today.<\/p>\n<p>You can see it working <a href=\"http:\/\/ideone.com\/FCdfQ\">here<\/a>.<\/p>\n<p><strong>References<\/strong><\/p>\n<p>Here are some additional references on deriving the Y-Combinator<\/p>\n<ul>\n<li><a href=\"http:\/\/www.catonmat.net\/blog\/derivation-of-ycombinator\/\">Deriving the Y Combinator in Scheme<\/a>.<\/li>\n<li><a href=\"http:\/\/www.catonmat.net\/blog\/wp-content\/uploads\/2010\/02\/thewhyofywhyofy.pdf\">A second approach to deriving the Y Combinator in Scheme<\/a><\/li>\n<li><a href=\"http:\/\/blog.jcoglan.com\/2008\/01\/10\/deriving-the-y-combinator\/\">Deriving the Y Combinator in Javascript<\/a><\/li>\n<li><a href=\"http:\/\/igstan.ro\/posts\/2010-12-01-deriving-the-y-combinator-in-7-easy-steps.html\">Another approach to deriving the Y Combinator in Javascript<\/a><\/li>\n<li><a href=\"http:\/\/citizen428.net\/blog\/2010\/12\/14\/clojure-deriving-the-y-combinator-in-7-stolen-steps\/\">Deriving the Y Combinator in Clojure<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This is the ninth chapter of a series of posts about porting\u00a0The Little Schemer\u00a0to Clojure. You may wish to\u00a0read the intro. So far we&#8217;ve covered\u00a0flat data structures,\u00a0reading flat data structures,\u00a0creating data structures,\u00a0creating a numeric tower, working with\u00a0multiple occurrences of a &hellip; <a href=\"https:\/\/juliangamble.com\/blog\/2012\/09\/15\/the-little-schemer-in-clojure-chapter-9-lambda-the-ultimate-deriving-the-y-combinator\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[3,12],"tags":[],"class_list":["post-427","post","type-post","status-publish","format-standard","hentry","category-clojure","category-thelittleschemer"],"_links":{"self":[{"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/posts\/427","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/comments?post=427"}],"version-history":[{"count":11,"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/posts\/427\/revisions"}],"predecessor-version":[{"id":575,"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/posts\/427\/revisions\/575"}],"wp:attachment":[{"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/media?parent=427"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/categories?post=427"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/juliangamble.com\/blog\/wp-json\/wp\/v2\/tags?post=427"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}