The Node Ahead: JavaScript leaps from browser into future
theregister.co.uk
theregister.co.uk
I've actually spent a lot of time with Node since the company I work for was an early adopter. This all based on opinion but, my general feeling about Node is that the underlying concept is great but, Javascript is an awful language to do it all in. The lack of real support for continuations (and/or coroutines) means there is no escape from the callback hell and tracking down errors can be a real nightmare. Ultimately for simple projects Node works fine but reach a point where your application becomes at all complex and things can get hairy real fast (of course this statement could be made about client side Javascript as well).
I say this not to discourage anyone from trying Node because for many projects Node may be just what you need but, there are some downsides one should probably keep in mind.
Thread safety problems are all about data changing in between your statements due to some other threads. Coroutines make that happen only along calls to other routines, which is very disciplined.
Note: this is just my impression.
http://newsgroups.derkeiler.com/Archive/Comp/comp.lang.javas...
about this video
http://developer.yahoo.com/yui/theater/video.php?v=dahl-node
mentions "He's also agains the use of co-routines because they're too hard"
I still don't know enough to take sides, but the thread I just linked helped me to better understand the issue.
do_something_and_then(function (){
do_another_thing_and_then( function (){
say "we're done!"
});
});
to: do_something;
do_another_thing;
say "we're done";
Coroutines are one way of doing this, but source rewriting (Haskell-"do-notation"-style) also works.An instructive example is the Coro module for Perl (which is a bit more coroutine-ish, as it provides separate perl and C stacks for each async action, etc.): http://search.cpan.org/perldoc?Coro
It lets you write something like:
async {
my $t = AnyEvent->timer( after => 5, cb => Coro::rouse_cb );
Coro::rouse_wait();
say "OH HAI";
};
instead of: my $t = AnyEvent->timer( after => 5, cb => sub {
say "OH HAI";
});
This may look like it's not an improvement, but it is after you add some sugar: sub sleep($) {
my $seconds = shift;
my $cb = Coro::rouse_cb;
my $t = AnyEvent->timer( after => $seconds, cb => $cb );
}
async {
sleep 5;
say "It's been 5 seconds!";
sleep 10;
say "It's been 15 seconds!";
};
instead of: my $t; $t = AnyEvent->timer( after => 5, cb => sub {
say "5";
$t = AnyEvent->timer( after => 10, cb => sub {
say "15";
undef $t;
});
});Edit: I love coffeescript - prefer it to JS when using node - but I still can't build a web app in a single file on ~/public_html on a shared webhost. Yet.
cat ~/public_html/index.php
<?php
echo("Hello, world!");
?>
All a would-be programmer needs to get rocking in PHP is basic HTML knowledge (check w3schools for instance), an FTP client, and a link to the online PHP manual with its searchable index and extensive sample code. Getting to that point with Node is still a ways off. npm install fibers
Also, node's cb-passing stuff is pretty close to the very canonical examples of CPS in Scheme, so I'm not sure what you mean by it not having continuations.I really enjoyed the article because it approached node.js as it should have, as the new way of doing things on the server. I see node.js becoming as ubiquitous as ruby/python/perl are on the server (maybe even for desktop applications).
Even if node.js doesn't become as big as I think it will, I feel that the shift is has helped cause is a positive one for the server space and we will all benefit from it.
Email me gustaf@voxer.com if you want to know more and I'll connect you with the right person.
Our servers are built out of Node.js, CouchDB, and Redis. If you are excited about node, server-side JavaScript, and new databases, this is an opportunity to work on this technology full-time.
If they sincerely believe that Erlang offers a superior alternative to Node for what the influx of new Node developers need, then they should be looking to provide resources to help these devs "graduate" to erlang.
Not once have I seen a blog post saying "Like Node.js? Then you're going to love Erlang! Let me show you why it's better, with some snippets to compare and contrast."
One could compare Node.js to Twisted, Tornado or EventMachine. However, comparing Erlang to Node.js is somehow weird as they have different paradigms — Erlang is highly-concurrent with its "green" processes, while Node is single-process single-thread with "asynchronous" paradigm.
(However, there are some aspects, that could be compared. Erlang has "let it crash" motto, while in Node.js one has to be careful with any exceptions. Erlang is distributed and Node.js has no notion of processes.)
Shell is not a language optimized for stability. It is optimized for interactive use, above all else - it's not even a very good scripting language, even though it's historically been used that way an awful lot.
Python is not a language optimized for stability - it's not even mentioned in the Zen of Python: http://www.python.org/dev/peps/pep-0020/
The primary focus of Java (at the time of it's creation) was "write once, run anywhere". The primary focus of Java (now) is "languages that compile to JVM bytecode are nifty - plus, we have C-like syntax but are a high-level language".
The primary focus of Erlang, before and above anything else, is program stability. OTP exists to increase stability. "Let it crash" exists to increase stability. Parallelism and message passing are in the language not because they're neat, but because (if they are used at all sensibly) they will increase stability.
Still I cannot see why this is a cultural issue that keeps developers away. Missing things like good string-libs, or ",;." syntax hassles, ok. But stability-features?
The point you address for C is , in a way, also valid for Erlang. It's your program which has to be stable, the language just offer you supervisors and independent processes. "Write it correctly" is the only way to achieve that goal, Erlang does not help you with that. Could be that messing up an OTP behaviour is as easy as dereferencing a null pointer... (disclaimer: I'm no Erlang developer)
Given the fact that there already exist bridges that can take javascript snippets and run them in sub-processes within erlang I am really surprised that no one has bothered to do a "enode" system that just provides a node-like api for the callouts to the javascript processes.
couchdb can only run javascript functions on json objects, and really only to transform those objects into other objects. last i checked, it has no way of interacting with the erlang node it's hosted on.
Python isn't slow by any means, but I think for what they were trying to do, node.js really fit their use case better. Being able to hook up so many different types of functionality all into one 'application' is really freeing especially considering how approachable it is.
Look at the AnyEvent:: namespace on search.cpan... there's a quite a bit of stuff there. Everything that Node has, and more.
You should use Node because you like Javascript, not because other languages don't have as good of libraries... because other languages have as good of libraries.
http://developer.yahoo.com/yui/theater/video.php?v=dahl-node
In it, Ryan makes an important point about JavaScript being a natural fit because it was designed for a constrained environment. In particular, there is no way of doing I/O in JavaScript's traditional browser environment without providing a callback argument (I'm not counting interacting with the DOM as I/O here, and a couple of pedantic exceptions pointed out by judofyr below), and for the way in which the browser guarantees that only one callback will be executed at a time.I think this idea of a constrained environment is very important. If blocking I/O functions are strewn about the APIs you have at your disposal, then programmers tend to default to using them.
The other point he makes is that often evented APIs are just missing from the underlying platform. Does every way of doing some sort of I/O in the universe of Python APIs have variants that take callback arguments? Even if the answer is 'yes' (which would surprise me) there is a minefield of blocking calls one would need to avoid in a disciplined manner.
...which may not be easy. Tell me: does myAwesomeFunction() do some blocking I/O under the hood? You can't tell from the name. Do the docs always make that clear, and provide an alternative with a callback?
Edited to include judofyr's exceptions — which bolster rather than undermine the point, because note that window.prompt's raison de'etre is to block for user interaction, and document.write is a RAM operation rather than disk or network I/O.
There is no way of doing I/O in JavaScript's traditional browser environment
without providing a callback argument.
What about `window.prompt`? Or `document.write`?(Man, I just learned about this site five minutes ago and it's already useful!)
For real i/o in JavaScript, look at AJAX: Callback based.
While being ridiculously fast it leaked memory like crazy. So I've found that there were almost no debugging tools (except for old good gdb) to find out what was going on. (I've heard that there are some changes like `node debug`, though. Should dig the archives and try code with latest Node version.)
I believe this was an inherent consequence of JavaScript and V8 being tailored to short-lifetime (milliseconds of DOM operations, then lazy waiting for events to fire) applications with low amount of events (user in-browser activity).
Nope, it's just bugs. Every programming language has memory-related bugs... just less of them as they get older.
If memory serves, 1.0 is not so far way... half a year? When node hits 1.0 and there is a perception of API stability, third-party development will likely explode.
I don't know whether to laugh or to cry... Node/JS may replace EventMachine/Ruby or Twisted/Python for quickly whipping up an evented app or service, but it will be quite a while before anyone would consider moving an erlang project to node. Node is little threat to the distributed, fault-tolerant, concurrent niche that Erlang occupies -- within that realm there is nothing you can do in node that can't be done better in erlang and a great deal of bulletproof infrastructure in the frameworks built up around erlang and its vm that node will never come close to.
Hubris much?
What he says is basically true. Node is never going to replace Erlang for the same reasons it will never replace C++. Erlang is simply different from Javascript and no amount of runtime improvement can change that.