3 ms·
Rich Hickey has some interesting things to say about learning clojure via SICP. http://groups.google.com/group/clojure/browse_thread/thread/8f23ae245ba4a661 ht
by silkodyssey 17y ago
Rich Hickey has some interesting things to say about learning clojure via SICP.
http://groups.google.com/group/clojure/browse_thread/thread/8f23ae245ba4a661 http://groups.google.com/group/clojure/browse_thread/thread/...
- dschobel 17y agoKind of off-topic, but I'm pretty surprised clojure doesn't do TCO. Is that a JVM limitation?
- ikitat 17y agoYes
- dantheman 17y agoThis one of the things that Microsoft got right with the CLR. That TCO is required by scheme is where I finally grokked programming language semantics -- how implementation and form are intertwined.
- tl 17y agoIsn't the TCO problem largely a non-issue? My understanding is that if you do (defn function [...] ... (recur ...)) instead of (defn function [...] ... (function ...)) the compiler handles it for you.
- scythe 17y agoThere's more to tail-call optimization than simply imitating iteration using recursion.
- dmoney 17y agoWhat else is it used for?
- chancho 17y agohttp://en.wikipedia.org/wiki/Continuation-passing_style http://en.wikipedia.org/wiki/Continuation-passing_style
- Xichekolas 17y agoAlso, this blog post (which did the rounds on HN a while back) was excellent for understanding it: http://funcall.blogspot.com/2009/04/you-knew-id-say-something.html http://funcall.blogspot.com/2009/04/you-knew-id-say-somethin... (It's part of a 5 part series... but you don't have to necessarily read all of them... it kind of wanders.)
- silentbicycle 17y agoIt may help to stop thinking of it being used specifically for recursion - there can be tail calls between several functions. In cases where TCO is applicable, function A calls B, and B calls C, but since B isn't doing anything to the result, C can return directly to A. This is transitive - D, E, F, ... could all return to A as well, in constant space. It "goto"s the next function (but with arguments), and returning and popping the results off the call stack is deferred. Rather than going into fairly abstract examples* , TCO is useful because it allows more things to be expressed in terms of function calls, without having to worry about blowing the stack. While the discussion surrounding them can be a bit overly academic, they ultimately matter because they can help make code clearer. (Not always, but you can implement clearer looping mechanisms on top of them.) A tail call is like a de-fanged goto. * Just one: Parsing by implementing a finite state machine in function calls. See Shriram Krishnamurthi's "The Swine Before Perl" (http://www.cs.brown.edu/~sk/Publications/Talks/SwineBeforePerl/ http://www.cs.brown.edu/~sk/Publications/Talks/SwineBeforePe...). While the stacktrace no longer records intermediate steps, (and thus loses info useful for debugging), language implementations can typically hook tail calls to save the information when a debugging flag is on. It's not as big a problem in practice as some people think.