store/[org.clojure/clojure "1.8.0"] clj::clojure.core/trampoline

Official Documentation

Add notes
Arities
==================================================
   [f]
   [f & args]

Docstring
==================================================
  trampoline can be used to convert algorithms requiring mutual
  recursion without stack consumption. Calls f with supplied args, if
  any. If f returns a fn, calls that fn with no arguments, and
  continues to repeat, until the return value is not a fn, then
  returns that non-fn value. Note that if you want to return a fn as a
  final value, you must wrap it in some data structure and unpack it
  after trampoline returns.

Source

(defn trampoline
  "trampoline can be used to convert algorithms requiring mutual
  recursion without stack consumption. Calls f with supplied args, if
  any. If f returns a fn, calls that fn with no arguments, and
  continues to repeat, until the return value is not a fn, then
  returns that non-fn value. Note that if you want to return a fn as a
  final value, you must wrap it in some data structure and unpack it
  after trampoline returns."
  {:added "1.0"
   :static true}
  ([f]
     (let [ret (f)]
       (if (fn? ret)
         (recur ret)
         ret)))
  ([f & args]
     (trampoline #(apply f args))))

Example 1

Edit
(defn foo [x]
  (if (< x 0)
    (println "done")
    #(foo (do (println :x x) (dec x)))))
;; => #'user/foo

;; trampoline will keep calling the function for as long as "foo" returns a function.
(trampoline foo 10)
;; > :x 10
;; > :x 9
;; > :x 8
;; > :x 7
;; > :x 6
;; > :x 5
;; > :x 4
;; > :x 3
;; > :x 2
;; > :x 1
;; > :x 0
;; > done
;; => nil

Uses on crossclj