Created
December 15, 2022 10:21
-
-
Save divs1210/6e069952e8de5c8629fdf34b81d6d20b 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