Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Modest agreement here.

I am a big fan of being able to get stack backtraces when I have a problem to debug. But tail call recursion silently throws away stack frames. You get great performance benefits from doing so, but I'd like an option when debugging to get at the information that has been thrown away.

During debugging I'd prefer to change recur into a function call than make an edit that kills the optimization for less obvious reasons. So far so good.

But recur is less flexible than tail call optimization. Consider for the moment a problem that you have modeled with finite state machines. Each state is a function, and a state transition is signaled by calling the next function. With tail call optimization this won't grow your stack. With recur you have no choice because you can't jump to another function.



I believe the trampoline function / special form can do the mutual tail-call in clojure (http://clojure.org/api#toc569) :

  trampoline can be used to convert algorithms requiring
  mutual recursion without stack consumption.
but I haven't used it yet, am still fairly new to lisp / clojure, so certainly am not an expert in this field. YMMV


Good point. That is possible, albeit with a modest overhead. The overhead would be irrelevant except that state machines get used in very performance critical ways, such as inside a regular expression engine. But possibly Clojure isn't the right language if you care about performance that much.

Incidentally I'd be shocked if trampoline was a special form rather than a function. I'm not sure what type a function is (I don't use clojure nor is it installed here), but it should be possible to implement it something like this:

  (defn trampoline [f]
    (if (eq? (type f) 'function')
      (recur (f))
      f))


Indeed, Clojure's trampoline is a function:

  (defn trampoline
    ([f]
      (let [ret (f)]
        (if (fn? ret)
          (recur ret)
          ret)))
    ([f & args]
      (trampoline #(apply f args))))


You can use trampolines in dumber languages too, so that mutual recursion without stack consumption is possible in for e.g. Javascript.

http://pastebin.com/m73e36bfc




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

Search: