Subject: Re: Tail recursion & CL From: Erik Naggum <erik@naggum.net> Date: Tue, 02 Oct 2001 13:34:18 GMT Newsgroups: comp.lang.lisp Message-ID: <3211018454924999@naggum.net> * Bruce Hoult | I don't know why, but you and Kent seem to want a lot more from "tail | call optimization" than I do. Huh? I have argued for a differentiation of "properly tail-recursive" and "tail call optimization". What I want from tail call optimization is meant to be a severe restriction of what Scheme freaks want from their undesirable "properly tail-recursive" concept. | Or, rather, you *don't* want it and so insist that if it can't work in | every conceivable situation then it isn't worth having at all. Are you nuts? Where did you get this garbage? Of course I want it. However, I do not want it mandated by the standard, because that has a lot of negative aspects to it. Hell, if I want a standard that says something so annoying as requiring a properly tail-recursive execution model, I would use Scheme. I loathe Scheme. Get a grip, Bruce, quit pretending that you are fighting an enemy you are not. Please realize that there is a difference between a desire for a feature and a desire for a law (or specification) that require others to provide a feature. You seem to confuse the two, or at least not allow other people (Kent and me?) to make a distinction, and get all flustered because you think we do not want what we do not want there to be a law to _require_. I believe the rest of your message rests on these false premises, too. | No it is not. Christ, Bruce, THINK! I have no patience with this crap. Go back and read what I wrote. You have clearly not understood what I said, and now you argue against something you have misunderstood. Quit that stupidity. | You'd have to prove a bunch of other things as well, of course, but that | one alone is sufficient to show that it's very very difficult to | impossible to convert something inside an unwind-protect into something | that can be tail-called. This is just simply wrong. _Listen_, now, OK? | Indeed. Which is precisely why using a tail-call for things inside an | unwind-protect is a nonsense. You obviously fail to think about this, and that annoys me. Consider this simple fact: What a function returns to is _not_ under its control. If a function returns to its caller, which does some work before it also returns, it could as well return to a different function that does that work. This is the core of the argument for tail-call optimzation, is it not? Why does it _not_ apply to unwind forms? _Think_ about this, OK? | The whole *point* of the tail call is that it doesn't return Huh? What is this nonsense? On the contrary, the whole point is that it returns to the caller of the caller in place of the caller, which has _redirected_ it to return elsewhere from what _its_ caller said it should return to. The whole *point* with tail calls is that there is a simple semantic equivalence between call/return/return and jump/return, and that this is completely independent of _both_ what you jump _and_ return to. What I suggest is an _expansion_ of the mere implementation of tail-call optimization such that you can call functions for their side-effect after a call that returns a value simply by returning to them instead of callling them. That is well within the conceptual framework of what you seem to be clamoring for. Why do you not get this simple application of your concept of tail-call optimization? | Anything that you have to come back and do later (e.g. unwind) totally | nullifies that. _Wrong_. _THINK_ about this, will you? _How_ you arrange for something to be done after you have returned is ORHTHOGONAL to arranging to do it. | This is true, but it's pretty pointless. In a recursive call that | contains an unwind-form you're going to grow your stack of | unwind-forms-to-be-executed without bound. So you think tail-call optimization is _only_ for recursion? What _is_ this? Bruce, you _are_ not the idiot you seem to be insisting on showing me right now. What has gotten into you? The Scheme freaks want a properly tail recursive execution model for a number of reasons. Tail call optimization is a much weaker concept, and it will actually save a lot of stack space -- namely the stack space consumed by arguments and call frames -- _even_ if you have special bindings and unwind-protect forms. _Those_ are the worth-while savings. And what is this silly thing about "without bound"? There will be no more and no less bound on the recursion regardless of tail-call optimization! If you can save on _some_ resources, but not all, why are _you_ opposed to that? Was it not _you_ who accused Kent and me of the following just a few lines up? | Or, rather, you *don't* want it and so insist that if it can't work in | every conceivable situation then it isn't worth having at all. Now _you_ are arguing this silly position which nobody else holds. Quit the stupidity and _think_ about what you are saying, damn it! | Sure, you'll save a little memory because the structure that you put on | that stack each time is probably a little smaller than the entire stack | frame for the function would be, but that's just a savings of a constant | factor -- it doesn't make a tail-recursive function (or set of mutually | tail-calling functions) execute in constant space, which is the purpose | of the optimization. Why do you restrict an optimization to such a purpose? Why do you need there to be "constant space" when there is a clear and present benefit from not over-using another resource? And why do you drag in the _size_ of call frames? Christ, Bruce, that is _so_ beside the point. Call frames can be *large* these days. An unwind-protect/special stack can be very small. Now _you_ want to discard the stack space savings because you will still need special/unwind-protect space? What _is_ this? Whatever _are_ you defending, Bruce Hoult? Whatever it is, I can assure you that it is _not_ under attack. Just _think_ about the arguments you get and you might learn something that you are currently insisting on _not_ seeing. ///