Skip to content

Instantly share code, notes, and snippets.

@martintrojer
Created July 23, 2012 11:13
Show Gist options
  • Save martintrojer/3163126 to your computer and use it in GitHub Desktop.
Save martintrojer/3163126 to your computer and use it in GitHub Desktop.
Untying the Recursive Knot
(defn fact' [fact n]
(if (= n 0) 1
(* n (fact (dec n)))))
(defn fact [n]
(if (= n 0) 1
(* n (fact (dec n)))))
(defn even' [odd es os [e & t]]
(if e
(odd (conj es e) os t)
[es os]))
(defn odd' [even es os [o & t]]
(if o
(even es (conj os o) t)
[es os]))
(y (fn [f & args] (apply even' (partial odd' f) args)) [] [] (range 7))
;; [[0 2 4 6] [1 3 5]]
(declare odd)
(defn even [es os [e & xs]]
(if e
(odd (conj es e) os xs)
[es os]))
(defn odd [es os [o & xs]]
(if o
(even es (conj os o) xs)
[es os]))
(even [] [] (range 7))
;; [[0 2 4 6] [1 3 5]]
(declare odd)
(defn even [es os [e & xs]]
(if e
(odd (conj es e) os xs)
[es os]))
(defn odd [es os [o & xs]]
(if o
(even es (conj os o) xs)
[es os]))
(even [] [] (range 7))
;; [[0 2 4 6] [1 3 5]]
(defn y [f & xs]
(apply f (partial y f) xs))
(y (fn [f n]
(println "fact" n)
(fact' f n))
5)
;; fact 5
;; fact 4
;; fact 3
;; fact 2
;; fact 1
;; fact 0
;; 120
(y fact' 10)
;; 3628800
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment