Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The problem this solves is a serious one, in my experience, even though I find their choice of syntax rather curious. Given that JavaScript 1.7 introduces the yield keyword, it would make sense to add support for that to V8 and implement the infrastructure for concurrent asynchronous I/O around that as a library. The concurrency aspect is, after all, orthogonal to the blocking vs. callback situation, and can easily be done even when using callbacks, with a single callback function called upon completion of all concurrent I/O. I believe the Dojo framework provides such a utility, and I wrote my own simplistic stand-alone mini-library for exactly this a while back. [0]

I've run into the problem of endless chained callbacks in C, where it's much worse due to the lack of nested functions, let alone closures or garbage collection.[1] I ended up using the switch block "coroutine" hack [2] for the worst cases, along with dynamically allocated "context" structs to hold "local" variables. A proper macro system would have helped transform blocking code into CPS form. I tried to integrate a SC [3] pass into our build, which could have done it, but ran into all sorts of practical/yak shaving problems, so I ended up with the C preprocessor macro/switch solution for now. In user space, explicit stack-switching with something like swapcontext() is probably preferable, if you can get away with it, but in the kernel this is rather problematic.

[0] https://github.com/pmj/MultiAsync-js

The reason I wrote my own was because I originally needed it in Rhino, the JVM-based JS implementation, and I couldn't find anything similar that worked there.

[1] Yes, there are garbage collectors that work with C, but to my knowledge, none of them can be used in kernel modules. In any case, the other 2 issues are worse and aren't solveable within the language via libraries.

[2] http://www.linuxhowtos.org/C_C++/coroutines.htm

[3] http://super.para.media.kyoto-u.ac.jp/~tasuku/sc/index-e.htm...



My first thought for implementing tame.js was with yield, but V8 doesn't currently support it (though it's reserved as a "future" keyword). A direct use of yield (without anything like twait) would probably make node code look more like Python/Twisted code, which while better than the status quo, still can get unmanageable in my experience.

Agreed that twait conflates concurrency with blocking/callbacks, but it my experience, it's a natural and useful combination.


I think you could do something manageable with yield alone (at least with python-style generators). I've been meaning to try something like this with tornado. The general idea is that yielding would either immediately produce a callback or asynchronously "wait" for a previously-generated callback to be run. It would look something like this:

    doOneThing(yield Callback("key1"))
    andAnother(yield Callback("key2"))
    res1 = yield Wait("key1")
    res2 = yield Wait("key2")


True, you wouldn't get the syntactic sugar of the result variables - you would have to return them as an array or object with named properties. Lack of V8 support is of course the killer, and when I wrote my original comment, I for some reason assumed you'd modified V8 (at which point you may as well have implemented yield), but it turns out you just do the CPS transform in a preprocessing pass. Nice!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: