Hacker News new | past | comments | ask | show | jobs | submit login

A longer answer, because there seems to be a lot of confusion here.

The JVM security model allows a function to goto anywhere inside the current function, but does not allow a goto to outside the current function.

This means that JVM based languages can do tail call optimizations in self-recursive functions, but can't TCO in mutually recursive functions.

With Clojure, Rich Hickey thought there was some accidental complexity here, so he added the recur special form. Recur guarantees the call is in the tail position, and throws an exception if it isnt. Recur can go to the top of the function, or an enclosing loop block inside the function.

To do mutual recursion in Clojure, you use a trampoline. That looks like

    (declare even? odd?)

    (defn even? [x]
      (if (= x 0)
        true
        #(odd? (dec x)))

    (defn odd? [x]
      (if (= x 1)
        true
        #(even? (dec x)))

    (trampoline even? 100)
What we're doing here is defining two mutually recursive functions, but instead of calling the other directly, we return a function of no arguments that calls the other function. Then call trampoline, passing the function and any arguments. Not the most elegant solution, but it works.



Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: