Maximally minimal stack trace standardization

John Lenz concavelenz at
Mon Sep 29 15:08:07 PDT 2014

On Mon, Sep 29, 2014 at 12:19 PM, Steve Fink <sphink at> wrote:

> On 09/29/2014 09:14 AM, Sam Tobin-Hochstadt wrote:
> > On Mon, Sep 29, 2014 at 10:55 AM, John Lenz <concavelenz at>
> wrote:
> >> I really have no idea what the behavior should be in the faces of
> optimized
> >> tail calls (which is must broader than simply self recursive methods
> that
> >> can be rewritten as a loop).   I've seen various suggestions (a capped
> call
> >> history) but I'm curious how efficient functional languages deal with
> this.
> > Different functional languages do a variety of things here:
> >
> > - simply show the current stack, without the functions that made tail
> > calls (this is probably the most common)
> > - have a bounded buffer for stack traces
> > - implement tail calls via a trampoline; this has the side-effect that
> > the stack has "recent" tail calls in it already
> >
> > I'm sure there are other choices here that people have made.
> "Stack traces" are really an overload of (at least?) 3 different concepts:
> 1. A record of how execution reached the current state. What debuggers
> want, mostly.

This is also important for server side reporting of client side error,
which while similar, is not the same as an optionally debugger activated.

> 2. The continuation from this point on - what function will be returned
> to when the current function returns normally, recursively up the call
> chain.
> 3. A description of the actual state of the stack.
> In all of these, the semantics of the youngest frame are different from
> all other frames in the stack trace.
> For #2, thrown exceptions make the implied continuation ordering a lie,
> or at least a little more nuanced. You sort of want to see what frames
> will catch exceptions. (But that's not a trivial determination if you
> have some "native" frames mixed in there, with arbitrary logic for
> determining whether to catch or propagate an exception. Even JS frames
> may re-throw.)
> Inlined functions may cause gaps in #1 and #2, unless the implementation
> takes pains to fill them in with dummy frames (in which case it's not
> really #3 anymore.)
> Unless the implementation plays games, tail calls can make #1 lie as
> well. You really called f(), but it doesn't appear because its frame was
> used for executing g() before pushing the remaining frames on your
> stack. Tail calls don't really muck with #2 afaict.
> All three meanings are legitimate things to want, and all of them
> require some implementation effort. Even #3 is tricky with a JIT
> involved. And I'm not even considering floating generator frames, which
> may not fit into a linear structure at all. Or when users want "long
> stacks" for callbacks, where the stack in effect when a callback was set
> is relevant.
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list