On Mon, Sep 29, 2014 at 12:19 PM, Steve Fink <[email protected]> wrote:
> On 09/29/2014 09:14 AM, Sam Tobin-Hochstadt wrote: > > On Mon, Sep 29, 2014 at 10:55 AM, John Lenz <[email protected]> > 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 > [email protected] > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

