Saturday, September 17, 2011

Why node.js? And Why not?

I've been thinking about this recently as I've been coming down from my node.js high (which fluctuates depending on my mood).

The node.js high is the thrill of two dreams colliding in an orgy of programming goodness (1) sharing code between client and server in a meaningful way and (2) a opinionated stance on IO without threads.

Sharing is caring
For those among us that have dealt with the web, it is very frustrated to have to replicate some business logic and templates between the front-end and the back-end. We have to do this to deliver the best possible customer experience. I've spent a lot of time trying to figure how to make good "write once" Ajax solutions. If you go 100% Ajax, then you fuck up SEO. If you go 100% Back-end, then you realize a less than ideal user experience. If the programming the language is the same down to how data is validated, transformed, and rendered, then the back-end and front-end can share a great deal of business critical code. I believe in the possibility to deliver a 100% "SEO" friendly and Awesome user experience.

I feel this current division between SEO (what most businesses needs to thrive) and UX (what makes it easier and fluid to use) is difficult to execute on. This is where the general idea of "Server Side JavaScript" delivers some very interesting ideas and potential. While I haven't seen the best platform yet, there is an opportunity to wow us.

Threads are Hard
I like multi-threaded programming for the intellectual challenges it poses, but I feel like they are mostly a waste for a single core. A single CPU can be much better managed the way node.js does it with an event loop (or you can use libev or libevent like a real programmer, yes, yes). Once you get to multi-cores thou, you a really talking about a distributed algorithm. The same intellectual challenges found in multi-threaded programming are isomorphic to those found in distributed algorithms (just with higher latency).

Hard is bad. I like hard because I'm that nerd in math class that does math problems for fun. Most people want to go home to their kids, play a video, and then get laid after eating a sandwich.  I go home to do math (which baffles my wife).

So, anything that keeps threads away and those hard problems are bay can be seen as nice. I'll be honest, node.js delivers well on this front. I've done some very impressive things with node.js that would make me shutter with threads, and then I load test it; it makes me happy. Out of the box, I get a nice way to express data flow with continuations. It's awesome. No race conditions (unless I'm doing something distributed), No deadlocks, No locks. It just works.

node.js feels like an Apple product.

Coming Down from the High
JavaScript was not designed for enterprise servers. I'll address this on two fronts, and I'll skip the 1.9GB limit because that's just a detail that real programmers can fix and then submit a patch.

The first front is that continuation passing of things that may leak has no safety in terms of releasing resources. If I intend to perform some IO and expect the function to hand off control to the continuation I pass, then I would like a guarantee that the continuation is going to be called.

This is a huge hole. Code written in node.js has to trust node.js 100% since that code surrenders its own control flow. Instead of crashing, node.js can silently hang customers which is not good at all. Having experience this issue more than once, building on node.js now feels like building on sand. Sure, I can go and fix the platform, but it feels like adding duct tape. I'm not sure if trusting node.js 100% is harder than threads or not.

The second front is type safety. I'll give some background about myself. I started in C which I'd call "moderately typed" because you do stupid things all the type. Then I moved up to C++ which was a little bit better. Then I did a bit of Java, and hated it. Then tried C# 1.0, it was OK. Then I did OCaml, and I loved it. I dabbled in Erlang, skipped it (it didn't make me happy). Did a bunch of C# 3.0+, and I loved it. Did tons of PHP and JavaScript, it was ok.Wrote some ruby junk, it didn't make me happy. I fell in love with Lisp and building things with AST. I found myself content with JavaScript, and I was riding the node.js high. Now I work in Java, and my side-projects are a combination of Java and JavaScript. node.js is my new Perl, and I love it for that. I'd prefer C#, but I don't want to spend $ for Visual Studio nor do I want to do C# without an IDE.

Having given the litany of my past, I have no investment in either static typing or dynamic typing. Either are fine. However, type safety is very important to me these days. I want to use type safety as way of expressing  both the ways things should work and the ways things misbehave. Things misbehave all the time for valid reasons.

I hate the way Java's try/catch let forces you do a bunch of silly things, but I love the idea that I can use it force myself and others to make sure they considered every case. I hate null because it lets you fuck up so much up. This is one reason I love OCaml's union types. I don't have to program with null. I can give every output of my function a meaningful value that forces the consumer to deal with. I've considered resurrecting my node.ocaml project to work on this, but I'd need to write a highly durable IO story for some of my work which I don't really want to do yet.

Future
There are a bunch of reasons I want to create yet another programming language, mix the things I want in OCaml, make it asynchronous so it compiles to finite state machines, remove null, make it easy to deal with error, make it pretty, add control structures for handling failure, build a better type system, better control over the heap, hook it up to the cloud, make deployment painless.

The problem with the directions I want to go is that the advances I want are marginally useful and expensive in the grand scheme of things. The things I want are better, but we live in a world which values "worse is better". When I put on the business man hat, then I agree with this statement. When I put on my academic beautiful code hat, then this statement makes me want to go into my cave and be a hermit.

node.js is worse, but that makes it better. The problems I have now will be patched. After enough investment, people will consider it reliable. People will build reliable libraries. Yet, I want to build stuff and not the platform anymore. While node.js is my new perl replacement (and it's fucking awesome at that), doing hard-core server side stuff for me is going on the back-burner.

But I wonder, are the gains there real or marginal? I don't know. I do know that node.js (like ruby was) is a risk that could either pay off big (as ruby has) or fizzle out. It depends on you.

No comments:

Post a Comment