What’s wrong with Node.js and Javascript?

So in my last post I promised to talk about what is wrong with Node.js and Javascript.

Let’s start with Javascript…

One big issue is that the OO model seems to be a bit fragile. It is instance based rather than class based, so objects have methods which they simply gather up from the “prototype” when you construct them. Or something like that. It’s all a bit unclear to me exactly how it all works, and inheritance is fragile – you can’t change an object’s inheritance after putting methods in the prototype already, as that resets the prototype. To be honest this isn’t *that* much worse than Perl, but then I am not holding Perl up as the greatest OO language to compare to. On the plus side people have created conventions for making this work reasonably cleanly, and some code can look pretty decent.

At first I was annoyed that strings are immutable. This comes across as slightly weird sometimes because there are operators which make them look mutable such as “+=” to append to a string, but really that just gives you a new string behind the scenes – it’s just syntactic sugar. I’m kind of used to this now.

Regular expressions suck. They have no “s” modifier to allow a dot to match any char (you have to use [\s\S]). Lots and lots of things in regexps are not supported. At some point I’ll probably have to do an interface to re2 or pcre to access what I need. On the other hand the interface is nicer than Perl’s “Global Variables” approach when accessing matched text.

There’s no way to have binary strings. This is super frustrating. If you are dealing with a line-based protocol like SMTP which might not be 7bit clean, there’s just no way to have both regexps (to handle the line-at-a-time code) and binary data. I’d have to iterate over the “Buffer” (which is how you do binary data in Node.js) a character at a time to find the line endings, and I doubt that would perform (though in fairness I haven’t tried it).

There’s inconsistencies. For example you can do: for (var i = 0; i < 10; i++) { ... } but you can’t do if (var m = str.match(/t/)) { ... } (what I’m pointing out is the lexically defined “var” there).

There’s no easy way to get line numbers of callers (well there is, but you have to construct a new Error(), which feels odd). I suspect this is due to the browser heritage – a bit of a security through obscurity thing.

In general the language feels a bit “light” on features. Again this is because of the browser heritage, and lots is being added through modules.

Now onto Node.js…

The biggest problem really is the immaturity of the libraries. There’s just a lot missing that you might expect, especially for something that is designed for writing servers.

Typical examples:

  • There’s no file locking (flock) available. This is utterly dumbfounding.
  • There’s no setsid() and no fork(), so without an external library you can’t daemonise.
  • There’s no way to set socket options, you have to rely on what the API already provides you with.
  • There’s no seek() or a way to seek() on a file, and no way to reset the EOF counter.

You get the idea – the library is just young and naive.

The other problem which has me rather concerned is the lack of API stability – there’s no deprecation cycle yet in their project management, things just get ripped out if they are deemed “bad”. One example was socket.setSecure() (upgrade a socket to TLS), which I could really use, and see no reason it’s a “bad” API. I suspect it was broken in some ways and was just too hard to fix. Apparently there’s a way for me to still emulate socket.setSecure() but I can’t for the life of me figure it out with the current APIs in place.

The event loop… Having it is great, but if you block (say you need to build a large data structure) you’re screwed. There’s no threads or way to build it outside of the event loop aside from a worker and sending the structure back as JSON (but then you have to parse THAT!). There’s a lot of zealotry in the node community that their way is just fine and that you shouldn’t ever need to do this, but sadly it’s not true.

Finally one more thing: There’s no decent line profiler yet. I don’t even know if this can be built without hooking into the debugger. Basically something like NYTProf would be great. There’s some subroutine level profiling built into v8, but I can’t figure it out.

I’m sure I have other gripes, but those are the major ones I can remember.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s