Category Archives: ECMAScript

Now that’s a nice ‘stache

dot-stacheThere was something that bugged me about Allen Wirfs-Brock‘s proposed “monocle-mustache” syntax for JS: it updates the properties of the object on the left-hand side, but it doesn’t look like it’s updating properties; it looks like some strange combination of creating a new object and accessing properties of the left-hand side:

this.{ foo: 17, bar: "hello", baz: true };

Then this week a couple things happened that got me thinking: Reg Braithwaite (aka @raganwald) posted his proposal for a CoffeeScript syntax to support the “fluent style” of programming, inspired by Smalltalk’s message cascades:

array
    .pop()
    .pop()
    .pop()

path
    .moveTo(10, 10)
    .stroke("red")
    .fill("blue")
    .ellipse(50, 50)

Next I saw Bob Nystrom‘s post about a cascade syntax proposal for Dart, which is a small variation on Allen’s monocle-mustache:

document.query('#myTable').{
    queryAll('.firstColumn').{
        style.{
            background = 'red',
            border = '2px solid black'
        },
        text = 'first column'
    },
    queryAll('.lastColumn').{
        style.background = 'blue',
        text = 'last column'
    }
};

This is really just a tiny tweak to Allen’s original syntax, but it makes a world of difference: it uses the = sign for assignment. Much clearer!

Now, assignments with commas don’t really look like JS. But since the point of cascades is to do imperative sequencing — i.e., to ignore the result of intermediate message sends and do each message send on the original object from the left-hand side — it makes perfect sense to use a statement-like syntax:

array.{
    pop();
    pop();
    pop();
};

path.{
    moveTo(10, 10);
    stroke("red");
    fill("blue");
    ellipse(50, 50);
};

this.{
    foo = 17;
    bar = "hello";
    baz = true;
};

Even sweeter, JavaScript’s automatic semicolon insertion kicks in and lets you do this very concisely:

array.{
    pop()
    pop()
    pop()
};

path.{
    moveTo(10, 10)
    stroke("red")
    fill("blue")
    ellipse(50, 50)
};

this.{
    foo = 17
    bar = "hello"
    baz = true
};

What’s so great about a cascade syntax is that when you want to do imperative programming on the same object, you don’t have to rely on the API creator to return this from every method. As the client of the API you don’t have to care what the method returns, you throw away the result anyway.

In fact, this is one of the things I don’t like about method chaining in JS today: you can’t actually tell whether the method is mutating the current object and returning itself or producing some entirely new object. And when you mix the two styles, it gets even blurrier. Look at Bob’s example from jQuery:

$('#myTable')
    .find('.firstColumn')
        .css({'background': 'red',
              'border': '2px solid black'})
        .text('first column')
    .end()
    .find('.lastColumn')
        .css('background','blue')
        .text('last column');

You just have to know that .find() produces a new object, and .css() and .text() modify it and produce the same object, but nothing about the syntax tells you this. (And personally, I always feld that .end() was where jQuery’s API jumps the shark.)

With a cascade syntax in addition to normal method calls, you can so much more easily distinguish when you’re doing something to the same object, and when you’re selecting new objects:

$('#myTable').{
    find('.firstColumn').{
        style.{
            background = 'red'
            border = '2px solid black'
        }
        text = 'first column'
    }
    find('.lastColumn').{
        style.background = 'blue'
        text = 'last column'
    }
};

Gist here. These are just my initial thoughts; I’ll have to work on fleshing out a full proposal, including the full grammar spec.

contracts.coffee

Mozilla Research intern Tim Disney has has just released contracts.coffee, a dialect of CoffeeScript with a sweet syntax for wrapping JavaScript objects with contracts that are automatically checked at runtime (“assert on steroids”). Tim’s got a great tutorial with lots of examples, so I won’t try to reproduce it here. Just check it out!

Contracts.coffee is a great demonstrator of the power of JavaScript proxies, which are coming in the ES6 standard, have been shipping in SpiderMonkey since Firefox 4, and are in the works for V8. Contracts.coffee uses proxies to create wrapper objects that do all the proper checking to enforce your contracts.

It’s also a nice experiment in language design (using ideas from Eiffel and Scheme), which we’ll be paying attention to along the road to ES7 and beyond.

Automatically scheduled JS tasks—with joins!

When I spoke at the Mountain View JS meetup about upcoming features in JS the other week, I showed a slide demonstrating how you can build cooperative threads with generators, in order to do asynchronous I/O in sequence without having to chain callbacks. I got a great question about this: is it possible to do several operations concurrently but then block until they all finish? Or do you have to force every I/O operation into a sequence? In other words, can you implement joins?

So I figured it was time to make my jstask library a little more fully-featured. I’ve implemented a task scheduler, so that tasks don’t have to be manually resumed. And I’ve implemented join, so that you can chain some operations, but still run others concurrently. For example:

spawn(function() {
    var foo, bar, baz;
    yield join(spawn(function() { foo = yield read("foo.txt"); }),
               spawn(function() { bar = yield read("bar.txt"); }),
               spawn(function() { baz = yield read("baz.txt"); }));
    // ...
});

I’ve designed the library so that if a task throws an exception and another task is joined on it, the exception propagates to the joiner. So you can simply write:

spawn(function() {
    var foo, bar, baz;
    try {
        yield join(spawn(function() { foo = yield read("foo.txt"); }),
                   spawn(function() { bar = yield read("bar.txt"); }),
                   spawn(function() { baz = yield read("baz.txt"); }));
    } catch (e) {
        // ...
    }
    // ...
});

If any one of the subtasks throws an exception, the others are automatically cancelled and the exception propagates to the outer task.

This might not be the only policy that makes sense. I hope to keep experimenting with jstask, and it’s up on github and available for forking (no pun intended). Maybe we’ll discover other useful policies. This is one of the cool things about generators: they’re general and flexible enough to support multiple different libraries, policies and applications.

My JS meetup talk

On February 9th I gave a talk at the Mountain View JavaScript meetup, hosted by Google, on some of the cool features we’re working on for the next version of ECMAScript. Max Walker from Marakana, Inc. did a beautiful job recording and editing the video.

Caveat: there’s one point in the video where I claim that in-browser modules loaded from the same URL shouldn’t share the same instance (aka “singletons”). Kevin Dangoor has recently prodded me to reconsider this, and I think he’s right: I believe we can share instances more like CommonJS, even in the browser. I’m still working on some of the details but I think it’s gonna be awesome.

Module scoping and linking

The ECMAScript TC39 committee had its regular meeting this week. One of the things we talked about were some revisions that Sam Tobin-Hochstadt and I have been discussing for the Harmony module system.

In previous iterations, the design allowed nested modules to refer outside their bodies only to other modules. For example:

    module A {
        var foo = 42;
        module B { ... }
    }

Module B would be allowed to refer to A, but not foo. This would also be true if module B could be loaded from an external file:

    module A {
        var foo = 42;
        module B = load "b.js";
    }

On es-discuss, Jasvir Nagra and Ihab Awad raised the concern that this design renders externally-loaded modules too sensitive to external scopes, similar to textual inclusion (aka #include). To be fair, they would only be sensitive to modules in scope, since other bindings would be removed from scope. But the point still stands: non-local changes to the lexical environment in external files would affect externally loaded modules. It’s not too hard to come up with plausible scenarios where this could bite programmers.

The revision we discussed proposes separating the cases of externally loaded modules and lexically nested modules. For one thing, in the first example above, why shouldn’t B be able to refer to foo? It’s right there! That’s just good old lexical scope. But if B is loaded externally, it should not be sensitive to a lexical environment of unbounded size. But at the same time, we still need to provide the ability to link together modules, even with cyclic dependencies, and place them in separate files. For example, an MVC app might be divided up into a few sub-modules:

    module MyApp {
        ...
        module Model = load "model.js";
        module View = load "view.js";
        module Controller = load "controller.js";
        ...
    }

The individual sub-modules ought to be able to import from one another, even cyclically — for example, the view and the controller might be mutually dependent. In essence, MyApp is creating a local module graph, consisting of its immediately nested module declarations.

So instead of inheriting the entire lexical environment of the code loading them, the modules Model, View, and Controller should be given a lexical environment with just the modules bound in the local module graph. That way, within every component of a program, you can easily divide it up into separate pieces, each of which may depend on other pieces. But at the same time, because they only see the other modules nested within MyApp, the sub-modules aren’t sensitive to code changes in the rest of the program.

JavaScript needs modules!, ctd

I generally try to make my slides visual aids instead of a crib sheet, which means they aren’t typically self-contained. So I should provide a little context for my earlier post on the Harmony module system.

First things first: this design has been a collaboration with Sam Tobin-Hochstadt, who’s been utterly indispensable, as well as discussions with the TC39 committee and the es-discuss mailing list.

Second things second: we are not in competition with CommonJS, nor do we intend to replace it! CommonJS has done great work building a framework for creating reusable components in JavaScript. Now, they didn’t have the luxury of changing the language. We do, and we have a responsibility to make use of it to make JavaScript — and the entire open web — a better development environment.

One of the best practices on the web is Doug Crockford’s “module pattern,” which is a coding pattern for writing unobtrusive components that avoid stepping on the toes of other components. Design patterns are a recurring theme on the web: innovative users find workarounds to the limitations of web technologies, and as these patterns of use become popular, browser vendors and standards organizations can and should provide built-in support to ultimately alleviate the need for the workarounds altogether.

So it should be for modules! Instead of having to go through the pain of creating and immediately calling functions in order to get better scoping semantics, and to save and restore global bindings to be unobtrusive, JavaScript should have better scoping and modularity from the outset.

The modules in this design are second-class, that is, they are a static declaration form rather than a general expression form. This means that the imports and exports of a module are known statically to the compiler, which makes them more amenable to supporting lexical scope.

The general forms for using modules are simple and intuitive: a module declaration binds a module and the export form determines what definitions within it are shared with the outside world. You can access the exports of another module simple by selecting them with the usual dot-syntax (such as UI.Widget), or you can bind local variables to the exports of another module with the import syntax.

Modules can have cyclic dependencies, as long as the modules are all in scope with one another — much like function declarations.

These basic, simple features are part of the theme of usability and minimal intrusion into the development process: putting code in a module should be as convenient a refactoring step as possible.

The next theme of the design is moving JavaScript towards true lexical scope. Previously, JavaScript has always had a global object at the top of the “scope chain” (i.e., the lexical environment), which means that undeclared variables are looked up dynamically in a shared object. This means that the language’s default behavior is to create global variables. This is easy to trip over, and makes it inconvenient to write modular programs.

The TC39 committee has already decided that the next version of JavaScript will make some backwards-incompatible semantic changes to the language — within reason — and only be enabled by opting in to a new language version. We’ve also agreed that ES5′s strict mode will be a baseline, i.e., the default semantics, for the new version. This eliminates two of the pieces of JavaScript that currently break lexical scope: with-statements and eval modifying its caller’s scope. The last remaining offender is the global object. With this new language version, we can finally eliminate that, too. The benefit is that JavaScript becomes lexically scoped at last — no more runtime errors due to accidentally-omitted var declarations or misspelled variable names!

Module declarations are scoped just like other declarations. They can be declared inline, they can be simple renamings of existing modules, or they can be loaded from external files. This latter form has much the same semantics as a script tag, except that it can be done from within JavaScript.

Notice that the client gets to name the module it loads, instead of the module naming itself. This is critical: it means that modules don’t have to try to contend for a global namespace and use painful naming techniques for defensively avoiding stepping on each other’s toes. They can also contain nested modules and happily name them whatever they like, without contention.

The last piece of the design is dynamic loading. Just because modules are second-class does not mean they cannot be dynamically represented as values. In fact, module instances are easily reflected as objects simply by referring to them in expressions. Module instance objects are essentially immutable “views” of module instances; you cannot modify the exports of a module instance, but you can dynamically query their properties just like any object.

Module loaders give you the ability to dynamically load modules, and even to create multiple isolated contexts in which to load them. You can even provide low-level hooks to create custom loading semantics for a given module loader. Dynamic loading makes it possible to achieve important web use cases like dynamic feature detection, conditional loading, or on-demand loading. At the more intricate end of the spectrum, you can do live upgrades, implement isolated and stratified execution environments like online IDE’s, and write security-critical code that runs untrusted code in restricted contexts.

In all, the point of our module proposal is to make it incredible easy to create JavaScript components and share them, and to make JavaScript a truly lexically scoped language. In a larger sense, the goal is to continue making it easier to share code, because when we lower the barriers to entry, more people do more awesome things with the web all the time. And that’s why we’re here.

JavaScript needs modules!

I’ve just given my breakout session, “JavaScript needs modules!“, at the Mozilla Summit. (Note: none of this is implemented yet, so please don’t take any of the code snippets too literally.)

The enthusiastic atmosphere at the summit has been palpable– it’s hard not to be in awe of my coworkers and fired up for what’s ahead for the web. For my part, I believe that modules are one of the most important upcoming features of JavaScript, and I also believe we can make them happen.

Static module detection is unnecessary

One of my original concerns for the “simple modules” proposal for ECMAScript was that we should support a simple, static form of what you might call “module detection.” I’ve since realized that this feature is probably unnecessary.
Continue reading