JavaScript is Not Web Assembly

It’s fairly common these days to think of JavaScript as a sort of “assembly language for the web”. After all, it’s the language that is natively supported by web browsers, making it the most widely deployed runtime in history. With Node, we have a very relevant general purpose non-browser stack for doing system programming using this language, so it’s even more important as a language.

Programmers like to improve things and solve problems. This is a healthy instinct, but like so many healthy instincts, it can be subject to runaway feedback loops and lead to pathological behavior.

If you are designing a language, compiling it to JavaScript is a pretty attractive option, for much the same reason that compiling C to machine code is an attractive option: running it in more places.

However, so far, most of the times that I’ve seen someone trot out the “JS = new assembly” horse, it’s not an apt comparison. The reason we write C instead of assembly is that:

  1. Assembly varies wildly between architectures. C is not as variable. So, the compiler can abstract away a lot of that peculiarity, and you only need to worry about it if you’re distributing precompiled binaries.
  2. C offers an order of magnitude more expressiveness.

I’m going to pick on CoffeeScript, because it’s clearly the most popular to-JS language. Jeremy Ashkenas is a great guy, and has shown himself on repeated occasions to be remarkably sane with respect to this issue. Either he hasn’t caught the language-wank crazy, or he hides it really well.

However, either or both of these points apply to every other to-JS language, including but not limited to GWT, paren-js, sibilant, streamline, kaffiene, narrative, et al. That’s not to say that any of these systems are bad, just that the “blah is to JS as C is to Assembly” analogy is wildly wrongheaded.

  1. CoffeeScript programs don’t vary any less across architectures than the JavaScript programs it creates. That is, you don’t compile it to target a given platform. (This is not true of GWT, which can compile different JS files for different browsers, but that’s not the norm in the to-JS world.)
  2. CoffeeScript does not offer an order of magnitude difference in expressiveness. I’m not using “expressiveness” as some fuzzy term to mean “how happy you are expressing yourself in X language”, but the more mathy technical meaning of “how many relevant program tokens are required to do X task.” CoffeeScript may require fewer tokens, sure, but not 10 to 1 fewer.

JavaScript is not the Assembly of the Web. It’s the C of the web. The to-JS languages are lining up to become the C++ of the web.

  1. They offer language features that make some sorts of programs a little bit easier to write, but don’t make an order of magnitude difference in expressive power.
  2. They’re mostly backwards compatible with JavaScript.
  3. You still need to grok the DOM, or node, or whatever other platform your program is interacting with, and that’s probably documented in JavaScript.
  4. They break almost all of the tooling that exists for JavaScript debugging.

Clarification: CoffeeScript does try very hard to compile to JS that runs on all JS platforms. However, it does not optimize for a given platform, or have a specified target when it compiles. The resulting JS is still a high-level general-purpose program, and the pitch, at least, is that it is a better one than you would have written as easily by hand.