Constraints and compromises in ECMAScript 6

This past week I attended a talk by Dave Herman, an employee of Mozilla and member of ECMA TC39, who are in charge of the standard for JavaScript. Dave talked about a few of the features and improvements coming to JS in ECMAScript 6, including, what I think is the most exciting and desperately needed: the new module system.

I won't describe how the new module system actually works in this post, as that information is already available elsewhere (in particular at the ES Wiki). While this new module system looks great, I was concerned with the fact that it eschews the current community built around Node and its CommonJS module loading system. I asked Dave what the reasoning for this was. It boiled down to wanting to provide features for module loading which would not be possible using Node's current CommonJS system. Interoperability between client and server side JavaScript programs will eventually be achieved by converting existing code targeted for Node to the new module system.

While this may be a painful migration due to the amount of existing code using CommonJS, it seems like the best choice, given that the amount of JavaScript code targeting Node is dwarfed by the amount targeting the browser. Node will also be able to begin the conversion process fairly soon, as it only needs to wait for the implementation of ECMAScript 6 modules in V8.

Another feature Dave talked about was variable interpolation in strings via so-called quasi-literals. This feature is something very common in other high level languages, but to date JavaScript has relied on the concatenation of strings and variables with the + operator to achieve this. ES6, somewhat confusingly, uses the ` (backtick) to surround these quasi-literals and interpolates variables with ${varname} syntax. I was also curious about the reason for this awkward choice, given Ruby and CoffeeScript's precedence for using double-quoted strings with embedded expressions in #{}, but Dave had the answer. Backticks were chosen for backwards compatibility. If existing strings were to suddenly gain this ability, existing code on the web that happened to have literal occurrences of ${ in them would become syntax or reference errors. The most important constraint TC39 must embrace, unlike languages which compile to JavaScript, is that changes to the language must not break existing code on the web.

Backticks, even though they are often used to execute shell commands in other languages, were chosen simply due to limited set of ASCII characters remaining for new syntax. Again, the syntax they chose here is not ideal, but given the constraints necessary for advancing JavaScript without breaking the web as it exists today, it's a pretty decent compromise.

I'd like to thank Dave again for his talk. I'm looking forward to ES6!

Comments

Florian Florian commented
April 23, 2012

Backticks are a really bad choice. On latin-1 keyboards it requires te key sequence shift+`+space

Dave Herman Dave Herman commented
April 23, 2012

Hi Florian,

We're open to alternatives if you have suggestions. I guess one alternative would be Python's triple quotes:

console.log("""
Usage: ${arguments[0]} [options]
    -h   print this help info
    -l    launch the nuclear missiles
""");

Thoughts?

Dave

Martndemus Martndemus commented
April 23, 2012

Well, if you go down that road. Here in the Netherlands both " and ` are done that way. It's them damn dead keys (http://en.wikipedia.org/wiki/Dead_key). Dutch people use US international keyboard layouts and there might be some other countries too.

Martndemus Martndemus commented
April 23, 2012

Further reading into: https://en.wikipedia.org/wiki/International_keyboard_layout

  • A lot of countries in europe have the backtick hidden behind a Alt Gr combo. (France, Germany ...)
  • Italians lack a backtick on their keyboard
nschubach nschubach commented
April 23, 2012

Why not just make the "container":

$"Hello ${variable}!"
or
$'Hello ${variable}!'

Any string lead by a $ would parse for ${} values. Or replace $ with ? for ?'Hello ${variable}!'

Jason Denizac Jason Denizac commented
April 23, 2012

The approach nschubach suggests - a prefix character - is similar to C#'s multiline string notation, eg:

string str = @"hello
world
how
are you?";

C# doesn't interpolate variables that way (string.Format is used, instead), but it offers a way to let the compiler know to treat the string differently - and more importantly it clearly signals to a developer that this string is different - without introducing new or visually ambiguous characters.

Whether $, @, or some other character, a string literal prefix feels much better to me than yet another type of quote.

Gert Peter Brigsted Gert Peter Brigsted commented
April 24, 2012

I have to agree with nschubach. The backward tick (`) is a pain to write, requiring three keys to be pressed. But marking the entire string with a prefix symbol seems like a plausible solution we can all enjoy. Also, as Jason Denizac states, it is more visible than backward ticks. I usually use the single quotes for strings, and it would be easy to mistake one for the other (` vs. ').

mathew mathew commented
April 25, 2012

Why not use a directive similar to "use strict" to enable non-backwards-compatible behavior such as string interpolation? Developers could then enable the new features once they had established that they wouldn't cause their existing code to break.

Comments are closed

Comments are automatically closed 2 weeks after publication. If you still have something to say about the article, feel free to contact me.