Node has shared memory between actors, having multiple async code flows executed on shared memory that appear to be sync by design is very hard to do. This leads to implementation specific behavior unless we standardize edit resolution. Most people who complain about nested callbacks generally forget that you can abstract away event delegation to objects and objects can manage multiple states. Also, if you are nesting many callbacks, you should probably try to split up the functionality to logical pieces, our code base of 20k+ lines of Node rarely if ever sees more than 3 nested functions (including the original invoker).
While memory resolution is possible and able to be standardized it can prove difficult when working with Native object where state of memory may be cached in C/C++/etc. Web workers have provided a nice share-nothing abstraction that is probably more suitable than overhauling the fact that closures can share the same memory. On top of this, critical expectations of sync behavior would require any memory access that could affect the shared memory be either locked and prevented or rolled back at a later time. The DOM's live NodeLists are a good example of shared memory causing issues in this area, proposing all proxies be allowed to do this is would require the same care that every time we deal with a live NodeList requires. Even worse, libraries must support this, similar to how a few libraries that break when a script in strict mode invokes them but unlike frowned upon features, we are talking about every feature that a proxy has would have to be guarded for this. Monads through callbacks instead of hiding async behavior through proxies is a better idea not just because of the complex compilation changes needed to support this, but also because a user of an API can expect for something to have an unknown return time with callbacks. Explicit behavior will always be more appropriate than "magic" async behavior appearing synchronous with shared memory is what leads to hard to debug race conditions. Semaphores will become needed to lock resources that merely *may* be affected by something that *may* be occuring but is not guaranteed to be. Having the compiler do this would lead to nightmares. Not sharing memory between concurrent flows of control and not splitting flows of control that may have preemption is much more sane. If you wish to discover more about this I would suggest looking at the solutions in shared memory systems for C++, Node, and Java. C++ and Java will be using semaphores to cage potential race conditions, while Node generally can get away with counters (we have seen cases where when we have to use workers we rely on semaphores so I would suggest looking at process race conditions in these as well). Cheers, Bradley _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss