-
-
Save lambder/c66e1f04448e6a41fecfb8016489ec26 to your computer and use it in GitHub Desktop.
Clojure trampolined continuation passing style
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defmacro trampolined | |
"Wraps recursive calls." | |
[& body] | |
`(fn [] ~@body)) | |
(defn trampolined-k-fn | |
"Takes a k-fn and returns a stackless fn. | |
k-fn should be a CPS function with k as the first arg. | |
In k-fn, all recursive calls should be wrapped using `trampolined`." | |
[k-fn] | |
(fn [& args] | |
(trampoline #(apply k-fn identity args)))) | |
;; Example usage | |
;; ============= | |
(defn k-A | |
"Ackermann function. | |
Implemented in trampolined Continuation Passing Style." | |
[k m n] | |
(cond | |
(zero? m) | |
(k (inc n)) | |
(zero? n) | |
(recur k (dec m) 1) | |
:else | |
(recur (fn [n'] | |
(trampolined | |
(k-A k (dec m) n'))) | |
m | |
(dec n)))) | |
(def A | |
(trampolined-k-fn k-A)) | |
(A 3 10) ;; => 8189 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment