Skip to content

Instantly share code, notes, and snippets.

@missingfaktor
Last active September 4, 2017 15:06
Show Gist options
  • Select an option

  • Save missingfaktor/a70b8fe1c2fe314017b90663127a485b to your computer and use it in GitHub Desktop.

Select an option

Save missingfaktor/a70b8fe1c2fe314017b90663127a485b to your computer and use it in GitHub Desktop.
akar.try-out=> (defn tail-recursive-sum [x running-total]
#_=> (if (zero? x) running-total #(tail-recursive-sum (dec x) (+ running-total x))))
#'akar.try-out/tail-recursive-sum
akar.try-out=> (alter-var-root #'tail-recursive-sum (fn [cur] (partial trampoline cur)))
#object[clojure.core$partial$fn__4759 0x6188158f "clojure.core$partial$fn__4759@6188158f"]
akar.try-out=> (tail-recursive-sum 10000 0)
StackOverflowError clojure.lang.Util.equiv (Util.java:30)
scala> import util.control.TailCalls._
import util.control.TailCalls._
scala> def tailRecursiveSum(x: Int, running: Int): TailRec[Int] = x match {
| case 0 => done(running)
| case _ => tailcall(tailRecursiveSum(x - 1, x + running))
| }
tailRecursiveSum: (x: Int, running: Int)util.control.TailCalls.TailRec[Int]
scala> tailRecursiveSum(100000, 0).result
res2: Int = 705082704
@puredanger

puredanger commented Sep 4, 2017

Copy link
Copy Markdown

Not sure what you're doing with the alter-var-root. I would do something like:

(defn tramp-sum [x t] 
  (trampoline tail-recursive-sum 10000 0))

(tramp-sum 10000 0)
;;=> 50005000

Of course in this case, the idiomatic way to get TCO in Clojure is to just use recur. trampoline is only needed for mutual recursion.

(defn tail-recursive-recur [x running-total]
  (if (zero? x) running-total (recur (dec x) (+ running-total x))))

(tail-recursive-recur 10000 0)
;;=> 50005000

@missingfaktor

Copy link
Copy Markdown
Author

@puredanger Thanks a lot, mate! I figured out what was wrong. alter-var-root also changes the reference to tail-recursive-sum in its original definition. :-) Mutability... Still bites me after all these years!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment