Tuesday, February 5, 2013

Node.js Hatred Reveals Significant Dysfunction In The Ruby Culture

A hostile ignorance regarding Node.js seems, to me, to be a pervasive dysfunction in the Ruby culture. For example, Avdi Grimm wrote:

I do share the opinion of a number of my colleagues that using a reactor-based framework in a language lacking native fibers, coroutines, continuations, or threads leads to messy code.

Among the most obvious problems with the above: Node.js is not a framework. A more subtle problem: these remarks came, if you can believe it, in the context of an apology for harshing on somebody's code - specifically, a naive but very well-named and perfectly harmless command-line utility written in Node. Because it was a command-line utility, there was no "reactor-based framework" in question in that code at all. Another subtle problem: Mr. Grimm has gone on record with the opinion that ActiveRecord can lead to messy code, yet I've never seen him laughing at people for using Ruby just because a lot of Ruby code involves ActiveRecord.

In the same way that these remarks about a "reactor-based framework" were completely irrelevant to the matter at hand, Tony Arcieri leveled completely irrelevant criticisms against a blog post I wrote.

In my blog post, I said:

I think listening to Node.js hype at all is foolish.

Mr. Arcieri devoted paragraph after paragraph to Node.js hype in his post, and then told me on Twitter that his post was a point-by-point rebuttal of mine. (In fact, his post frequently argues against points raised by other people, and says so.) He also spent several paragraphs arguing against the position that Rails is no good for JSON APIs, and then very strongly implied that I advocated this position, supplying as proof an unrelated Twitter conversation which contains no words about JSON APIs at all:

The idea that Rails 4 operates on a foundation free of technical debt, by the way, is not just laughable for anyone who's read my own book, Rails As She Is Spoke, it's also hard to take seriously coming from the author of Objects On Rails.

I first learned of the Ruby culture's surprising difficulties with reading comprehension when I described prominent Rubyist Chad Fowler as a werewolf. I used the metaphor of the game Werewolf, which Mr. Fowler had popularized at that time, and which every Ruby developer who went to a single conference that particular year had heard of, thanks to Mr. Fowler popularizing it. This game involves killing werewolves. No actual players die, because it's a game. I recommended that the werewolf in question, namely Mr. Fowler, be killed - in the sense of the game, which literally every prominent Rubyist knew about at the time.

Nonetheless, the community responded by taking my murder recommendation completely literally, despite clearly recognizing that when I said the man was a mythological, supernatural, demonic wolf monster, I was speaking metaphorically. The blog post frequently mentioned the werewolf metaphor, and included several gigantic pictures of werewolves. I still get shit about this today from people who seriously think I wanted to kill the guy in real life.

Apparently this picture is easy to miss.

In retrospect, I regret my post, and consider it immature, although I certainly stand by the actual substance of its accusations, the most important being that Mr. Fowler insulted one of my open source Ruby projects in a very disingenuous way, and that he did this less than 24 hours after he had asked me to review his book. However, it was not a wise thing to post, and the major reason it was so unwise of me to post it: very few responses to it showed any sign of rational analysis whatsoever. Likewise, this hostility to Node.js passes, in both the instance of Mr. Arcieri's blog post, and Mr. Grimm's, into the realm of unreason, by means of faulty logic and irrelevant tangents.

In the instance of my misbehavior, it's easy to see how emotion got in the way of precise reading and rational interpretation. But in the case of Node.js, I find it harder to understand, and I find it impossible to describe as healthy. I want to eradicate this mindless hostility, since it inhibits logical discussion, but I don't know how.

However, I do know an easy workaround. Most Rubyists (myself included) already prefer CoffeeScript to JavaScript. Many other languages compile to JavaScript besides CoffeeScript. ClojureScript and Fay are two of the most interesting. ClojureScript, obviously, is a Clojure implementation which compiles to JavaScript; Fay is a Haskell implementation which compiles to JavaScript. ClojureScript is useful enough that it powers a fascinating new text editor called Light Table.

as of Light Table 0.2.0, the entire thing is now built on top of ClojureScript and the only Clojure left in the system is used for evaling Clojure. With the help of the Node-Webkit project out of Intel, we now use Node.js for all of our platform interaction and we rely on chromium to present our UI. There are many reasons we went down this path and ultimately it has worked out really well for us. ClojureScript, though it has had its moments, has generally been a joy to use and has allowed us to keep our codebase incredibly tight and small despite all of the stuff we've managed to build into LT.

Neither ClojureScript nor Fay replicates their "parent" language with 100% accuracy, but (like CoffeeScript) both provide a more enjoyable syntax than JavaScript, and a subculture with a more mature and sophisticated outlook than the JavaScript culture at large. These seem, to me, to be the major complaints which prominent Rubyists have leveled against JavaScript. I consider both these complaints legitimate, but in the year 2013, I have to call it both provincial and backwards to continue remaining ignorant of these solutions. Criticizing Node.js, without understanding the many ways you can use it, does not seem to me to constitute any useful kind of conversation.

If you're snobbish about JavaScript, I can understand. In many ways, it's a fucked-up language. But Unix is full of utilities which are quirky beyond reason, yet which are nonetheless incredibly useful to learn.

And although it might be fucked up in some ways, JavaScript's not a language whose community is infected with unreasoning hatred, which, at the risk of being repetitive, is always a sign of dysfunction in programming language communities, in my opinion.


The specs I get when I use CoffeeScript and jasmine-node are mind-bendingly fast. They make RSpec look like a steam engine trying to compete with a Lamborghini, and this remains true even when I disentangle Rails from my RSpec specs.

So if you're snobbish about JavaScript, get over it, and just use CoffeeScript, ClojureScript, or Fay instead.

I played with Node.js out of curiousity, like a programmer with a healthy attitude will do from time to time, and I learned a few things. So I created an ongoing series of videos about how to make music with CoffeeScript and Node.js. I'm porting a Ruby project to CoffeeScript in the process of making these videos.

The Ruby project used MIDI to trigger drums in a drum machine, and used probabilistic AI to enable the software to improvise original drum rhythms. So far, the CoffeeScript version can play back pre-programmed drum rhythms (and basslines, and melodies), but I haven't set up the AI stuff yet. Nonetheless, I can already say that the Node.js/CoffeeScript implementation of this Ruby software is completely superior in two important respects.

First, Ruby is slower, even today. When you write software that performs music, you want it to be fast. You need it to be fast, because timing is an essential element of rhythm. Node.js is very, very fast.

Second, I wrote this project in Ruby 1.8, and Ruby 1.8 used a more primitive syntax for lambdas. The Ruby version of this project used lambdas a lot. CoffeeScript, since it is really just JavaScript with less typing, enables you to treat functions as objects without any special lambda syntax. I haven't ported that part of the Ruby project to CoffeeScript yet, because these videos are just a side business, but I know for a fact that when I do, using functions as first-class objects will make my life much easier. I had to alias lambda to L to craft a pseudo-syntax, because I used lambda so much, and the effect on my code was not good.

(Although the Ruby 1.9 syntax for lambdas is more powerful, it is still pretty damn weird, and the CoffeeScript code will still be much more elegant and readable than a Ruby 1.9 implementation would have been. And lambdas remain a less flexible concept than functions as objects.)

I realize that many people use Node.js for many other things, and that building MIDI software is not the most common use case. It's always surprising the range of useful applications which a Turing-complete language can provide. Nonetheless, I find hatred tedious and useless, and I very much wish I did not ever see it anywhere near Ruby.

That's because I still use Ruby a lot, and I still think it's awesome. I praise Rails quite a bit in my book, despite the fact that I also criticize it. Any realistic appraisal of any technology will involve both criticism and praise. I think the same way about Node, and I don't understand why other people don't do the same.

In the words of why the lucky stiff:

when you don’t create things, you become defined by your tastes rather than ability. your tastes only narrow & exclude people. so create.

(And if you're creating music, check out my videos. ;-)

Update: Very soon after I wrote this, I realized how ridiculous it was, at this point, to be surprised by anything revealing dysfunction in the Ruby culture. But I still think we can aim higher.

Also, if you want to tweet anything at me about this, bear in mind that I've uninstalled all my Twitter clients for a few days, because I'm working on something. Sorry! I haven't disconnected my email, but that's mainly because I'm getting to the point where I only look at email every few days or so.