Node.js is genuinely exciting
simonwillison.net
simonwillison.net
People who are already comfortable with programming with events and closures in Javascript are going to try Node and say things like "where has this been all my life?". In those few short days Node has highlighted to me just how dramatic of an impact a tool that is close to your language/model of choice can have on your ability to rapidly turn ideas into working code. For a cross section of coders that work with jQuery all day, Node will be a big deal.
Node has some really friendly and highly productive people working behind it, chief among them Ryan Dahl ( http://github.com/ry ). To learn Node's ins and outs and have some fun, I spent this weekend building out a simple node-based MapReduce-like work unit processor and needed a lot of random help along the way. When I needed gzip ( http://github.com/waveto/node-compress ), or to communicate with Unix command processes, or a redis client ( http://github.com/fictorial/redis-node-client/ ), the Node community was there to help me very quickly.
Simply said, Node.js is a very productive and fun environment for weekend hacks, and I expect it to become a primary fixture in my toolbox in the coming months.
[edit: added links]
Now imagine implementing a normal http controller. You have to do say 5 MySQL call (or redis, whatever) to get all the data you want. This means that you have to nest together 5 closures. Now if any of the methods fails and there is no global error handler that disconnects the client then that means that the connection will hang forever until the browser user hits the stop button. Spotting these situations becomes really hard with complex code.
Futures ( Go channels ) solve this because they block the thread when someone accesses the data. If you want to do 3 db calls you can just write familiar code:
var a = db.select(...); var b = db.select(...); var c = db.select(...);
print c #=> blocks until c has returned
I haven't done that much of asynchronous programming, but I think you end up creating some helper constructs that help prevent excessive nesting. For example you could create a function that takes an array of functions and calls them sequentially (in the sense that when the first callback is executed, it calls the second function and so on).
var a = something_async(), b = something_else_async();
Upon calling something_async, the code starts waiting and blocks further execution until it is ready, going to the next statement. This is not a foreign concept at all, and is used in javascript as well with alert, prompt, confirm:
fries = window.confirm("Do you want fries with that?")
confirm is an async method (has to wait for the user), but the next line is not executed until it returns. I personally see no advantage to creating a system of callbacks:
do_x(function () { do_y(function() { do_z() }) })
when this would be much more readable:
do_x(); do_y(); do_z();
and would have the exact same perf characteristics. In fact, you could probably simpy code transform the latter into the former (I know this is what stratified JS does), although this is probably the worst way to do it. What you really want is to just auto-call "wait" on every promise (I believe wait still gives you the asynchronous benefits).
Of course, the main "drawback" to this is that you need language support to pull it off, so you need to implement a preprocessor of some sort.
And yes, both asynchronous and synchronous operations have their place, umm, except perhaps in Haskell where things get funky. Chaining async operations together in javascript can be tedious, but its easy enough to write a helper function to handle it for you. Every javascript app I've written that uses AJAX always has some form of createCallback(context, function, arguments) function.
I'm very surprised that not more languages implement this pattern. Maybe i'm missing something but this is the major feature of GO, except that almost everyone missed it and focused on the fact that it compiles fast and looks like c
do_x();
do_y();
do_z();
Ideally those three should not even be dependent on each other (FP to the rescue). They should absolutely not block if you're going to write your code this way. If they are dependent and need to block they should be written this way: do_z(do_y(do_x()));
Each one delivers a promise for it's computation. All you need is custom events and function decorators. Port my library Promises.js to Node.js ;) It's only about 300 LOC (another 5 or so to implement function decoration).var result = do_x() + do_y();
and could. Again, if I understand the documentation for node.js correctly, simply automatically appending a .wait() to every promise returned should in theory give you this behavior (and be as performance/non-blocking/etc) as the other method.
var resultp = add(do_x(), do_y();
do_z(resultp);
do_foo();
You're code will block on add. This code only blocks on unrealized promises, that is do_foo gets to execute. This is _more_ concurrent.It's my opinion that JS is the new lingua franca of programming, and it's about time we replaced C/Java. It has consistent syntax, some great functional aspects, dynamic typing, and it's now become a top target for optimization by some of the world's smartest engineers.
Breaking into systems coding is the next step, IMO, in JS becoming a legitimate option for "anything" programming. I think node.js is going to be the library for it. It's really idiomatic and concise, and it's got just the right amount of opinionatedness I think to become the systems and JS version of Rails.
Indeed. And its new incarnation, ECMAScript 5, fixes many problems with the existing language and makes it a lot more powerful and better suitable for programming "in the large".
Steve Yegge beat you to it: http://steve-yegge.blogspot.com/2007/02/next-big-language.ht...
I'm saying that I think that this is JavaScript's first implementation in the wild that I've liked enough to want to do non-web programming in.
I'm not so excited by this guy writing an HTTP server in JavaScript. I'm excited about the potential of JavaScript in writing elegant, high-performance apps that aren't tied to the web.
#1 C-like syntax (might be closer to Ruby actually)
#2 Static-typing but feels pretty dynamic due to extremely good type inference
#3 Perform on par with plain Java
#4 IDE(Eclipse/NetBean) support
#5 Everything in the "Kitch sink" section included + Actor-based threadless concurrency + easy to write embedded DSL + (I heard even continuation is coming soon). So what's missing is a macro system ...
#6 JVM so multiplatform by default (even on Android)
Isn't java.nio supposed to provide non-blocking IO (at least for socket)?
http://paultyma.blogspot.com/2008/03/writing-java-multithrea...
Even on Android what? Which Scala based project I could run on Android unmodified?
Where I can get JVM for linux/bsd on ARM?
And to me it seems that learning a new programming language (even one using a relatively obscure syntax), is a much simpler task than designing an entire project (or piece of a project), around a language that doesn’t really fit the needs of a project.
To that extent, I think that the idea of a ‘lingua franca’ language is an inherently broken metaphor. Programming languages are closer to human-computer interaction tools than they are natural languages. ‘Lingua franca’ implies that every language can communicate approximately the same thing (it is just a matter of who has influence). I think this is a mistake, as different languages allow you to think in hugely different ways about programming. Different languages have different intrinsic concepts.
It may be that this argument boils down to ‘if all you have is a hammer, everything looks like a nail,’ but even that is an oversimplification, as I don’t even use the same hammer for all types of nails (tack hammer, framing hammer, etc).
I am not saying that node.js is necessarily a bad thing to have. It may turn out that Javascript is indeed particularly well suited to this type of application. Superficially, however, nothing convinces me that this is some sort of exciting home-run-win situation (or that it is any better than any other functional-style programming language).
Could you explain the excitement and appeal to me?
I don't think JavaScript will cover every paradigm in the sense of obscure language concepts, in that it will likely never have Lisp's complicated macro system or Ruby's ability to make really fluid DSLs. I don't want it to; the appeal to me is that what's going on in JavaScript is almost always self-evident (if you avoid the bad parts). () means you're calling a function or forcing operator association. {} means you're defining a block, array, or dictionary.
I do think, though, that it could establish the new minimum standards of the 'demo language' for an algorithm. For algorithm demonstration and sharing, I think it's absolutely awesome that there is a language that is now capable of doing anything you want with an interpreter (albeit DOM-confined) pre-installed on every single computer you use. I don't want to read Wikipedia algorithms in some hacked-up Pascal. Give me something I can run now, but that's universally understood: a strong common medium to explain programming languages in unobfuscated terms.
There's not much I can say that I didn't already say in my blog entry. JavaScript is designed for event-driven programming in the browser, and my brief experience with node.js makes me believe that it also works well for event-driven programming on the server. And V8 is really fast.
As for Erlang... when you're programming for the web, it's useful to have a programming language that treats strings as more than just an array of integers.
http://www.erlang.org/cgi-bin/ezmlm-cgi?4:mss:47293:200911:d...
(You can either think that he is biased or that he would be an expert on it).
I mean, it seems to me that javascripts main advantage in programming for the web would be DOM manipulation. And that is good, but a lot of languages can do it. (Honestly I've never really done (much) direct string manipulation for web programming).
It doesn't seem to me that javascript really has a monopoly on event driven programming either. It is relatively easy to do that sort of thing in almost any other functional style language...
What popular languages are cooler than JS? Maybe Ruby, but for my taste there is too much metaprogramming in Ruby which makes it very hard to master. I like the extreme simpleness of JS (basically everything is a hash, that's it).
Though I must admit that now that it looks like it has a shot at being the language for everything, I am getting second thoughts. Those brackets can get ugly - something with a slightly cleaner syntax might have been preferable. But all current languages have their pros and cons, and JS doesn't fare badly in copmparison.
For example I think Ruby takes it too far - you can get clean syntax, but the tendency to create something like a DSL for everything is also a burden for learning. Plus, Ruby is still too slow for a lot of tasks.
Could you explain the excitement and appeal to me?
Yup. Javascript combines several elements that give it a reach for high power.* Javascript is a prototype-based language. I find this to be a better way to write software than other approaches.
* There's a good ometa implementation for javascript. Ometa is a powerful ways of writing domain specific languages.
* Modern JVMs support javascript, meaning that anything you do in javascript can be adapter to leverage existing Java codebases.
* Combination of javascript on both the client and server will likely expose new possibilities. For example, I've been thinking about the possibility of a 'builder' app in javascript whereby you use a firebug console to dynamically build a form and attach business logic to it and then freeze it back to the server. Yes, you could do it at the moment, but it's less effort if you only have one codebase to think about. The thread of bloat in the client becomes less of a problem with new approaches to development like Google Gears, also.
Node.js is an important foundation to javascript establishing itself as a viable server-side language. At a glance, it looks to be a good balance of what's needed, also.
This is what's interesting, I think. The reason Erlang does so well at this is that stuff written in Erlang basically just doesn't block because a scheduler sits under the whole thing.
> Node creator Ryan Dahl has a stated aim for Node to never provide a blocking API—even filesystem access and DNS lookups are catered for with non-blocking callback based APIs.
So that's the tricky bit, I suppose, especially as your language/environment grow, and people start doing random stuff with it.
BTW, it's also worth mentioning that Tcl has had a nice event system since well before Twisted came out, built into the language. However, like Python, you can't count on random commands not to block, so you have to be careful.
Edit: Or Events in EventEmitter are being executed one at a time, so there is no need for locks?
Don't get me wrong here, I love coding in Javascript and have often entertained the idea that server-side Javascript would be fun. I also totally buy the need to get away from thread-per-request for many web serving scenarios, Comet being a perfect example.
However when I see someone going so far with this as to say "all APIs must be non-blocking" I have to wonder if they would be better served by using a language where threads were less expensive. I know closures make this kind of thing a lot less of a pain than back in the day when we were programming against OSs with no threads and async APIs were often a necessity, but to mandate this style is basically asking developers to manually rewrite all of their logic into continuation passing style. It's a bit, well... naive is the kindest word that comes to mind.
BTW, I don't think it's a coincidence that all of these event-driven web frameworks are for interpreted languages with crappy thread support.
The server is supposed to continue responding to incoming requests even while it is waiting 2 seconds for previous requests. So I figured that if I quickly queued up a bunch of requests (say, over the course of one second), they would all respond just as quickly after the two seconds was up.
However, each response came a full 2 seconds after the previous response. I increased the wait argument to 10 seconds just to be sure.
This seems functionally equivalent to blocking. Is this the way the example is supposed to work?
I was naively cranking out a bunch of tabs in Firefox really quickly. :) I guess Firefox doesn't make concurrent requests when it's the same URL...?
If the event bus has executors (which it could in v8), it will be parallel to boot.
I have been doing a lot of Javascript/jQuery UI stuff at work lately and have become VERY comfortable with the anonymous callbacks and such. Now I'm ready to jump on Node and see what I can do. This looks awesome!
This, however, looks really cool. I've been waiting for a compelling JS server side framework for awhile—definitely going to have to check it out. I hope other people aren't making the same mistake.
That's the deal maker for me... To have custom defined events. Correct me if I'm wrong but even Twisted doesn't have this facility?
Otherwise, it's a matter of preference. What's the main advantage of PHP/Ruby over Perl?