getify / monio

The most powerful IO monad implementation in JS, possibly in any language!
http://monio.run
MIT License
1.05k stars 58 forks source link

Known Issue: call-stack overflow with long chains #9

Closed getify closed 2 years ago

getify commented 2 years ago

If you do io.chain(..).chain(..)....... (or map(..) or concat(..)) a whole bunch of (over 10,000) times, you eventually overflow the call stack. Same thing with doing lots of yield io in a do/doEither routine.

And all the same goes for IOx.

This is a significant defect in the design of IO/IOx in that it requires a significant refactoring to use a form of trampolining to prevent the call-stack from building up and overflowing. A trampoline of this sort is extremely complicated to design, and very intrusive to wire into IO/IOx.

Some progress has been made, but this remains not fully addressed.

getify commented 2 years ago

Update: So far, as far as I can tell and test, IO's trampolining is fixed. I have tests in the IO test suite that go up to 25k iterations (which should go well beyond the normal call-stack if trampolining wasn't working). I have even run these tests at 10x that length (250k iterations) without error, though the delay (while running the test suite) was too long to comfortably leave in.

However, IOx trampolining is not addressed at all yet, and I don't yet know how to even do so, given the internal structure of IOx's implementation. I had hoped that IO trampolining would magically "fix" it, but alas it did not.

getify commented 2 years ago

This was incredibly challenging to get trampolining threaded through all of IOx. I am mostly confident that's now working (added quite a few tests), so closing this for now. But there are so many corner cases around call-stack depth, this issue may have to be revisited in the future.