Why JavaScript?

One strain of objection I often hear about the project of making the web more extensible is that it implies travelling further down the JavaScript rabbit hole. The arguments often include:

  • No other successful platform is so limited to a single language (in semantics if not syntax).
  • Better languages exist and, surely, could be hooked up to the HTML DOM instead.
  • JavaScript can’t really describe everything the web platform does, so it’s not the right tool for this archeological excavation.

These, incidentally, are mirrors to the fears that many have about the web becoming “too reliant” on JavaScript. But that’s a topic for another post.

Lets examine these in turn.

The question of what languages a platform admits as first-class isn’t about the languages — not really, anyway. It’s about the conventions of the lowest observable level of abstraction. We have many languages today that cooperate at runtime on “classical” platforms (Windows/Linux/OSX) and the JVM because they collaborate on low-level machine operations. In the C-ish OSes, that’s about moving words around memory area and using particular calling conventions for structuring input and outputs to kernel API thunks. Above that it’s all convention; see COM. Similarly, JVM languages interop at the level of JVM bytecode.

The operational semantics of these platforms are incredibly low level. The flagship languages and most of the runtime behavior of programs are built up from these very low-level contracts. Where interop happens at an API level, it’s usually about a large-ish standard library which obeys most of the same calling conventions (even if its implementation is radically different).

The web has it the other way around. It achieved broad compatibility by starting the bidding at extremely high level semantics which, initially, had very little in the way of a contract beyond bugwards compatibility with whatever Netscape or MSFT shipped last. The coarse, interpret-it-as-you-go contract of HTML is one of the things that has made it such a hardy survivor. JavaScript was added later, and while it has lower-level operational semantics than HTML or CSS, that history of bolting JS on later has led to the current project of encouraging extensibility and layering; e.g., through Web Components. It’s also why those who cargo-cult their experiences of other platforms onto the web find themselves adrift. There just isn’t a shared lower level on which to interoperate.

That there aren’t other languages interfacing with the web successfully today is, in part, the natural outcome of a lack of shared lower-level idioms on which those languages could build-up runtimes on. It’s no accident that CoffeeScript, TypeScript, and even Dart find themselves running mostly on top of JS VMs. There’s no lower level in the platform to contemplate.

Which brings us to the second argument: there are other, better languages…surely we could just all agree on some bytecode format for the web that would allow everyone to get along…right?

This is possible, but implausible.

Implausibility is the only reason I pour time and effort into trying to improve JS and not something else. The Nash Equilibrium of the web gives rise to predicable plays: assuming that incentives for adopting low-level descriptions of JS (as any such bytecode would have to describe JS as well as everything else) are not evenly distributed, movement by any group that is not all of the competitors stymies compatibility, which after all is the whole goal. Any language that wishes to interoperate with JavaScript and the existing DOM is best off describing its runtime in terms of JavaScript for fear that the threat to not adopting a compatible bytecode is credible. Compatibility strategies that straddle the fence can work, but it’s not a short (or clear) game to play. And introducing an abstraction that’s not fundamentally lower-level than JS (and/or does not fully subsume its semantics) is simply doomed. It would lack the power to even credibly hold out hope for a compatible future.

So, yes, there are better languages. Yes, you could put them in a browser. But unless you possess the power to put them in every browser, they don’t matter unless their operational semantics are 1:1 with JavaScript.

You can see how I ended up on TC39. It’s not that I think JS is great (it has well-documented flashes of genius, but so does any competitor worth mentioning) or even the perfect language for the web. But it is the *one language that every vendor is committed to shipping compatibly*. Evolving JS has the leverage to add/change the semantics of the platform in a way that no other strategy credibly can, IMO.

This leaves us with the last objection: JS doesn’t fully describe everything in the web platform, so why not recant and switch horses before it’s too late to turn back?

This misreads platforms vs. runtimes. All successful platform have privileged APIs and behaviors. Successful, generative platforms merely reduce the surface area of this magic and ensure that privileged APIs “blend in” well — no funky calling conventions, no alien semantics, etc. Truly great platforms leave developers thinking they’re the only ship in the entire ocean and that it is a uniform depth the whole way across. It’s hard to think of a description any more at odds with the web platform. Having acknowledged the necessity and ubiquity of privileged APIs, the framing is now right to ask: what can be done about it?

I’ve made it my work for the past 3+ years — along with a growing troupe of fellow thinkers — to answer this charge by reducing the scope and necessity of magic in everyday web development. To describe how something high-level in the platform works in terms of JS isn’t to deny some other language a fair shot or to stretch too far with JS, it’s simply to fill in the obvious gaps by asking the question “how are these bits connected?”

Those connections and that archeological dig are what are most likely to turn up the sort of extensible, layered, compatible web platform that shares core semantics across languages. You can imagine other ways of doing it, but I don’t think you can get there from here. And the possible is all that matters.

8 Comments

  1. bob
    Posted July 3, 2013 at 4:08 am | Permalink

    another take here: https://nicolas.perriault.net/code/2013/why_javascript/ (same title!)

  2. Adam
    Posted July 3, 2013 at 4:39 am | Permalink

    “No other successful platform is so limited to a single language (in semantics if not syntax).”

    iOS.

  3. Posted July 3, 2013 at 6:39 am | Permalink

    That’s not true in practice. You’re allowed to include Lua interpreters and the like. That you can’t dynamically import code from the outside world is a different concern.

  4. Nux
    Posted July 4, 2013 at 2:02 pm | Permalink

    There is ASM.js which is a first attempt at making a low level standard which could be optimized in a very different way. For now I think there is no way to tell if it’s going to fail or be a success, but seems a nice addition to the web.

  5. Posted July 5, 2013 at 5:31 am | Permalink

    Hey Nux,

    Yeah, ASM.js is a good example of how it’s possible to explain more of the stuff that JS can’t “do” by expanding the set of things it can do. Much the way Binary Data in ES6 is going to open up JS’s ability to describe things that were previously “out of scope” for JS, expanding JS is, to me, the only credible way to peel back the onion of the web platform compatibly. Using that lens gets you a long way, and kudos to Mozilla for continuing to push.

  6. Rob
    Posted July 5, 2013 at 1:09 pm | Permalink

    The references to JVM and bytecode sound like you’re confusing JavaScript with Java.

  7. Posted July 9, 2013 at 3:06 am | Permalink

    Rob:

    I haven’t confused them, but apologies of it reads confusingly. Understanding the strains of argument often means adopting the perspectives of those doing the arguing, and adopting the CLR variant of the bytecode argument would have put up a regrettable and irrational “but that’s MSFT! I hate them!” barrier in the minds of many readers.

    Regards

  8. kevin c
    Posted August 1, 2013 at 4:01 am | Permalink

    My preference would be for the ecmascript/es-discuss group to have the Dart deal:
    A new language – with a new lean, sane runtime – which initially compiles down cleanly to ES5.

    It’s almost 20 years since Java and Javascript. We need something new – which works well with the ‘DOM Reformation’ – Web Components, Web Animations, Pointer Events etc.

    The goal of Dart isn’t bad – the implementation of that goal is. There is so much more innovative thinking on es-discuss – but it’s hampered by maintaining backward compatibility with JS.

    One of the objections to a ‘new’ language and runtime a few years ago was hardware/memory limitations. But now lets skate to where the puck is going – really great multi-core CPU/GPU’s with 2GB+ of RAM.

    In 2001 I was develop apps on IE5 which were pulling down JSON with XMLHttpRequest and building MVC interfaces. Also using .hta’s and htc’s. ScriptX for printing. And when MS released C#/dotnet with ASP.net I knew something had gone seriously wrong at MS – because ASP.NET was oblivious of the rich IE5 platform – it was all about round trips. Then MS stagnated IE to focus on xaml etc – and the rest is history. But now with the new API’s like Web Components – innovation has started again.

    Google need a unified platform across Chrome/ChromeOS and Android. Something sane, simple, secure and structured. With snappy touch and graphics. I don’t think the dalvik stack is right long term for apps on anything bigger than a phone. And can V8 handle more complexity?

3 Trackbacks

  1. [...] Why JavaScript? – why invest loads of time and effort making JS fit the needs of the modern web, by another reformist TAG member, Alex Russell [...]

  2. By The week in articles. | Unpunctual Programmer on July 6, 2013 at 6:14 pm

    [...] Why Javascript by Alex Russell Russell defends javascript on the web and confronts frequent arguments against it’s use. [...]

  3. By Why JavaScript? | I read stuff. on July 18, 2013 at 11:58 am

    [...] http://infrequently.org/2013/07/why-javascript/ [...]