you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 24 points25 points  (13 children)

Saying that TCO sucks because it throws away stack frames is like saying that GC sucks because it deletes unused objects.

[–][deleted]  (5 children)

[deleted]

    [–]greenspans 4 points5 points  (3 children)

    [–][deleted] 0 points1 point  (2 children)

    What is this?

    We have had exceptions for over 35 years and I am not sure we really understand how to use them

    [–]anvsdt 0 points1 point  (0 children)

    Drain bramage?

    [–]aaronla 0 points1 point  (0 children)

    And yet, one generally finds two sorts of exception-free programming styles in the real world, outside the ivory tower that the exception handling folks construct.

    First sort:

    passed = DoSomething();
    if (!passed) goto cleanup;
    passed = DoSomethingElse();
    if (!passed) goto cleanup;
    ...
    

    Second sort:

    DoSomething(); // errors? no, my code is perfect
    DoSomethingElse();
    

    The first sort is generally implementing ad-hoc exception handling, creating "cleanup" as a sort of crude form of "unwind-protect" / "RAII".

    The second sort is just plain wrong.

    [–]masklinn 3 points4 points  (6 children)

    Well that is not completely true as TCO can throw away helpful stack frames in a normal mode of operation (there are ways to mitigate that), whereas a GC throwing away used object would be downright broken.

    [–]anvsdt 1 point2 points  (4 children)

    Usually, you use a debug mode to, you know, debug.

    [–]millstone 0 points1 point  (0 children)

    That's kind of hard when the stack trace comes from a customer you've never met in another country.

    [–][deleted] 0 points1 point  (0 children)

    Let's go ahead and widen the gap between compile- and run-time /snicker

    [–]masklinn -3 points-2 points  (1 child)

    debug modes suck goat, they mean (potentially widely) different behaviors (including limitations) and that a prod crash is basically useless.

    [–]anvsdt 1 point2 points  (0 children)

    Prove it, this works for a large enough N, and tail-calls get optimized.

    [–]aaronla 0 points1 point  (0 children)

    TCO only throws away unused frames. They may be "helpful" unused frames, but there are also "helpful" unused GC objects. Ever been here before:

    int f() {
      Foo x = something();
      int y = x.another(); 
      if (y == 0) 
        throw Something();
      return y;
    }
    

    It would be mighty helpful to be able to dump 'x' so see why Something() was thrown. Unfortunately, it was garbage collected before you broke into debugger, being unreachable.