> > Used in some Lisp implementations, a trampoline is a loop that iteratively > invokes thunk-returning functions (continuation-passing style). A single > trampoline is sufficient to express all control transfers of a program; a > program so expressed is trampolined, or in trampolined style; converting a > program to trampolined style is trampolining. Trampolined functions can be > used to implement tail-recursive function calls in stack-oriented > programming languages.
All a trampoline does is implement the same optimization that tail-recursion would have done automatically had it been there. Practically this means that a recursive nextTick loop using the proposed semantics will run in constant stack space and never stack overflow. So it's behavior will be just a while(true){} loop from that point of view. A simple implementation of the new nextTick could be: var nextTicks = []; function nextTick(fn) { nextTicks.push(fn); } Then after every real event source tick finishes we could flush the nextTick queue: function runNextTicks() { var next; while (next = nextTicks.shift()) { next(); } } Since the nextTick calls don't call the callbacks on their own stack, the stack never grows. Every next() call starts from the one runNextTicks call at the end of the event tick. Read the gist comments for the full discussion on this. https://github.com/joyent/node/issues/3335 On Tue, May 29, 2012 at 1:16 PM, Marco Rogers <marco.rog...@gmail.com>wrote: > I should probably not use words unless I'm sure what they mean :) Pardon > my ignorance a bit here. I probably need to be educated about this subject. > I've got a few comments though. > > What I mean is that if this change happens, the potential for exploding > call stack should be handled. I think the trampoline technique is one way > to do that. But if I understand it correctly using a generic trampoline to > kill the stack at some predetermined time would just make things messy. > Forget trampolines. > > The more I think about the original problem, the more I think nextTick > does exactly what it should do, and we need something else to ensure that > people don't miss data. setImmediate seems a likely candidate. But it's not > clear to me how the semantics differ from setTimeout(0). What I'm hearing > is that the way it will work in node is that a callback set with setTimeout > will go on the current tick queue immediately. So it will be guaranteed to > be executed and run to completion before the event loop yields to any i/o > operations. Is that accurate? > > If that is accurate, how does it compare to the implementation proposed by > Microsoft and implemented in IE ( > http://ie.microsoft.com/testdrive/Performance/setImmediateSorting/Default.html)? > If they're not exactly the same semantics, that could create some > compatibility problems. It also looks like setImmediate is not in going to > be standardized. For that reason I would recommend putting it on the > process namespace instead of a free global. If it ever does become a > standard, it'll be easier to stay backwards compatible by sticking the new > version onto process. > > As for the potential for recursive callbacks. Isaac makes a good case that > it's seems the same normal infinite recursion. But this is not a normal > environment and doesn't look like normal recursion. I think it's very > likely people will mistakenly do this. Especially since we've been training > people that when you do nextTick or setTimeout/setInterval, that it won't > lock up your event loop. For instance, this is a common js pattern. > > var doThing = function() { > // do some thing interesting > > setTimeout(doThing, delay); > } > > setTimeout(doThing, delay) > > This is an alternate pattern to setInterval that makes sure your current > job is complete before re-running. But we tell people that "nextTick is > like setTimeout, only more efficient". So in node, people do this. > > var doThing = function() { > // do some thing interesting > > process.nextTick(doThing); > } > > process.nextTick(doThing); > > With the proposed change, this will now starve your event loop right? But > it looks perfectly reasonable. If your program locks up or you get an Error > from this, that would definitely violate least surprise in my mind. > Avoiding starving the event loop is critical to a working node program. > With this change, that task is just a little harder. > > :Marco > > On Sunday, May 27, 2012 3:49:55 PM UTC-7, Jorge wrote: >> >> On May 27, 2012, at 8:38 PM, Marco Rogers wrote: >> >> > Early post cause I'm on my phone. In short, I think the new behavior >> should definitely have trampoline behavior to prevent starvation. >> >> What do trampolines have to do with starvation? >> >> -- >> Jorge. > >