4 ms·
This presentation has a tiny bit on coroutines: http://nodejs.org/jsconf2010.pdf http://nodejs.org/jsconf2010.pdf > Coroutines complicate the mental model whi
by felixge2 16y ago
This presentation has a tiny bit on coroutines:
http://nodejs.org/jsconf2010.pdf http://nodejs.org/jsconf2010.pdf
> Coroutines complicate the mental model while adding only cheap syntactic pleasures.
- kevingadd 16y agoThe statements made about co-routines/cooperative threading and the stated reasoning for removing them makes me wonder whether the decision to remove them was made based on benchmarking and experimentation or just based on taste. In my experience they simplify many forms of asynchronous logic tremendously and can have performance benefits as well, as long as you're not forced to use them for everything. I suppose someone who wants them in node.js can just reimplement them as an extension.
- felixge2 16y agoWell, just as there is the problem of thread-safety, there is also the problem of co-routine safety. Basically callbacks and coroutines don't play well together. But there were a bunch of reasons for the removal, performance and quality of the initial implementation also played into it AFAIK.
- kevingadd 16y agoIf you implement coroutines as a state machine they integrate just fine with callback-oriented APIs. But perhaps that was the problem since the PDF mentions stack swapping.
- jules 16y ago> Basically callbacks and coroutines don't play well together. Can you elaborate on this? I thought the opposite: coroutines play very well with callbacks. Callback libraries force you to write programs in continuation passing style. Coroutines let you write asynchronous programs in normal style. Lets assume we have an asynchronous readAsync(callback) function that reads a number and calls the callback with the input when it's ready. Now you're writing your program like this: readAsync(function(x){ readAsync(function(y){ write(x+y) }) }) What you want to write is this: x = read() // may block this coroutine, but *not* the entire program y = read() write(x+y) This can be achieved with something like: function read(){ coro = getCurrentCoroutine() var result callback = function(x){ result = x; coro.resume() } readAsync(callback) yield // stops the current coroutine until it is resumed return result } It seems to me that this is a general way to adapt any callback style library to coroutines.
- makmanalp 16y agoActually, that's not a very good argument. The answer to that is "to you, maybe". The better argument is this one: "Must worry about I/O occurring in all function calls. (They might call wait().) The user needs to make their functions coroutine safe!" I think this is the reason why coroutines are more popular in functional programming languages where side effects are limited by style or by enforcement of the language itself.
- felixge2 16y agoYes, other languages might be more suitable for coroutines. But then again, Erlang is probably a language more "suitable" to high concurrency programming, but node's goal is to make writing scalable networks programs possible for everyone. One might call it the PHP of concurrency : )
- jules 16y agoThat is not a good argument either. If you are going to write your entire IO library in asynchronous style like node.js then you could easily make all IO routines coroutine safe. In fact you have exactly the same problem whether you use coroutines or not. If you have a nice asynchronous program and I call wait in the middle that's going to hurt you in the same way.
- felixge2 16y agoYou're correct, it would not be impossible to write coroutine safe code in node.js. The problem is just that coroutines are not natural in JS, and people will shoot themselves in the foot all the time. Some "features" are better left out to allow a bigger audience to write reliable Software. Your milage may vary.
- jules 16y agoPerhaps, but in my experience using coroutines is easier than using callbacks because coroutines make code look the same as if it was synchronous. readAsync(function(x) { readAsync(function(y) { write(x+y) }) }) vs x = read() y = read() write(x+y) You don't really need to know how to use the full power of coroutines if you just want asynchronous operations. You just need to know that read() may block the current coroutine.