From: josephoswald+gg on
On Aug 6, 7:17 am, Elena <egarr...(a)gmail.com> wrote:

> IMHO, that would be a better way to make TCO available, that is: TCO
> should be explicit, since you know beforehand whether you want your
> function to be tail recursive or not. Then, whenever you fail to
> implement a tail recursion among mutually recursive functions, the
> compiler should complain. If I'm not mistaken, OCaml has (somewhat)
> explicit TCO. Or detecting such errors would better be left to test
> cases?

This is absurd. TCO is a simple optimization: instead of "push
outgoing arguments, jump to routine, pop incoming arguments without
having looked at them, return", the compiler recognizes the incoming
arguments are actually dead, so it rearranges the tail call to be "pop
unneeded incoming arguments, push outgoing arguments, jump to
routine."

Unlike Pythonistas, many comp.lang.lisp readers actually are aware of
the "Ultimate Lambda" papers, and understand that calling conventions
to allow recursion were novel in the 1950s and 60s, and these
optimizations were recognized in the 1970s.

Why the hell should the programmer have to turn on a big switch to
allow the compiler to make this straightforward calculation? It is a
completely idiotic idea based on some emotional worry that somehow
using excess stack is good for digestion, or because TCO is taught in
Scheme classes. Yes, like all optimization, it can make debugging
somewhat harder because the CPU instructions resemble the code less
that might be expected, so you offer switches to turn optimizations
off if stack consumption is less harmful than the debugging pain.

This is completely separate from the stylistic question about whether
deliberately writing your code to depend on TCO is a good idea. That
depends on the range of implementations you will want to run on, and
how ugly the result is compared to all alternatives.
From: Frode V. Fjeld on
> On Aug 6, 7:17 am, Elena <egarr...(a)gmail.com> wrote:

>> [...] TCO should be explicit [...]

"josephoswald+gg(a)gmail.com" <josephoswald(a)gmail.com> writes:

> This is absurd. [...]

> This is completely separate from the stylistic question about whether
> deliberately writing your code to depend on TCO is a good idea.

No it's not, this is precisely the issue. If code never depends on TCO,
then TCO is indeed but a simple compiler trick that is largely
irrelevant to the programmer. If you (want to) have code that does
depend on TCO, then having explitit syntax for it is the only reasonable
way to go.

> That depends on the range of implementations you will want to run on,
> and how ugly the result is compared to all alternatives.

This is the current state of affairs with Common Lisp, but explicit TCO
would have been an improvement.

--
Frode V. Fjeld

From: josephoswald+gg on
On Aug 6, 8:19 am, "Frode V. Fjeld" <fr...(a)netfonds.no> wrote:
> > On Aug 6, 7:17 am, Elena <egarr...(a)gmail.com> wrote:
> >> [...] TCO should be explicit [...]
> "josephoswald...(a)gmail.com" <josephosw...(a)gmail.com> writes:
> > This is absurd.  [...]
> > This is completely separate from the stylistic question about whether
> > deliberately writing your code to depend on TCO is a good idea.
>
> No it's not, this is precisely the issue. If code never depends on TCO,
> then TCO is indeed but a simple compiler trick that is largely
> irrelevant to the programmer. If you (want to) have code that does
> depend on TCO, then having explitit syntax for it is the only reasonable
> way to go.
>
> > That depends on the range of implementations you will want to run on,
> > and how ugly the result is compared to all alternatives.
>
> This is the current state of affairs with Common Lisp, but explicit TCO
> would have been an improvement.
>
> --
> Frode V. Fjeld

There is more than one way to enforce the constraint that "this module
must not consume more than X amount of stack for input Y."

One is to write explicitly iterative code. Another is to write TCO-
amenable code and use a compiler that can exploit it, and maybe you
have to check the emitted code to be sure. Having a compiler that
warns you that "I couldn't achieve the optimization that you were
looking for" is a convenience feature like a compiler warning about
excessive boxing of results, and I don't object to optional (declare
(tco 3)) forms or whatever. Requiring a programmer to use a completely
different syntax to *turn on* a low-level optimization is backward.
Having control over how the compiler weights various trade-offs is
good. Having to formally request help from the compiler with a "yes-I-
the-programmer-can-see-this-is-a-tail-call" form is a pain.
From: Frode V. Fjeld on
"josephoswald+gg(a)gmail.com" <josephoswald(a)gmail.com> writes:

> [...] Requiring a programmer to use a completely different syntax to
> *turn on* a low-level optimization is backward. Having control over
> how the compiler weights various trade-offs is good.

I find this completely backwards. If your code depends on TCO, then by
definition it is not a low-level optimization, it is rather the required
semantics of your code.

> Having to formally request help from the compiler with a "yes-I-
> the-programmer-can-see-this-is-a-tail-call" form is a pain.

Again, if your program requires TCO then the programmer must know and
see that "this is a tail call". See any introductory textbook on "tail
call style" iteration and you know that the programmer must be painfully
aware of whether a particular call is a tail call or not, sometimes
twisting the code inside out to make it so. The only difference is
whether this required aspect of the program's semantics will be explitly
manifested in the program text or not. For the maintainer of said
program, having these required semantics explicitly and plainly
expressed would be a pleasure, I'm sure.

--
Frode V. Fjeld

From: Pascal J. Bourguignon on
Elena <egarrulo(a)gmail.com> writes:

> On Aug 6, 10:43�am, Pascal Costanza <p...(a)p-cos.net> wrote:
>> Here is a way how to do TCO in Common Lisp:http://groups.google.com/group/comp.lang.lisp/msg/8f9dcf58a00aca27
>>
>> It can't be implemented as just a macro, because it requires the
>> cooperation of different parts of a program. You can only do that as a
>> "real" language extension.
>
> Thanks for the link, Pascal.
>
> IMHO, that would be a better way to make TCO available, that is: TCO
> should be explicit, since you know beforehand whether you want your
> function to be tail recursive or not. Then, whenever you fail to
> implement a tail recursion among mutually recursive functions, the
> compiler should complain. If I'm not mistaken, OCaml has (somewhat)
> explicit TCO. Or detecting such errors would better be left to test
> cases?

You're all forgetting something.

In Common Lisp, most tail calls ARE NOT tail calls.

This is because of dynamic binding. Not only of variables, but also
of unwind frames, a lot of them are hidden in with-* macros, catch
frames, condition handlers, restarts, etc.

So even if TCO was mandatory, it couldn't be applied often in Common
Lisp programs.



--
__Pascal Bourguignon__ http://www.informatimago.com/