Hacker News new | past | comments | ask | show | jobs | submit login
Drinking the Node.js Kool-Aid (querna.org)
89 points by shawndumas on Sept 11, 2010 | hide | past | favorite | 34 comments



Since we're talking about node...

I like async, and I like node. However, for plain jane dynamic web apps, with no real time needs, I see it as being more of pain than using Ruby (or Python, or whatever).

Why? JS syntax kinda sucks for dealing with day to day business logic. Ruby is just more clear and easier to work with.

I think using node.js by default is bad design. It should be isolated to the cases where you need it.


If you find the syntax to be a problem - you may find CoffeeScript (http://coffeescript.org/) interesting. It emphasizes the good parts of JavaScript while minimizing the warts, all wrapped up in very nice syntax.


Here's a fun example. Matz (creator of Ruby) contributed a chapter to Beautiful Code (the O'Reilly book). In it, he uses this example of a Rake task as his example of a beautiful piece of Ruby:

    task :default => [:test]
    task :test do
      ruby "test/unittest.rb"
    end

Let's see what that could look like in CoffeeScript, assuming a similar library:

    task default: ['test']
    task 'test', ->
      ruby 'test/unittest.rb'

Pretty nice. Running that through the CoffeeScript compiler produces this JavaScript:

    task({
      "default": ['test']
    });
    task('test', function() {
      return ruby('test/unittest.rb');
    });


http://coffeescript-theparts.heroku.com/ this could be of interest, although the actual coffeescript site is better/great...


I posted this info as a comment on the guy's blog (still awaiting moderation), but I thought you might find it interesting too, the point being that amazing things are possible with JavaScript and node.js, but if you're thinking single-file scripts with a tangled nest of callbacks and prototypal inheritance chains+constructors that are hard to keep straight, well ... there are better ways ......... :-D

As a JavaScript developer working with node.js (and client side scripts too, of course), I’d like to recommend a couple of related things:

Joose3 — an object system for JavaScript which allows truly classful programming; use it to implement all sorts of meta-programming magic with ease: http://joose.it/ http://openjsan.org/doc/s/sa/samuraijack/Joose/3.011/lib/Joo...

JooseX.CPS — a continuation-passing-style "trait" for Joose classes which helps prevent your asynchronous code from turning into "callback spaghetti": http://joose.it/blog/2010/08/02/asynchronous-aka-non-blockin... http://openjsan.org/doc/s/sa/samuraijack/JooseX/CPS/0.11/lib...

Joose is open source, works with both node.js and in browsers, and there are various ways to install and leverage its libraries, e.g. npm: http://github.com/isaacs/npm

This isn’t an advertisement. I started exploring node.js in early 2010, and my "discovering" Joose was a real boon as I was looking to do some complicated things that seemed daunting when trying to express the concepts in terms of prototypal inheritance.

Not everyone finds it attractive, but I’m always happy to spread the word in hopes that Joose can make someone else’s life and programming projects a little less stressful, which is what it's done for me.


I don't think syntax is really that much of an issue. The fact is if you might expand to real-time apps later on, you'll have to write new abstractions all over again for stuff like fetching data, whereas if you started with something like node.js, you wouldn't. It's simply a matter of if you feel it's worth it or not, and it's really case-by-case.


"Everything is Async: Because the base environment has been built essentially from scratch, everything is asynchronous. This means there is no ‘defer to thread’ like in Twisted Python; You just can’t make blocking code."

This is not necessarily a good thing. Sometimes you need to write a piece of code that executes sequentially. Having the ability to do that if you need to is a good thing. Sometimes it can be unnatural and unwieldy to split a block of functionality up into a set of callback functions.


Yep. Your code ends up looking like the output of a continuation-passing transform, with every kind of sequential composition involving nested callbacks. It feels quite low-level and clunky and is one of the things I like least about writing Javascript on the browser.

Another thing is, when you go async, you're essentially giving up on using the language runtime's stack for most purposes. With that, you lose some useful functionality (useful stack traces, exceptions bubbling up).


Use Step, man


While node.js has some appealing characteristics it doesn't seem to solve the main problem with realtime web apps -- coordination between the multiple client side view states and the server side state. It's easy enough to hack together communication between these two layers but it always feels a bit half baked. Something like etherpad should be the new hello world app.


Have you seen DNode? http://substack.net/posts/85e1bd/DNode-Asynchronous-Remote-M...

Doesn't solve that problem (which is really, really hard) but it's a very interesting step.


Groupware is an extraordinarily difficult problemin this respect, especially if you want to handle the rare edge cases. The problem with maintaining multiple client side view states to be the same has a great deal of intrinsic complexity due to the very weak guarantees provided by network communication (if you want any kind of responsiveness whatsoever.)


I tend to solve the problem of showing the same state to all users with the CouchDB _changes feed. It fits the groupware problem like a glove. Here's just one example app:

http://couchapp.org/focus/_design/focus/index.html


True, but I suspect there is a lot that could be done by baking something like the feedsync protocol together with knockout.js style view binding, node.js and a websocket connection.


The problem with feedsync and trying to serialize knockout.js to disconnected clients is conflict handling. Secondly, you have to worry about potentially divergent states if messages are lost in-transit (depending how robust your needs are.)

That being said, you could hack something together with a very optimistic approach using knockout.js and socket.io (to gracefully degrade if websockets arent available.)


So it is possible to write an entire webapp in Node.js? I think I'll try it out on my next project since I don't have experience in any web frameworks. I wonder if Node.js has any Postgres bindings.


By Dahl himself, actually.

http://github.com/ry/node_postgres


http://expressjs.com/ is a good web framework for node, if you can get over the fact that their docs all assume that you know Ruby and have used the popular templating engines in it.


Yes and yes.


Node.js is one of the most promising sounding projects I've seen in the last year in terms of something I may actually use in production code. JavaScript's agile syntax combined with ubiquity thanks to web browsers make it one of the few languages that would make switching to it bearable for, say, a Pythonista like me. And Node.js may be the final straw that unleashes it on the server-side.


Curious though, if you are a Pythonista, why not use something like gevent or tornado?


tornado solves one very specific problem that friendfeed had. It's being used for other problems, but it solves them less well than, say, twisted.

twisted solves networking problems of all types really well, but (as Paul mentions in his post), most libraries for python are written assuming they have the entire interpreter to themselves for as long as they want (which in the naïve case, turns it into tornado, but it at least has facilities for running async tasks in other threads or processes).

node.js does as well, but it's developing a very rich library very fast. Certain things are harder to deal with (personally, I think twisted got async error handling right and most everyone else hasn't got there yet), but people think they understand javascript better than they think they can understand twisted.


Tornado solves the problem of building web frontends, particularly those with comet features. This problem is not specific to FriendFeed. A number of other services use Tornado including Brizzly, Quora and Hipmunk.

Twisted has support for many network protocols while Tornado only has support for HTTP (client and server). If you are doing something other than HTTP, than Twisted might be the better choice.


The author mentions how he switched from using Twisted to Node.js. I would be very interested in hearing more about the advantages and disadvantages of this as I am building a service in Python right now that I am using Twisted for. I don't really know anything about Node.js but I have been hearing a lot about it. A couple hangups for me are that 1) I'm not a huge fan of Javascript itself and 2) I'd really rather not mix Python and Javascript together. Note that my app doesn't currently use HTTP and maybe that plays a role in Node vs Twisted.


I argue that twisted is better for most practical uses of comet.

Tornado mastered only the "have lots of suspended connections" thing. Many of the examples involve blocking for processing one of those connections. What's the point of having 20k connections terminated on an http comet connection if you completely block the entire event loop to service a single one while you make another network connection (e.g. memcached, mysql, etc...).

In this regard, most real life comet apps are doing more than http. To be fair, tornado did ship with a yet another python http client, so you can at least use it with a database that speaks http without blocking, though without chainable deferreds, it's hard to do the exact right continuations required to chain these events together without locking the event loop.


The Tornado philosophy is to use blocking for fast operations and async for the occasional long operation. Tornado applications compensate for blocking by running several instances of the application.

Twisted is theoretically better than Tornado because everything is async in Twisted, but Tornado is more practical because it's easier to write straight-line code than chains of callbacks. The cost of Tornado is that you need more memory on the frontend because you run more instances of the application.

In my previous comment, I listed some real life comet applications that use Tornado. What real life comet applications use Twisted?


@inlineCallbacks make linear code very easy to write in twisted. Have you tried it lately? Here's a snippet of code out of my gearman implementation:

    @defer.inlineCallbacks
    def gclient(gearman):
        w = client.GearmanClient(gearman)
        x = yield w.submit('test', 'some data')
        print "result:", repr(x)
Pretty straighforward, I think -- you just stick a 'yield' between your invocation and the capture of the results.

As far as who's using in actual comet applications -- it's hard to say. The last time I tried looking for a comet implementation, what appeared to be the canonical "cometd" was written in twisted. I ended up not using it and rolled my own twisted based server that was closer to my requirements. It's been in production for a few years now, but is still a somewhat secret project.

I'm pretty sure you could research their userbase as well as I could.

I'm not saying twisted is perfect and all other technology sucks (though deferreds, once you understand them, are really the only way to do this sort of thing).

When tornado was launched, I started playing with it and couldn't understand why it prevented me from integrating so many asynchronous tasks. I spent an hour or two separating the good parts of tornado from the reimplementation of twisted and built tornado on top of twisted. It was, as far as I could tell, at the starting point, minus 1,297 lines of python.


Those have attractive qualities too, you're right.

One advantage to using something like Node.js, however, is language homogeneity: having all your browser client-side code and server-side code in 1 programming language. While it's good to use The Right Tool For The Job there's also a benefit to having the simplest solution possible, with the least amount of moving parts, and requiring the least amount of tech knowledge (esp languages) to deliver that solution. While I prefer Python to JavaScript, if we never get to a world where Python is built-in to every browser there is some attraction to moving in the other direction. "If you can't beat 'em, join 'em."


I never understood this argument. Client side javascript and server side javascript aren't really the same at all, it's not like you can re-use your client side javascript on the server. The only benefit I see is that you don't have to context switch between python and javascript, but the only time I can remember this affecting me is when I forget to type semi-colons.


That's not always true.

Templating is a perfect case for reusing code on both sides of the connection. In the optimal scenario, the browser can render a template based on requests for JSON data. However, if the client doesn't support JavaScript, the same template can be rendered on the server-side and fed to the browser traditionally. Great for accessibility and SEO.

Input validation is another situation that's a great candidate for shared code.

Another nice benefit is that server-side JavaScript brings an assortment of mature DOM selection/manipulation engines with it. I believe there was an example of using jQuery on the server-side with node.js posted here recently.

Jaxer[0], which was ahead of its time, had a nice approach to sharing client/server logic with its runat="both". It's a shame that project never got much traction.

[0] http://www.jaxer.org/


"it's not like you can re-use your client side javascript on the server".

The other is more appealing. The wins for client/server code share are for things like field validations and templates.


"... it's not like you can re-use your client side javascript on the server. ..."

nodejs and jsdom perhaps? "jsdom + jQuery in 5 lines with node.js" ~ http://news.ycombinator.com/item?id=1665999


What on earth constitutes an "agile syntax"?

I thought there was fairly universal agreement that while javascript has many strengths, its syntax was not one of them.


I see it as a kind of Switzerland that will draw from all camps in a way that other languages/frameworks haven't.




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

Search: