Search code examples
recursionclojurelispy-combinator

Applying the Y-Combinator to a recursive function with two arguments in Clojure?


Doing the Y-Combinator for a single argument function such as factorial or fibonacci in Clojure is well documented: http://rosettacode.org/wiki/Y_combinator#Clojure

My question is - how do you do it for a two argument function such as this getter for example?

(Assumption here is that I want to solve this problem recursively and this non-idiomatic clojure code is there deliberately for another reason)

[non y-combinator version]

(defn get_ [n lat]
    (cond
      (empty? lat) ()
        (= 0 (- n 1)) (first lat)
        true (get_ (- n 1) (rest lat))))

(get_ 3 '(a b c d e f g h i j))

Solution

  • The number of args doesn't change anything since the args are apply'd. You just need to change the structure of get_:

    (defn get_ [f]
      (fn [n lat]
        (cond
          (empty? lat) ()
          (= 1 n) (first lat)
          :else (f (dec n) (next lat)))))
    
    (defn Y [f]
      ((fn [x] (x x))
       (fn [x]
         (f (fn [& args]
              (apply (x x) args))))))
    
    user=> ((Y getf) 3 '(a b c d e f g h i j))
    c