I found Rich's answer August 14th, 2008:

On Aug 14, 6:35 am, "rob.la...@gmail.com" <rob.la...@gmail.com> wrote:
> As I understand it, Clojure does not have tail call optimisation,
> because of limitations of the JVM. Scala, however, has TCO, or at
> least something called Tail Recursion Optimisation which, from my
> newbie perspective seems to be more or less the same thing. ( I can't
> find a definitive reference on this, but the web is littered with
> references )
>
> Are they the same thing?

No they are not. Full TCO optimizes all calls in the tail position,
whether to the same function or another. No language that uses the JVM
stack and calling convention (e.g. Clojure and Scala) can do TCO since
it would require either stack manipulation capabilities not offered in
the bytecode spec or direct support in the JVM. The latter is the best
hope for functional languages on the JVM, but I'm not sure is a
priority for Sun as tail-calls are not idiomatic for JRuby/Jython/
Groovy.

IMO, either a language has full TCO or it simply doesn't support using
function calls for control flow, and shouldn't use the term. I didn't
implement self-tail-call optimizations because I think, for people who
rely on TCO, having some calls be optimized and some not is more a
recipe for error than a feature.

So, Clojure has recur, which clearly labels the only situations that
won't grow the stack, apologizes for no real TCO, doesn't pretend to
support function calls for control flow, and anxiously awaits TCO in
the JVM, at which point it will fully support it.

> Is this something that Clojure could/should
> copy?
>
> I ask, because I find that I develop a little nagging voice squeaking
> "beware the stack depth" every time I implement a recursive solution.
> Is this an irrational fear? Should I worry about this?
>

I don't think so, once you have an understanding of the options in
Clojure. In addition to recur, there are lazy sequences and lazy-cons.
To the extent you can structure your processing using the lazy
sequence model, including making your own calls to lazy cons, you can
write traditional-looking functional and recursive solutions that not
only don't grow the stack, but also don't create fully-realized result
lists on the heap, a terrific efficiency boost. I am not contending
that this is as general as TCO, but it has other nice properties, like
the ability to make results that are not tail calls (e.g. list
builders) space efficient.

You should be wary of transliterating Scheme code that relies on TCO
to Clojure.

> I haven't had any problems so far in the toy applications I've worked
> with; but in my day-job I've had to deal with large-ish data-sets that
> grow over time and the prospect of one day experiencing
> StackOverflowException on a production app scares me silly.
>
> Now, I know I could implement everything manually using recur, but it
> doesn't feel natural. Is this something that I should just get over?
> Will it feel natural in time?
>

I'll let the users chime in on this point.

Rich


On Wed, 26 Jan 2011 13:10:52 -0800 (PST)
Armando Blancas <armando_blan...@yahoo.com> wrote:

> From SICP: "With a tail-recursive implementation, iteration can be
> expressed using the ordinary procedure call mechanism". As I
> understand this, a tail call is a loop with functional notation but
> not actually a function call. That's why I find this issue difficult
> to follow, since loops are internal details of a function/method and
> don't get involved with calls, stack frames, access security, or how
> the jit-compiled code may or may not be optimized. So there's
> something key here that I'm missing.
> 
> In a little project of mine I plan on doing this (hand-coded with ASM
> as my compiler doesn't do TCO yet). That seems to work but I wonder
> what issues may come up.
> 
> int fact(int n, int r) {
>   if (n == 0) return r;
>   else return fact(n-1, n*r);
> }
>    0:   iload_0
>    1:   ifne    6
>    4:   iload_1
>    5:   ireturn
>    6:   iload_0
>    7:   istore_2 // temp for n
>    8:   iload_2
>    9:   iconst_1
>    10:  isub
>    11:  istore_0
>    12:  iload_2
>    13:  iload_1
>    14:  imul
>    15:  istore_1
>    16:  goto    0
> 
> On Jan 26, 11:20 am, Luc Prefontaine <lprefonta...@softaddicts.ca>
> wrote:
> > From what I recall from a previous thread it would require so much
> > byte code tweaking that Hot Spot optimizations would become useless.
> >
> > You can search the mailing list, you will find a couple of
> > instructive discussions about this.
> >
> > Luc P.
> >
> > On Wed, 26 Jan 2011 10:01:04 -0800
> >
> > Raoul Duke <rao...@gmail.com> wrote:
> > > On Wed, Jan 26, 2011 at 7:41 AM, Michael Gardner
> > > <gardne...@gmail.com> wrote:
> > > > However, the JVM does not support tail-call optimization.
> > > > Apparently Clojure can't support implicit TCO without support
> > > > from the JVM
> >
> > > always wondered about that also wrt scala etc., am under the
> > > impression that it is implementable, but it would be too slow?
> >
> > --
> > Luc P.
> >
> > ================
> > The rabid Muppet
> 



-- 
Luc P.

================
The rabid Muppet

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to