Mozilla

Articles

Sort by:

View:

  1. ES6 In Depth: Destructuring

    ES6 In Depth is a series on new features being added to the JavaScript programming language in the 6th Edition of the ECMAScript standard, ES6 for short.

    Editor’s note: An earlier version of today’s post, by Firefox Developer Tools engineer Nick Fitzgerald, originally appeared on Nick’s blog as Destructuring Assignment in ES6.

    What is destructuring assignment?

    Destructuring assignment allows you to assign the properties of an array or object to variables using syntax that looks similar to array or object literals. This syntax can be extremely terse, while still exhibiting more clarity than the traditional property access.

    Without destructuring assignment, you might access the first three items in an array like this:

    var first = someArray[0];
    var second = someArray[1];
    var third = someArray[2];
    

    With destructuring assignment, the equivalent code becomes more concise and readable:

    var [first, second, third] = someArray;
    

    SpiderMonkey (Firefox’s JavaScript engine) already has support for most of destructuring, but not quite all of it. Track SpiderMonkey’s destructuring (and general ES6) support in bug 694100.

    Destructuring arrays and iterables

    We already saw one example of destructuring assignment on an array above. The general form of the syntax is:

    [ variable1, variable2, ..., variableN ] = array;
    

    This will just assign variable1 through variableN to the corresponding item in the array. If you want to declare your variables at the same time, you can add a var, let, or const in front of the assignment:

    var [ variable1, variable2, ..., variableN ] = array;
    let [ variable1, variable2, ..., variableN ] = array;
    const [ variable1, variable2, ..., variableN ] = array;
    

    In fact, variable is a misnomer since you can nest patterns as deep as you would like:

    var [foo, [[bar], baz]] = [1, [[2], 3]];
    console.log(foo);
    // 1
    console.log(bar);
    // 2
    console.log(baz);
    // 3
    

    Furthermore, you can skip over items in the array being destructured:

    var [,,third] = ["foo", "bar", "baz"];
    console.log(third);
    // "baz"
    

    And you can capture all trailing items in an array with a “rest” pattern:

    var [head, ...tail] = [1, 2, 3, 4];
    console.log(tail);
    // [2, 3, 4]
    

    When you access items in the array that are out of bounds or don’t exist, you get the same result you would by indexing: undefined.

    console.log([][0]);
    // undefined
    
    var [missing] = [];
    console.log(missing);
    // undefined
    

    Note that destructuring assignment with an array assignment pattern also works for any iterable:

    function* fibs() {
      var a = 0;
      var b = 1;
      while (true) {
        yield a;
        [a, b] = [b, a + b];
      }
    }
    
    var [first, second, third, fourth, fifth, sixth] = fibs();
    console.log(sixth);
    // 5
    

    Destructuring objects

    Destructuring on objects lets you bind variables to different properties of an object. You specify the property being bound, followed by the variable you are binding its value to.

    var robotA = { name: "Bender" };
    var robotB = { name: "Flexo" };
    
    var { name: nameA } = robotA;
    var { name: nameB } = robotB;
    
    console.log(nameA);
    // "Bender"
    console.log(nameB);
    // "Flexo"
    

    There is a helpful syntactical shortcut for when the property and variable names are the same:

    var { foo, bar } = { foo: "lorem", bar: "ipsum" };
    console.log(foo);
    // "lorem"
    console.log(bar);
    // "ipsum"
    

    And just like destructuring on arrays, you can nest and combine further destructuring:

    var complicatedObj = {
      arrayProp: [
        "Zapp",
        { second: "Brannigan" }
      ]
    };
    
    var { arrayProp: [first, { second }] } = complicatedObj;
    
    console.log(first);
    // "Zapp"
    console.log(second);
    // "Brannigan"
    

    When you destructure on properties that are not defined, you get undefined:

    var { missing } = {};
    console.log(missing);
    // undefined
    

    One potential gotcha you should be aware of is when you are using destructuring on an object to assign variables, but not to declare them (when there is no let, const, or var):

    { blowUp } = { blowUp: 10 };
    // Syntax error
    

    This happens because the JavaScript grammar tells the engine to parse any statement starting with { as a block statement (for example, { console } is a valid block statement). The solution is to either wrap the pattern or the whole expression in parentheses:

    ({ safe }) = {};
    ({ andSound } = {});
    // No errors
    

    Destructuring values that are not an object, array, or iterable

    When you try to use destructuring on null or undefined, you get a type error:

    var [blowUp] = null;
    // TypeError: null has no properties
    

    However, you can destructure on other primitive types such as booleans, numbers, and strings, and get undefined:

    var [wtf] = NaN;
    console.log(wtf);
    // undefined
    

    This may come unexpected, but upon further examination the reason turns out to be simple. When using an object assignment pattern, the value being destructured is required to be coercible to an Object. Most types can be converted to an object, but null and undefined may not be converted. When using an array assignment pattern, the value must have an iterator.

    Default values

    You can also provide default values for when the property you are destructuring is not defined:

    var [missing = true] = [];
    console.log(missing);
    // true
    
    var { message: msg = "Something went wrong" } = {};
    console.log(msg);
    // "Something went wrong"
    
    var { x = 3 } = {};
    console.log(x);
    // 3
    

    (Editor’s note: This feature is currently implemented in Firefox only for the first two cases, not the third. See bug 932080.)

    Practical applications of destructuring

    Function parameter definitions

    As developers, we can often expose more ergonomic APIs by accepting a single object with multiple properties as a parameter instead of forcing our API consumers to remember the order of many individual parameters. We can use destructuring to avoid repeating this single parameter object whenever we want to reference one of its properties:

    function removeBreakpoint({ url, line, column }) {
      // ...
    }
    

    This is a simplified snippet of real world code from the Firefox DevTools JavaScript debugger (which is also implemented in JavaScript—yo dawg). We have found this pattern particularly pleasing.

    Configuration object parameters

    Expanding on the previous example, we can also give default values to the properties of the objects we are destructuring. This is particularly helpful when we have an object that is meant to provide configuration and many of the object’s properties already have sensible defaults. For example, jQuery’s ajax function takes a configuration object as its second parameter, and could be rewritten like this:

    jQuery.ajax = function (url, {
      async = true,
      beforeSend = noop,
      cache = true,
      complete = noop,
      crossDomain = false,
      global = true,
      // ... more config
    }) {
      // ... do stuff
    };
    

    This avoids repeating var foo = config.foo || theDefaultFoo; for each property of the configuration object.

    (Editor’s note: Unfortunately, default values within object shorthand syntax still aren’t implemented in Firefox. I know, we’ve had several paragraphs to work on it since that earlier note. See bug 932080 for the latest updates.)

    With the ES6 iteration protocol

    ECMAScript 6 also defines an iteration protocol, which we talked about earlier in this series. When you iterate over Maps (an ES6 addition to the standard library), you get a series of [key, value] pairs. We can destructure this pair to get easy access to both the key and the value:

    var map = new Map();
    map.set(window, "the global");
    map.set(document, "the document");
    
    for (var [key, value] of map) {
      console.log(key + " is " + value);
    }
    // "[object Window] is the global"
    // "[object HTMLDocument] is the document"
    

    Iterate over only the keys:

    for (var [key] of map) {
      // ...
    }
    

    Or iterate over only the values:

    for (var [,value] of map) {
      // ...
    }
    

    Multiple return values

    Although multiple return values aren’t baked into the language proper, they don’t need to be because you can return an array and destructure the result:

    function returnMultipleValues() {
      return [1, 2];
    }
    var [foo, bar] = returnMultipleValues();
    

    Alternatively, you can use an object as the container and name the returned values:

    function returnMultipleValues() {
      return {
        foo: 1,
        bar: 2
      };
    }
    var { foo, bar } = returnMultipleValues();
    

    Both of these patterns end up much better than holding onto the temporary container:

    function returnMultipleValues() {
      return {
        foo: 1,
        bar: 2
      };
    }
    var temp = returnMultipleValues();
    var foo = temp.foo;
    var bar = temp.bar;
    

    Or using continuation passing style:

    function returnMultipleValues(k) {
      k(1, 2);
    }
    returnMultipleValues((foo, bar) => ...);
    

    Importing names from a CommonJS module

    Not using ES6 modules yet? Still using CommonJS modules? No problem! When importing some CommonJS module X, it is fairly common that module X exports more functions than you actually intend to use. With destructuring, you can be explicit about which parts of a given module you’d like to use and avoid cluttering your namespace:

    const { SourceMapConsumer, SourceNode } = require("source-map");
    

    (And if you do use ES6 modules, you know that a similar syntax is available in import declarations.)

    Conclusion

    So, as you can see, destructuring is useful in many individually small cases. At Mozilla we’ve had a lot of experience with it: destructuring was first implemented for JavaScript by Brendan Eich in 2006, again drawing from Python. It shipped in Firefox 2. So we know that destructuring sneaks into your everyday use of the language, quietly making your code a bit shorter and cleaner all over the place.

    Five weeks ago, we said that ES6 would change the way you write JavaScript. It is this sort of feature we had particularly in mind: simple improvements that can be learned one at a time. Taken together, they will end up affecting every project you work on. Revolution by way of evolution.

    Updating destructuring to comply with ES6 has been a team effort. Special thanks to Tooru Fujisawa (arai) and Arpad Borsos (Swatinem) for their excellent contributions.

    Support for destructuring is under development for Chrome, and other browsers will undoubtedly add support in time. For now, you’ll need to use Babel or Traceur if you want to use destructuring on the Web.


    Thanks again to Nick Fitzgerald for this week’s post.

    Next week, we’ll cover a feature that is nothing more or less than a slightly shorter way to write something JS already has—something that has been one of the fundamental building blocks of the language all along. Will you care? Is slightly shorter syntax something you can get excited about? I confidently predict the answer is yes, but don’t take my word for it. Join us next week and find out, as we look at ES6 arrow functions in depth.

    Jason Orendorff
    ES6 In Depth editor

  2. Creating a mobile app from a simple HTML site: Part 4

    How to polish your app and prepare it for market

    In previous sections of this step-by-step series (Part 1, Part 2, and Part 3) we’ve created an app that loads multiple school plans from the server.

    What we have so far is functional, but still has a number of issues, including two which are major: no offline mode and a hard-coded configuration. In this closing post, we’ll work on all of these issues.

    If you haven’t built up the examples from the previous parts, use stage7 app and stage7 server as a starting point. To get started, follow the instructions on how to load any stage in this tutorial.

    Refactoring

    First, let’s do some refactoring. We’ll add a User object type to make it easier to choose which user’s plan to display. This will allow us to remove some more code from the app’s main logic flow, making the code cleaner and more modular. This object will load data from the server to create the plan UI. At the moment, rendering is done in app.onDeviceReady and app.renderData methods. Our new onDeviceReady method creates an app.user object and runs the methods needed to get and render plans. Replace the existing onDeviceReady method with the following:

    onDeviceReady: function() {
        app.user = new User('johndoe');
        app.user.getPlans();
    
        app.activateFingerSwipe();
    },

    Next, delete the app.renderData method completely. We will store this functionality inside our new User object instead, as you’ll see below.

    Next, at the beginning of the index.js file (before the definition of Plan), add the following code to define the User object:

    function User(userid) {
        this.id = userid;
        this.plans = [];
    }
    
    User.prototype.getPlans = function() {
        var self = this;
        var request = new XMLHttpRequest({
            mozAnon: true,
            mozSystem: true});
        request.onload = function() {
            var plans = JSON.parse(this.responseText);
            for (var i = 0; i < plans.length; i++) {
                self.plans.push(new Plan(plans[i]));
            }
            self.displayPlans();
        };
        request.open("get", app.getPlansURL + this.id, true);
        request.send();
    };
    
    User.prototype.displayPlans = function() {
        var self = this;
        navigator.globalization.getDateNames(function(dayOfWeek){
            var deck = document.getElementById('plan-group');
            var tabbar = document.getElementById('plan-group-menu');
            for (var i = 0; i < self.plans.length; i++) {
                self.plans[i].createUI(deck, tabbar, dayOfWeek);
            }
        }, function() {}, {type: 'narrow', item: 'days'});
    };

    This contains functionality previously found in renderData and onDeviceReady. After the plan’s JSON is loaded from the server we iterate over the list and create a list of Plan objects in user.plans. We then call user.displayPlans, which creates the required DOM environment and invokes plan.createUI for each element of user.plans.

    You may notice that the above code uses app.getPlansURL to allow the XHR call to find the JSON. Previously the URL was hardcoded into request.open("get", "http://127.0.0.1:8080/plans/johndoe", true);. Since it’s better to keep settings in one place we’ll add this as a parameter of the app object instead.

    Add the following into your code:

    var app = {
        getPlansURL: "http://127.0.0.1:8080/plans/",
        // ....
    }

    Now try preparing your app again with the cordova prepare terminal command, starting your server, and reloading the app in WebIDE (as we’ve done in previous articles). The app should work as before.

    Offline mode

    Let’s turn our attention to making the app work offline.

    There are several technologies available to store data on the device. I’ve decided to use the localStorage API, as the data we need to store is basically just simple strings and doesn’t need any complex structuring. As this is a key/value store, objects need to be stringified (represented as a string). I will use only two functions — setItem() and getItem(). For example, storing a user id would require you to call localStorage.setItem('user_id', user.id);.

    There are two values we definitely need to store in the phone memory — the ids of the current user and the plans. To make the app fully open and allow users to use servers not provided by the app creators we also need to store the server address. We’ll start by storing the plans. The user id and server will be still hardcoded. Let’s add a new method — User.loadPlans — and call that from app.onDeviceReady, instead of calling both user.getPlans() and app.user.displayPlans. We will decide if the plans need to be loaded from the server and then display the plans by calling User.displayPlans() from User.loadPlans.

    First update onDeviceReady again, to this:

    onDeviceReady: function() {
        app.user = new User('johndoe');
        app.user.loadPlans();
        app.activateFingerSwipe();
    },

    Now add in the following definition for the loadPlans method, up near your other User object-defining code:

    User.prototype.loadPlans = function() {
        var plans = localStorage.getItem('plans');
        if (plans === null) {
            return this.getPlans();
        }
        console.log('DEBUG: plans loaded from device');
        this.initiatePlans(plans);
        this.displayPlans();
    };

    The above method calls another new method — initiatePlans. This parses the JSON representation of the plans and initiates Plan objects inside the User.plans array. In the future we would like to be able to reload the plans from the server, but the existing code always adds new plans instead of replacing them.

    Add the following definition just below where you added the loadPlans code:

    User.prototype.initiatePlans = function(plansString) {
        var plans = JSON.parse(plansString);
        for (var i = 0; i < plans.length; i++) {
            this.plans.push(new Plan(plans[i]));
        }
    }

    We also need to store the plans on the client. The best point to do this is right after the plans have been loaded from the server. We will call localStorage.setItem('plans', this.responseText) inside the success response function of getPlans. We must also remember to call the initiatePlans method.

    Update your getPlans definition to the following:

    User.prototype.getPlans = function() {
        var self = this;
        var request = new XMLHttpRequest({
            mozAnon: true,
            mozSystem: true});
        request.onload = function() {
            console.log('DEBUG: plans loaded from server');
            self.initiatePlans(this.responseText);
            localStorage.setItem('plans', this.responseText);
            self.displayPlans();
        };
        request.onerror = function(error) {
            console.log('DEBUG: Failed to get plans from ``' + app.getPlansURL + '``', error);
        };
        request.open("get", app.getPlansURL + this.id, true);
        request.send();
    };

    At this moment, successful loading of the user’s plans happens only once. Since school plans change occasionally (usually twice a year) you should be able to reload the plans from the server any time you want. We can use User.getPlans to return updated plans, but first we need to remove existing plans from the UI, otherwise multiple copies will be displayed.

    Let’s create User.reloadPlans — add the code below your existing User object-defining code:

    User.prototype.reloadPlans = function() {
        // remove UI from plans
        for (var i = 0; i < this.plans.length; i++) {
            this.plans[i].removeUI();
        }
        // clean this.plans
        this.plans = [];
        // clean device storage
        localStorage.setItem('plans', '[]');
        // load plans from server
        this.getPlans();
    };

    There is a new method to add to the Plan object too — Plan.removeUI — which simply calls Element.remove() on a plan’s card and tab. Add this below your previous Plan object-defining code:

    Plan.prototype.removeUI = function() {
        this.card.remove();
        this.tab.remove();
    };

    This is a good time to test if the code has really reloaded. Run cordova prepare again on your code, and reload it in WebIDE.

    We’ve got two console.log statements inside loadPlans and getPlans to let us know if the plans are loaded from device’s storage or the server. To initiate a reload run this code in Console:

    app.user.reloadPlans()

    Note: Brick reports an error at this point, as the link between each tab and card has been lost inside the internal system. Please ignore this error. Once again, our app still works.

    reloadPlans from Console

    Let’s make the reload functional by adding a UI element to reload the plans. In index.html, wrap a div#topbar around the brick-tabbar. First, add a reload button:

    <div id="reload-button"></div>
    <div id="topbar">
        <brick-tabbar id="plan-group-menu">
        </brick-tabbar>
    </div>

    Now we’ll make the button float to the left and use calc to set the size of the div#topbar. This makes Brick’s tabbar calculate the size when layout is changed (portrait or horizontal). In css/index.css, add the following at the bottom of the file:

    #topbar {
    	width: calc(100% - 45px);
    }
    
    #reload-button {
    	float: left;
    	/* height of the tabbar */
    	width: 45px;
    	height: 45px;
    	background-image: url('../img/reload.svg');
    	background-size: 25px 25px;
    	background-repeat: no-repeat;
    	background-position: center center;
    }

    We will download some Gaia icons to use within the application. At this stage, you should save the reload.svg file inside your img folder.

    Last detail: Listen to the touchstart event on the #reload-button and call app.user.reloadPlans. Let’s add an app.assignButtons method:

    assignButtons: function(){
        var reloadButton = document.getElementById('reload-button');
        reloadButton.addEventListener('touchstart', function() {
            app.user.reloadPlans();
        }, false);
    },

    We need to call it from app.deviceReady before or after app.activateFingerSwipe().

    onDeviceReady: function() {
        // ...
        app.activateFingerSwipe();
        app.assignButtons();
    },

    At this point, save your code, prepare your cordova app, and reload it in WebIDE. You should see something like this:

    reload button

    Here you can find current code for app and server.

    Settings page

    Currently all of the identity information (the address of the server and user id) is hardcoded in the app. If the app is to be used with others, we provide functionality for users to set this data without editing the code. We will implement a settings page, using Brick’s flipbox component to change from content to settings and vice versa.

    First we must tell the app to load the component. Let’s change index.html to load the flipbox widget by adding the following line into the HTML <head> section:

    <link rel="import" href="app/bower_components/brick-flipbox/dist/brick-flipbox.html">

    Some changes must happen inside the HTML <body> as well. brick-topbar and brick-deck need to be placed inside switchable sections of the same flipbox, and the reload button also moves to inside the settings. Replace everything you’ve got in your <body> so far with the following (although you need to leave the <script> elements in place at the bottom):

    <brick-flipbox>
        <section id="plans">
            <div id="settings-button"></div>
            <div id="topbar">
                <brick-tabbar id="plan-group-menu">
                </brick-tabbar>
            </div>
            <brick-deck id="plan-group">
            </brick-deck>
        </section>
        <section id="settings">
            <div id="settings-off-button"></div>
            <h2>Settings</h2>
        </section>
    </brick-flipbox>

    The idea is to switch to the “settings” view on pressing a settings-button, and then back to the “plans” view with the settings-off-button.

    Here’s how to wire up this new functionality. First up, inside your app definition code add a toggleSettings() function, just before the definition of assignButtons():

    toggleSettings: function() {
        app.flipbox.toggle();
    },

    Update assignButtons() itself to the following (we are leaving the reloadButton code here, as we’ll need it again soon enough):

    assignButtons: function() {
        app.flipbox = document.querySelector('brick-flipbox');
        var settingsButton = document.getElementById('settings-button');
        var settingsOffButton = document.getElementById('settings-off-button');
        settingsButton.addEventListener('click', app.toggleSettings);
        settingsOffButton.addEventListener('click', app.toggleSettings);
            
        var reloadButton = document.getElementById('reload-button');
        reloadButton.addEventListener('touchstart', function() {
            app.user.reloadPlans();
        }, false);
    },

    Next: we need to retrieve some more icons for the app. Save the settings.svg and back.svg files inside your img folder.

    Let’s update our css/index.css file too, to add the additional icons in and style our new features. Add the following at the bottom of that file:

    #form-settings {
        font-size: 1.4rem;
        padding: 1rem;
    }
    #settings-button, #settings-off-button {
        float: left;
        width: 45px;
        height: 45px;
        background-size: 25px 25px;
        background-repeat: no-repeat;
        background-position: center center;
    }
    #settings-button {
        background-image: url('../img/settings.svg');
    }
    #settings-off-button {
        background-image: url('../img/back.svg');
        border-right: 1px solid #ccc;
        margin-right: 15px;
    }
    brick-flipbox {
        width: 100%;
        height: 100%;
    }

    If you now prepare your cordova app again with cordova prepare, and reload the app inside WebIDE, you should see something like this:

    flipbox working

    Adding a settings form

    To add a form and some data, replace your current <section id="settings"></section> element with the following:

    <section id="settings">
        <div id="settings-off-button"></div>
        <h2>Settings</h2>
        <form id="form-settings">
            <p><label for="input-server">Server</label></p>
            <p><input type="text" id="input-server" placeholder="http://example.com/"/></p>
            <p><label for="input-user" id="label-user">User ID</label></p>
            <p><input type="text" id="input-user" placeholder="johndoe"/></p>
            <p><button id="reload-button">RELOAD ALL</button></p>
        </form>
    </section>

    Making it look good is easy! We’ll use some ready-made CSS available in Firefox OS Building Blocks. Download input_areas.css and buttons.css and save them in your www/css directory.

    Then add the following to your HTML <head>, to apply the new CSS to your markup.

    <link rel="stylesheet" type="text/css" href="css/input_areas.css">
    <link rel="stylesheet" type="text/css" href="css/buttons.css">

    Go into the css/index.css file and delete the #reload-button { ... } rule to make the “RELOAD ALL” button display correctly.

    Run cordova prepare again and reload the app in WebIDE, and you should see something like this:

    settings

    We’ve got the view — now to support it. When the app first installs there will be no setting, so the app will have no idea how to load the data. Instead of showing empty plans we immediately toggle the view to the settings. Update your onDeviceReady function as shown:

    onDeviceReady: function() {
        app.plansServer = localStorage.getItem('plansServer');
        app.userID = localStorage.getItem('userID');
        app.activateFingerSwipe();
        app.assignButtons();
    
        if (app.plansServer && app.userID) {
            app.user = new User(app.userID);
            app.user.loadPlans();
        } else {
            app.toggleSettings();
        }
    },

    The app needs to read the data from our form inputs, so save them into the phone’s storage, and reload after the change. Let’s add this functionality at the end of the app.assignButtons function. First we will stop the form from submitting (otherwise our app would just reload the index.html instead of redrawing the content). Add the following code to the end of the assignButtons function, just before the closing },:

    document.getElementById('form-settings').addEventListener('submit', function(e) {
        e.preventDefault();
    }, false)

    We will read and set the input value for the server. I’ve decided to read the input value on the blur event. It is dispatched when the user touches any other DOM Element on the page. When this happens, the server value is stored in the device’s storage. If app.plansServer exists on app launch, we set the default input value. The same has to happen for the userID, but there is a special step. Either we change the app.user or create a new one if none exists. Add the following just above the previous block of code you added:

    var serverInput = document.getElementById('input-server');
    serverInput.addEventListener('blur', function() {
        app.plansServer = serverInput.value || null;
        localStorage.setItem('plansServer', app.plansServer);
    });
    if (app.plansServer) {
        serverInput.value = app.plansServer;    
    }
    
    var userInput = document.getElementById('input-user');
    userInput.addEventListener('blur', function() {
        app.userID = userInput.value || null;
        if (app.userID) {
            if (app.user) {
                app.user.id = app.userID;
            } else {
                app.user = new User('app.userID');
            }
            localStorage.setItem('userID', app.userID);
        }
    });
    if (app.userID) {
        userInput.value = app.userID;    
    }

    After preparing your app and reloading it in WebIDE, you should now see the settings working as expected. The settings screen appears automatically if no plans are found in the localstorage, allowing you to enter your server and userID details.

    Test it with the following settings:

    • Server: http://127.0.0.1:8080
    • User ID: johndoe

    The only inconvenience is that you need to switch back to the plans view manually once Settings are loaded. In addition, you might get an error if you don’t blur out of both form fields.

    settings are working

    Improving the settings UX

    In fact, switching back to the plans view should be done automatically after plans are successfully loaded. We can implement this by adding a callback to the User.getPlans function, and including it in the call made from User.reloadPlans:

    First, update your getPlans() function definition to the following:

    User.prototype.getPlans = function(callback) {
        var self = this;
        var url = app.plansServer + '/plans/' + this.id;
        var request = new XMLHttpRequest({
            mozAnon: true,
            mozSystem: true});
        request.onload = function() {
            console.log('DEBUG: plans loaded from server');
            self.initiatePlans(this.responseText);
            localStorage.setItem('plans', this.responseText);
            self.displayPlans();
            if (callback) {
                callback();
            }
        };
        request.open("get", url, true);
        request.send();
    };

    Next, in User.reloadPlans add the callback function as an argument of the this.getPlans call:

    this.getPlans(app.toggleSettings);

    Again, try saving, preparing, and reloading your new code. You should now see that the app displays the plans view automatically when correct server and user information is entered and available. (It switches to the Settings view only if there is no error in self.initiatePlans(this.responseText).).

    final

    Where do we go from here

    Congratulations! You’ve reached the end of this 4-part tutorial, and you should now have your own working prototype of a fun school plan application.

    There is still plenty to do to improve the app. Here are some ideas to explore:

    • Writing JSON files is not a comfortable task. It would be better to add new functionality that lets you edit plans on the server. Assigning them to the user on the server opens new possibilities, and this would just require an action to sync the user account on both server and client.
    • Displaying hours would also be nice.
    • It would be cool to implement a reminder alarm for some school activities.

    Try implementing these yourself, or build out other improvements for your own school scheduling app. Let us know how it goes.

  3. ES6 In Depth: Rest parameters and defaults

    ES6 In Depth is a series on new features being added to the JavaScript programming language in the 6th Edition of the ECMAScript standard, ES6 for short.

    Today’s post is about two features that make JavaScript’s function syntax more expressive: rest parameters and parameter defaults.

    Rest parameters

    A common need when creating an API is a variadic function, a function that accepts any number of arguments. For example, the String.prototype.concat method takes any number of string arguments. With rest parameters, ES6 provides a new way to write variadic functions.

    To demonstrate, let’s write a simple variadic function containsAll that checks whether a string contains a number of substrings. For example, containsAll("banana", "b", "nan") would return true, and containsAll("banana", "c", "nan") would return false.

    Here is the traditional way to implement this function:

    function containsAll(haystack) {
      for (var i = 1; i < arguments.length; i++) {
        var needle = arguments[i];
        if (haystack.indexOf(needle) === -1) {
          return false;
        }
      }
      return true;
    }
    

    This implementation uses the magical arguments object, an array-like object containing the parameters passed to the function. This code certainly does what we want, but its readibility is not optimal. The function parameter list contains only one parameter haystack, so it’s impossible to tell at a glance that the function actually takes multiple arguments. Additionally, we must be careful to start iterating through arguments at index 1 not 0, since arguments[0] corresponds to the haystack argument. If we ever wanted to add another parameter before or after haystack, we would have to remember to update the for loop. Rest parameters address both of these concerns. Here is a natural ES6 implementation of containsAll using a rest parameter:

    function containsAll(haystack, ...needles) {
      for (var needle of needles) {
        if (haystack.indexOf(needle) === -1) {
          return false;
        }
      }
      return true;
    }
    

    This version of the function has the same behavior as the first one but contains the special ...needles syntax. Let’s see how calling this function works for the invocation containsAll("banana", "b", "nan"). The argument haystack is filled as usual with the parameter that is passed first, namely "banana". The ellipsis before needles indicates it is a rest parameter. All the other passed parameters are put into an array and assigned to the variable needles. For our example call, needles is set to ["b", "nan"]. Function execution then continues as normal. (Notice we have used the ES6 for-of looping construct.)

    Only the last parameter of a function may be marked as a rest parameter. In a call, the parameters before the rest parameter are filled as usual. Any “extra” arguments are put into an array and assigned to the rest parameter. If there are no extra arguments, the rest parameter will simply be an empty array; the rest parameter will never be undefined.

    Default parameters

    Often, a function doesn’t need to have all its possible parameters passed by callers, and there are sensible defaults that could be used for parameters that are not passed. JavaScript has always had a inflexible form of default parameters; parameters for which no value is passed default to undefined. ES6 introduces a way to specify arbitrary parameter defaults.

    Here’s an example. (The backticks signify template strings, which were discussed last week.)

    function animalSentence(animals2="tigers", animals3="bears") {
        return `Lions and ${animals2} and ${animals3}! Oh my!`;
    }
    

    For each parameter, the part after the = is an expression specifying the default value of the parameter if a caller does not pass it. So, animalSentence() returns "Lions and tigers and bears! Oh my!", animalSentence("elephants") returns "Lions and elephants and bears! Oh my!", and animalSentence("elephants", "whales") returns "Lions and elephants and whales! Oh my!".

    The are several subtleties related to default parameters:

    • Unlike Python, default value expressions are evaluated at function call time from left to right. This also means that default expressions can use the values of previously-filled parameters. For example, we could make our animal sentence function more fancy as follows:

      function animalSentenceFancy(animals2="tigers",
          animals3=(animals2 == "bears") ? "sealions" : "bears")
      {
        return `Lions and ${animals2} and ${animals3}! Oh my!`;
      }
      

      Then, animalSentenceFancy("bears") returns "Lions and bears and sealions. Oh my!".

    • Passing undefined is considered to be equivalent to not passing anything at all. Thus, animalSentence(undefined, "unicorns") returns "Lions and tigers and unicorns! Oh my!".

    • A parameter without a default implicitly defaults to undefined, so

      function myFunc(a=42, b) {...}
      

      is allowed and equivalent to

      function myFunc(a=42, b=undefined) {...}
      

    Shutting down arguments

    We’ve now seen that rest parameters and defaults can replace usage of the arguments object, and removing arguments usually makes the code nicer to read. In addition to harming readibility, the magic of the arguments object notoriously causes headaches for optimizing JavaScript VMs.

    It is hoped that rest parameters and defaults can completely supersede arguments. As a first step towards this, functions that use a rest parameter or defaults are forbidden from using the arguments object. Support for arguments won’t be removed soon, if ever, but it’s now preferable to avoid arguments with rest parameters and defaults when possible.

    Browser support

    Firefox has had support for rest parameters and defaults since version 15.

    Unfortunately, no other released browser supports rest parameters or defaults yet. V8 recently added experimental support for rest parameters, and there is an open V8 issue for implementing defaults. JSC also has open issues for rest parameters and defaults.

    The Babel and Traceur compilers both support default parameters, so it is possible to start using them today.

    Conclusion

    Although technically not allowing any new behavior, rest parameters and parameter defaults can make some JavaScript function declarations more expressive and readable. Happy calling!


    Note: Thanks to Benjamin Peterson for implementing these features in Firefox, for all his contributions to the project, and of course for this week’s post.

    Next week, we’ll introduce another simple, elegant, practical, everyday ES6 feature. It takes the familiar syntax you already use to write arrays and objects, and turns it on its head, producing a new, concise way to take arrays and objects apart. What does that mean? Why would you want to take an object apart? Join us next Thursday to find out, as Mozilla engineer Nick Fitzgerald presents ES6 destructuring in depth.

    Jason Orendorff
    ES6 In Depth editor

  4. Developer Edition 40: Always active network monitoring, CSS rules filtering, and much more

    Firefox 40 was just uplifted, and we have a lot of updates to share. This release took a major effort by Developer Tools contributors to address feedback we’ve heard directly from people using our tools. Grab a copy of the Developer Edition browser and check it out.

    Experimental Multi-process Support: A Request

    When you update to Developer Edition 40, you’ll be prompted to opt in to test multi-process Firefox. Please consider helping us test this new feature and providing feedback around any issues you see.

    New in the Inspector

    • There is now a filter box in the CSS Rules view that lets you find rules that match a string. See the Filter Styles screencast or the screenshot below. (Development notes: 1120616 and 1157293.)

    Inspector Filter Styles Screenshot

    • There is a new CSS documentation tooltip for CSS properties. Right click on any property in the CSS Rules view and select “Show MDN Docs” to see more information about that property. (Development notes.)

    MDN Tooltip In Inspector Screenshot

    • Inspector search now includes results from iframes and also includes class / id results without the CSS prefix. (Development notes: 873443 and 1149346.)
    • There is a new CSS Filter Editor Tooltip added by Mahdi Dibaiee. Check out the CSS Filter Editor Tooltip screencast for a demo, or try it on the filter demos page in Developer Edition. (development notes)
    • The Animation Inspector has had some major updates. It now shows subtree animations, playback rate can be controlled, and it previews and highlights animated DOM nodes. (Development notes: 1155651, 1155653, and 1144615.)

    There are too many changes to list in this post, but here are a few more interesting updates you may come across in the Inspector:

    • The Box Model view has legends for the regions and tooltips to show which CSS rule invoked the computed value. (Development notes: 1141571 and 1151956.)
    • shift+clicking a color swatch switches between color unit formats in place. (Development notes.)
    • New Scroll Into View, Open Link in New Tab, Copy Link, Open In Style Editor, and Open in Debugger context menu items in the Markup View. (Development notes: 901250, 921102, and 1158822.)

    Network Monitor News

    Cached network requests in Network Monitor Screenshot

    Here’s a selection of other changes and improvements in this release:

    • New Copy Response, Copy URL parameters, and Copy Request/Response Headers context menu items on each request. (Development notes: 955933, 1150717, and 1150715.)
    • Search box to filter requests. (Development notes.)
    • IP address included in Domain tooltip for network monitor. (Development notes.)
    • Added access keys to the request context menu. (Development notes.)

    Web Console

    • New console method: console.dirxml(). (Development notes.)
    • New filter options in the web console to show console messages from workers. (Development notes.)
    • Quotes in strings are no longer added if logged via console.log. Thanks to new contributor Dmitry Sagalovskiy for adding this feature! (Development notes.)

    Debugger

    General

    Special thanks to all the people who contributed patches to Firefox Developer Tools this release! Here is a list of all the DevTools bugs resolved for Firefox 40. Kudos to the many contributors.

    Do you have feedback, bug reports, feature requests, or questions? As always, you can comment here, get in touch with the team at @FirefoxDevTools, or share your constructive feedback and feature requests on our Firefox Dev Tools feedback channel.

  5. Let’s get charged: Updates to the Battery Status API

    Web APIs provide a way for Open Web Apps to access device hardware, data and sensors through JavaScript, and open the doors to a number of possibilities especially for mobile devices, TVs, interactive kiosks, and Internet of Things (IoT) applications.

    Knowing the battery status of a device can be useful in a number of situations or use cases. Here are some examples:

    • Utility apps that collect statistics on battery usage or simply inform the user if the device is charged enough to play a game, watch a movie, or browse the Web.
    • High-quality apps that optimize battery consumption: for example, an email client may check the server for new email less frequently if the device is low on battery.
    • A word processor could save changes automatically before the battery runs out in order to prevent data loss.
    • A system checking if an interactive kiosk or TV installed in a showroom of an event is charging or if something wrong happened with the cables
    • A module that checks the battery status of a drone in order to make it come back to the base before it runs out of power.

    This article looks at a standardized way to manage energy consumption: The Battery Status API.

    The Battery Status API

    Open Web Apps can retrieve battery status information thanks to the Battery Status API, a W3C Recommendation supported by Firefox since version 16. The API is also supported by Firefox OS, and recently by Chrome, Opera, and the Android browser, so now it can be used in production across many major platforms.

    Also, the W3C Recommendation has recently been improved, introducing Promise Objects, and the ability to handle multiple batteries installed on the same device.

    At the time of writing, this W3C update has not yet been implemented by Firefox: please check the following bugs for implementation updates or in case you want to contribute to Gecko development:

    • [1050749] Expose BatteryManager via getBattery() returning a Promise instead of a synchronous accessor (navigator.battery)
    • [1050752] BatteryManager: specify the behavior when a host device has more than one battery

    Below we will look at using the Battery Status API in an instant messaging app running on Firefox OS and all the browsers that currently support the API.

    Demo: Low Energy Messenger

    Low Energy Messenger is an instant messaging demo app that pays close attention to battery status. The app has been built with HTML + CSS + Javascript (no libraries) and uses static data. It does not include web services running on the Internet, but includes real integration with the Battery Status API and has a realistic look & feel.

    You’ll find a working demo of Low Energy Messenger, along with the demo code on Github, and an >MDN article called Retrieving Battery status information that explains the code step-by-step.

    Low Energy Messenger

    Low Energy Messenger has the following features:

    • A battery status bar, containing battery status information.
    • A chat section, containing all the messages received or sent.
    • An action bar, containing a text field, a button to send a message, a button to take a photo, and a button to install the app on Firefox OS
    • In order to preserve battery life when the power level is low, the app doesn’t allow users to take photos when the device is running out of battery.

    The visual representation of the battery, in the app’s status bar, changes depending on the charge level. For example:

    13% Discharging: 0:23 remaining
    40% Discharging: 1:19 remaining
    92% Charging: 0:16 until full

    Low Energy Messenger includes a module called EnergyManager.js that uses the Battery Status API to get the information displayed above and perform checks.

    The battery object, of type BatteryManager, is provided by the navigator.getBattery method, using Promises, or by the deprecated navigator.battery property, part of a previous W3C specification and currently used by Firefox and Firefox OS. As mentioned above, follow this bug for implementation updates or if you want to contribute to Gecko development.

    The EnergyManager.js module eliminates this difference in API implementation in the following way:

    /* EnergyManager.js */
     init: function(callback) {
         var _self = this;
        /* Initialize the battery object */
        if (navigator.getBattery) {
           navigator.getBattery().then(function(battery) {
               _self.battery = battery;
               callback();
           });
        } else if (navigator.battery || navigator.mozBattery) { // deprecated battery objects
            _self.battery = navigator.battery || navigator.mozBattery;
            callback();
        }
     }

    The navigator.getBattery method returns a battery promise, which is resolved in a BatteryManager object providing events you can handle to monitor the battery status. The deprecated navigator.battery attribute returns the BatteryManager object directly; the implementation above checks for vendor prefixes as well, for even older, experimental, API implementations carried on by Mozilla in earlier stages of the specification.

    Logging into the Web Console of a browser is a useful way to understand how the Battery Status API actually works:

    /* EnergyManager.js */
     log: function(event) {
        if (event) {
            console.warn(event);
        }
        console.log('battery.level: ' + this.battery.level);
        console.log('battery.charging: ' + this.battery.charging);
        console.log('battery.chargingTime: ' + this.battery.chargingTime);
        console.log('battery.dischargingTime: ' + this.battery.dischargingTime);
     }

    Here is how the logs appear on the Web Console:

    Web Console

    Every time an event (dischargingtimechange, levelchange, etc.) gets fired, the BatteryManager object provides updated values that can be used by the application for any purpose.

    Conclusions

    The Battery Status API is a standardized way to access the device hardware and is ready to be used in production, even if at the time of writing some compatibility checks still have to be performed on Firefox. Also, the W3C specification is generic enough to be used in different contexts, thus the API covers a good number of real-world use cases.

  6. Diving into Rust for the first time

    Rust programming languageRust is a new programming language which focuses on performance, parallelization, and memory safety. By building a language from scratch and incorporating elements from modern programming language design, the creators of Rust avoid a lot of “baggage” (backward-compatibility requirements) that traditional languages have to deal with. Instead, Rust is able to fuse the expressive syntax and flexibility of high-level languages with the unprecedented control and performance of a low-level language.

    Choosing a programming language usually involves tradeoffs. While most modern high-level languages provide tools for safe concurrency and memory safety, they do this with added overhead (e.g. by using a GC), and tend to lack performance and fine-grained control.

    To deal with these limitations, one has to resort to low-level languages. Without the safety nets of most high-level languages this can be fragile and error-prone. One suddenly has to deal with manual memory management, resource allocation, dangling pointers, etc. Creating software that can leverage the growing number of cores present in today’s devices is difficult — making sure said code works correctly is even harder.

    So how does Rust incorporate the best of both worlds in one language? That’s what we’ll show you in this article. Rust 1.0.0 stable has just been released. The language already has a vibrant community, a growing ecosystem of crates (libraries) in its package manager, and developers harnessing its capabilities in a variety of projects. Even if you’ve never touched a lower-level language, it’s a perfect time for you to dive in!

    The community has celebrated Rust's first stable release worldwide at 'Rust release parties'Rust t-shirts celebrate the release of Rust 1.0 worldwide.

    Use cases for Rust today

    So for systems hackers, Rust seems like a great choice, but how about those who are not familiar with low-level languages? Maybe the last time you heard the words “C” and “stack/heap allocation” was 10 years ago in CompSci 101 (or maybe never). Rust provides the performance typically seen only in low-level systems languages — but most of the time it certainly feels like a high-level language! Here are a few examples of how you can leverage Rust now in practical applications:

    I want to hack on hardware/write Internet-of-Things applications

    The IoT era and the expansion of the maker movement enables a real democratization of hardware projects. Whether it is the Raspberry Pi, Arduino, or one of the young titans like the BeagleBone or Tessel, you can choose from a slew of languages to code your hardware projects, including Python or JavaScript.

    There are times, however, when the performance these languages offer is simply not adequate. At other times, the microcontroller hardware you are aiming for is not suited to the runtimes these languages require: slow chips with tiny memory reserves and ultra-low-power applications still require a close-to-the-metal language. Traditionally that language has been C — but as you might have guessed, Rust is the new kid on the block.

    Rust supports a wide variety of exotic platforms. While some of this is still experimental, support includes generic ARM hardware, the Texas Instruments TIVA dev board, and even the Raspberry Pi. Some of the newest IoT boards like the Tessel 2 even come with official, out-of-the-box Rust support!

    I’m operating high-performance computing applications that scale to multiple cores

    Studies suggest Rust is already great for HPC (high-performance computing). You don’t even have to rewrite your whole application in Rust: its flexible Foreign Function Interface (FFI) provides efficient C bindings that let you expose and call Rust code without any noticable overhead. This allows you to rewrite your app module by module, slowly transitioning towards a better developer experience that will result in performance on par with the old code or better. You also get a more maintainable codebase with fewer errors, which scales better on a high number of cores.

    I simply need something fast!

    Rust is great for rewriting performance-sensitive parts of your application. It interfaces well with other languages via FFI and has a tiny runtime that competes with C and C++ in most cases, even when resources are limited.

    Despite the work-in-progress nature of the language, there are already business-critical, live production applications that have been making good use of Rust for some time: Yehuda Katz’s startup, Skylight uses high-performance Rust code embedded in a ruby gem for data-crunching. The 1.0.0 stable release is also an important milestone in that no breaking changes should happen from now on. That makes it safe to recommend Rust for even the most demanding and robust applications!

    Watch Yehuda Katz and Tom Dale talk about the basics of Rust programming and how they used Rust with Ruby in their app.

    Getting started with Rust

    There are many tutorials covering Rust in general, as well as specific aspects of the language. For example, the Rust blog has great articles on various facets of developing Rust applications. There are also excellent introductory talks such as Aaron Turon’s talk at Stanford University. He explains the main concepts and motivations behind Rust nicely, and the talk serves as the perfect appetizer, starting you on your journey:

    Talks and tutorials are no substitute for writing code, right? Rust’s got you covered in that regard, too! The Rust Book was conceived to help you get started — from installation to that first Hello World to providing an in-depth reference for all the core language features.

    Another resource worth mentioning is Rust by Example, which guides you through Rust’s key features, from the basics to the arcane powers of traits, macros, and the FFI. Rust By Example offers invaluable live-editable, in-browser examples with all of the articles. You don’t even have to download and compile Rust, as you can try (and edit) all of these examples from the comfort of your living room couch, just as they are. There is also a Rust Playpen for the exact same purpose.

    Not that downloading and installing Rust is much trouble, anyway. Head to the Rust homepage and download the appropriate binary/installer there. The downloads contain all the tools you need to get started (like rustc, the compiler, or cargo the package manager), and are available pre-built for all platforms (Windows, Linux, and OSX).

    What is it then, that makes Rust so unique, so different?

    The Rust Way

    Arguably it’s Rust’s unique ownership model that allows it to really shine — eliminating whole classes of errors related to threading and memory management, while easing development and debugging. It is also invaluable in keeping the language runtime minimal and the compiler output lean and performant.

    The ownership model

    The basic principle of Rust’s ownership model is that every resource can belong to one and only one “owner.” A “resource” can be anything — from a piece of memory to an open network socket to something more abstract like a mutex lock. The owner of said resource is responsible for using, possibly lending out the resource (to other users), and finally cleaning it up.

    All this happens automatically, with the help of scopes and bindings: bindings either own or borrow values, and last till the end of their scope. As bindings go out of scope, they either give their borrowed resource back, or in case they were the owner, dispose of the resource.

    What’s even better is that the checks required for the ownership model to work are executed and enforced by the Rust compiler and “borrow checker” during compilation, which in turn results in various benefits.

    Zero-cost abstractions

    Since the correct operation of a program is asserted at compilation time, code that compiles can generally be considered safe with regard to most common types of memory and concurrency errors (such as use-after-free bugs or data races). This is possible because Rust complains at compilation time if the programmer attempts to do something that violates the principles above, which in turn helps keep the language runtime minimal.
    By deferring these checks till compilation time, there’s no need to perform them during runtime (code is already “safe”), and no runtime overhead. In the case of memory allocations, there is no need for runtime garbage collection, either. This — advanced language constructs with little to no runtime overhead — is the basic idea of “zero-cost abstractions.”

    Though a thorough explanation of the ownership model is outside the scope of this article, the Rust Book (linked above) and various talks and articles excel in explaining its principles. The principles of ownership and the borrow checker are essential for understanding Rust, and are key to other powerful aspects of the language, like its handling of concurrency and parallelism.

    Two birds, one language construct

    Shared mutable state is the root of all evil. Most languages attempt to deal with this problem through the mutable part, but Rust deals with it by solving the shared part.
    The Rust Book

    Aside from memory safety, paralellism and concurrency are the second most important focus in Rust’s philosophy. It might seem surprising, but the ownership system (coupled with a few handy traits) also provides powerful tools for threading, synchronization, and concurrent data access.

    When you try some of the built-in concurrency primitives and start digging deeper into the language, it may come as a surprise that those primitives are provided by the standard library, rather than being part of the language core itself. Thus, coming up with new ways to do concurrent programming is in the hands of library authors — rather than being hard-wired into Rust, restricted by the language creators’ future plans.

    Performance or expressiveness? Choose both!

    Thanks to its static type system, carefully selected features, and having no garbage collector, Rust compiles into performant and predictable code that’s on par with code written in traditional, low-level languages (such as C/C++).

    By moving the various checks out of the runtime and getting rid of garbage collection, the resulting code mimics the performance characteristics of other low-level languages, while the language itself remains much more expressive. The (seemingly) high level constructs (strings, collections, higher order functions, etc.) mostly avoid the runtime performance hit commonly associated with them. Since the Rust compiler’s output is in the LLVM intermediate representation, the final machine code makes good use of the LLVM compiler’s cross-platform benefits and all additional (current and future) optimizations automatically.

    We could go on for hours about how with Rust you never have to worry about closing sockets or freeing memory, how traits and macros give you incredible flexibility for overloading operators, or even working with Rust’s functional aspect, juggling iterators, closures and higher order functions. But we wouldn’t want to overwhelm you early on! Sooner or later you will come across these anyway — and it’s more fun to discover for yourself exactly how deep the rabbit hole is.

    So now instead, let’s finally look at some code.

    Say hello to Rust

    Without further ado — your very first Rust code:

    fn main() {
        println!("Hello, Rust!");
    }

    Open this snippet in the Online Rust Playpen >>

    Wait, is that it? This may seem a bit anti-climactic, but there are only so many ways to write a Hello World in Rust. Bear with us while we share a slightly more complex example — and another timeless classic.

    What’s all this Fizzbuzz about

    We are going old-school with the FizzBuzz program! Fizzbuzz is an algorithm in which we count upwards for all eternity, replacing some of the numbers with fizz (for numbers evenly divisible by 3), buzz (for numbers divisible by 5), or fizzbuzz (divisible by both 3 and 5).

    Also to show our point (and to help familiarize you with Rust’s semantics), we have included the C and Python versions of the same algorithm:

    Imperative fizzbuzz – C version

    #include 
    
    int main(void)
    {
        int num;
        for(num=1; num<101; ++num)
        {
            if( num%3 == 0 && num%5 == 0 ) {
                printf("fizzbuzz\n");
            } else if( num%3 == 0) {
                printf("fizz\n");
            } else if( num%5 == 0) {
                printf("buzz\n");
            } else {
                printf("%d\n",num);
            }
        }
    
        return 0;
    }
    
    Imperative fizzbuzz – Python version

    for num in xrange(1,101):
        if num%3 == 0 and num%5 == 0:
            print "fizzbuzz"
        elif num%3 == 0:
            print "fizz"
        elif num%5 == 0:
            print "buzz"
        else:
            print num
    
    Imperative fizzbuzz – Rust version

    fn main() {
        for num in 1..101 { // Range notation!
            match (num%3, num%5) { // Pattern Matching FTW!
                (0, 0) => println!("fizzbuzz"),
                (0, _) => println!("fizz"),
                (_, 0) => println!("buzz"),
                     _ => println!("{}", num) 
            }
        }
    }
    

    Open this snippet in the Online Rust Playpen >>

    Even on such a small snippet, some of Rust’s power starts to show. The most obvious difference might be that we are using pattern matching, instead of traditional if statements. We could use those, however match is a very useful addition to a Rustacean‘s arsenal.

    The other thing to note is the range notation in the for-loop’s declaration (similar to its Python counterpart). It interesting, though, that in this case we could not have used a “traditional” C-like for loop instead — as it is by design unsupported in Rust. Traditional for loops are considered error-prone and are replaced with the safer and more flexible iterable concept.

    Here’s a more elaborate look at what happens in the pattern-matching phase of our fizzbuzz example:

    ...
     
    // For pattern matching, we build a tuple, containing
    // the remainders for integer division of num by 3 and 5
    match (num%3, num%5) {
        // When "num" is divisible by 3 AND 5 both
        // (both remainders are 0)
        // -> print the string "fizzbuzz"
        (0, 0) => println!("fizzbuzz"),
    
        // When "num" is divisible by 3 (the remainder is 0)
        // Is "num" divisible by 5? -> we don't care
        // -> print the string "fizz"
        (0, _) => println!("fizz"),
    
        // When "num" is divisible by 5 (the remainder is 0)
        // Is "num" divisible by 3? -> we don't care
        // -> print the string "buzz"
        (_, 0) => println!("buzz"),
    
        // In any other cases, just print num's value
        // Note, that matching must be exhaustive (that is,
        // cover all possible outcomes) - this is enforced
        // by the compiler!
             _ => pintln!("{}", num)
    }
    ...
    

    This is not the place to go deep on how pattern matching or destructuring work, or what tuples are. You’ll find excellent articles on these topics in the Rust Book, the Rust Blog, or over at Rust By Example, but we think it’s a great way to demonstrate the features and nuances that make Rust both powerful and effective.

    How about some functional Fizzbuzz

    To expand on the last example and demonstrate Rust’s true flexibility, in our second example we’ll crank our fizzbuzz up a notch! Rust calls itself multi-paradigm. We can put that to the test by rewriting our fizzbuzz example in functional style. To help put the code in perspective, we will also show the implementations in JavaScript (the ECMAScript 6 flavor), too:

    Functional fizzbuzz – JavaScript (ES6) version

    Array.from(Array(100).keys()).slice(1)
        .map((num) => {
            if (num%3 === 0 && num%5 === 0) {
                return "fizzbuzz";
            } else if (num%3 === 0) {
                return "fizz";
            } else if (num%5 === 0) {
                return "buzz";
            } else {
                return num;
            }
        })
        .map(output => console.log(output));
    
    Functional fizzbuzz – Rust version

    fn main() {
        (1..101)
            .map(|num| {
                match (num%3, num%5) { // Pattern Matching FTW!
                    (0, 0) => "fizzbuzz".to_string(),
                    (0, _) => "fizz".to_string(),
                    (_, 0) => "buzz".to_string(),
                         _ => format!("{}", num) 
                }
            })
            .map(|output| { println!("{}", output); output })
            .collect::<Vec<_>>();
    }
    

    Open this snippet in the Online Rust Playpen >>

    Not only can we mimic JavaScript’s functional style with closures and functional method calls, but thanks to Rust’s powerful pattern matching, we can even trump JavaScript’s expressiveness a bit.

    Note: Rust’s iterators are lazy, so we actually need the .collect() call (which is called a consumer) for this to work — if you leave that out, none of the above code will execute. Check out the consumers section of the Rust Book to learn more.

    Picking a project

    You’re eager to dive into Rust and ready to start something cool. But what to build? You could start small—write a small app or a tiny library, and upload it to crates.io. People have created many exciting projects in Rust already — from pet *nix-like kernels to embedded hardware projects, from games to web server frameworks, proving that the only limit is your imagination.

    If you want to start small, but contribute something useful while learning the intricacies of Rust programming, consider contributing to some of the projects already thriving on GitHub (or even the Rust compiler itself — which is also written in Rust).
    Or, you could start by rewriting small parts of your production app, and experimenting with the results. Rust’s Foreign Function Interface (FFI) is intended as a drop-in replacement for C code. With minimal effort you could replace small parts of your application with Rust implementations of the same code. But interoperability doesn’t stop there — these C bindings work both ways. This means you can use all standard C libraries in your Rust apps — or (since many programming languages come with standard C interface libraries) make calls back-and-forth between Rust and Python, Ruby, or even Go!

    Watch Dan Callahan’s talk “My Python’s a little Rust-y on how to hook up Rust with Python.

    There are virtually no languages that don’t work with Rust: want to compile Rust to JavaScript or use inline assembly in your code? Yes, you can!

    Now get out there and build something awesome.

    Please don’t forget — Rust is not simply a programming language — it’s also a community. Should you ever feel stuck, don’t be shy to ask for help, either on the Forums or IRC. You could also share your thoughts and creations on the Rust Reddit.

    Rust is already great — it’s people like you who are going to make it ever more awesome!

  7. ES6 In Depth: Template strings

    ES6 In Depth is a series on new features being added to the JavaScript programming language in the 6th Edition of the ECMAScript standard, ES6 for short.

    Last week I promised a change of pace. After iterators and generators, we would tackle something easy, I said. Something that won’t melt your brain, I said. We’ll see whether I can keep that promise in the end.

    For now, let’s start with something simple.

    Backtick basics

    ES6 introduces a new kind of string literal syntax called template strings. They look like ordinary strings, except using the backtick character ` rather than the usual quote marks ' or ". In the simplest case, they really are just strings:

    context.fillText(`Ceci n'est pas une chaîne.`, x, y);
    

    But there’s a reason these are called “template strings” and not “boring plain old strings that don’t do anything special, only with backticks”. Template strings bring simple string interpolation to JavaScript. That is, they’re a nice-looking, convenient way to plug JavaScript values into a string.

    There are one million ways to use this, but the one that warms my heart is the humble error message:

    function authorize(user, action) {
      if (!user.hasPrivilege(action)) {
        throw new Error(
          `User ${user.name} is not authorized to do ${action}.`);
      }
    }
    

    In this example, ${user.name} and ${action} are called template substitutions. JavaScript will plug the values user.name and action into the resulting string. This could generate a message like User jorendorff is not authorized to do hockey. (Which is true. I don’t have a hockey license.)

    So far, this is just a slightly nicer syntax for the + operator, and the details are what you would expect:

    • The code in a template substitution can be any JavaScript expression, so function calls, arithmetic, and so on are allowed. (If you really want to, you can even nest a template string inside another template string, which I call template inception.)

    • If either value is not a string, it’ll be converted to a string using the usual rules. For example, if action is an object, its .toString() method will be called.

    • If you need to write a backtick inside a template string, you must escape it with a backslash: `\`` is the same as "`".

    • Likewise, if you need to include the two characters ${ in a template string, I don’t want to know what you’re up to, but you can escape either character with a backslash: `write \${ or $\{`.

    Unlike ordinary strings, template strings can cover multiple lines:

    $("#warning").html(`
      <h1>Watch out!</h1>
      <p>Unauthorized hockeying can result in penalties
      of up to ${maxPenalty} minutes.</p>
    `);
    

    All whitespace in the template string, including newlines and indentation, is included verbatim in the output.

    OK. Because of my promise last week, I feel responsible for your brain health. So a quick warning: it starts getting a little intense from here. You can stop reading now, maybe go have a cup of coffee and enjoy your intact, unmelted brain. Seriously, there’s no shame in turning back. Did Lopes Gonçalves exhaustively explore the entire Southern Hemisphere after proving that ships can cross the equator without being crushed by sea monsters or falling off the edge of the earth? No. He turned back, went home, and had a nice lunch. You like lunch, right?

    Backtick the future

    Let’s talk about a few things template strings don’t do.

    • They don’t automatically escape special characters for you. To avoid cross-site scripting vulnerabilities, you’ll still have to treat untrusted data with care, just as if you were concatenating ordinary strings.

    • It’s not obvious how they would interact with an internationalization library (a library for helping your code speak different languages to different users). Template strings don’t handle language-specific formatting of numbers and dates, much less plurals.

    • They aren’t a replacement for template libraries, like Mustache or Nunjucks.

      Template strings don’t have any built-in syntax for looping—building the rows of an HTML table from an array, for example—or even conditionals. (Yes, you could use template inception for this, but to me it seems like the sort of thing you’d do as a joke.)

    ES6 provides one more twist on template strings that gives JS developers and library designers the power to address these limitations and more. The feature is called tagged templates.

    The syntax for tagged templates is simple. They’re just template strings with an extra tag before the opening backtick. For our first example, the tag will be SaferHTML, and we’re going to use this tag to try to address the first limitation listed above: automatically escaping special characters.

    Note that SaferHTML is not something provided by the ES6 standard library. We’re going to implement it ourselves below.

    var message =
      SaferHTML`<p>${bonk.sender} has sent you a bonk.</p>`;
    

    The tag here is the single identifier SaferHTML, but a tag can also be a property, like SaferHTML.escape, or even a method call, like SaferHTML.escape({unicodeControlCharacters: false}). (To be precise, any ES6 MemberExpression or CallExpression can serve as a tag.)

    We saw that untagged template strings are shorthand for simple string concatenation. Tagged templates are shorthand for something else entirely: a function call.

    The code above is equivalent to:

    var message =
      SaferHTML(templateData, bonk.sender);
    

    where templateData is an immutable array of all the string parts of the template, created for us by the JS engine. Here the array would have two elements, because there are two string parts in the tagged template, separated by a substitution. So templateData will be like Object.freeze(["<p>", " has sent you a bonk.</p>"].

    (There is actually one more property present on templateData. We won’t use it in this article, but I’ll mention it for completeness: templateData.raw is another array containing all the string parts in the tagged template, but this time exactly as they looked in the source code—with escape sequences like \n left intact, rather than being turned into newlines and so on. The standard tag String.raw uses these raw strings.)

    This gives the SaferHTML function free rein to interpret both the string and the substitutions in a million possible ways.

    Before reading on, maybe you’d like to try to puzzle out just what SaferHTML should do, and then try your hand at implementing it. After all, it’s just a function. You can test your work in the Firefox developer console.

    Here is one possible answer (also available as a gist).

    function SaferHTML(templateData) {
      var s = templateData[0];
      for (var i = 1; i < arguments.length; i++) {
        var arg = String(arguments[i]);
    
        // Escape special characters in the substitution.
        s += arg.replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;");
    
        // Don't escape special characters in the template.
        s += templateData[i];
      }
      return s;
    }
    

    With this definition, the tagged template SaferHTML`<p>${bonk.sender} has sent you a bonk.</p>` might expand to the string "<p>ES6&lt;3er has sent you a bonk.</p>". Your users are safe even if a maliciously named user, like Hacker Steve <script>alert('xss');</script>, sends them a bonk. Whatever that means.

    (Incidentally, if the way that function uses the arguments object strikes you as a bit clunky, drop by next week. There’s another new feature in ES6 that I think you’ll like.)

    A single example isn’t enough to illustrate the flexibility of tagged templates. Let’s revisit our earlier list of template string limitations to see what else you could do.

    • Template strings don’t auto-escape special characters. But as we’ve seen, with tagged templates, you can fix that problem yourself with a tag.

      In fact, you can do a lot better than that.

      From a security perspective, my SaferHTML function is pretty weak. Different places in HTML have different special characters that need to be escaped in different ways; SaferHTML does not escape them all. But with some effort, you could write a much smarter SaferHTML function that actually parses the bits of HTML in the strings in templateData, so that it knows which substitutions are in plain HTML; which ones are inside element attributes, and thus need to escape ' and "; which ones are in URL query strings, and thus need URL-escaping rather than HTML-escaping; and so on. It could perform just the right escaping for each substitution.

      Does this sound far-fetched because HTML parsing is slow? Fortunately, the string parts of a tagged template do not change when the template is evaluated again. SaferHTML could cache the results of all this parsing, to speed up later calls. (The cache could be a WeakMap, another ES6 feature that we’ll discuss in a future post.)

    • Template strings don’t have built-in internationalization features. But with tags, we could add them. A blog post by Jack Hsu shows what the first steps down that road might look like. Just one example, as a teaser:

      i18n`Hello ${name}, you have ${amount}:c(CAD) in your bank account.`
      // => Hallo Bob, Sie haben 1.234,56 $CA auf Ihrem Bankkonto.
      

      Note how in this example, name and amount are JavaScript, but there’s a different bit of unfamiliar code, that :c(CAD), which Jack places in the string part of the template. JavaScript is of course handled by the JavaScript engine; the string parts are handled by Jack’s i18n tag. Users would learn from the i18n documentation that :c(CAD) means amount is an amount of currency, denominated in Canadian dollars.

      This is what tagged templates are about.

    • Template strings are no replacement for Mustache and Nunjucks, partly because they don’t have built-in syntax for loops or conditionals. But now we’re starting to see how you would go about fixing this, right? If JS doesn’t provide the feature, write a tag that provides it.

      // Purely hypothetical template language based on
      // ES6 tagged templates.
      var libraryHtml = hashTemplate`
        <ul>
          #for book in ${myBooks}
            <li><i>#{book.title}</i> by #{book.author}</li>
          #end
        </ul>
      `;
      

    The flexibility doesn’t stop there. Note that the arguments to a tag function are not automatically converted to strings. They can be anything. The same goes for the return value. Tagged templates are not even necessarily strings! You could use custom tags to create regular expressions, DOM trees, images, promises representing whole asynchronous processes, JS data structures, GL shaders...

    Tagged templates invite library designers to create powerful domain-specific languages. These languages might look nothing like JS, but they can still embed in JS seamlessly and interact intelligently with the rest of the language. Offhand, I can’t think of anything quite like it in any other language. I don’t know where this feature will take us. The possibilities are exciting.

    When can I start using this?

    On the server, ES6 template strings are supported in io.js today.

    In browsers, Firefox 34+ supports template strings. They were implemented by Guptha Rajagopal as an intern project last summer. Template strings are also supported in Chrome 41+, but not in IE or Safari. For now, you’ll need to use Babel or Traceur if you want to use template strings on the web. You can also use them right now in TypeScript!

    Wait—what about Markdown?

    Hmm?

    Oh. ...Good question.

    (This section isn’t really about JavaScript. If you don’t use Markdown, you can skip it.)

    With template strings, both Markdown and JavaScript now use the ` character to mean something special. In fact, in Markdown, it’s the delimiter for code snippets in the middle of inline text.

    This brings up a bit of a problem! If you write this in a Markdown document:

    To display a message, write `alert(`hello world!`)`.
    

    it’ll be displayed like this:

    To display a message, write alert(hello world!).

    Note that there are no backticks in the output. Markdown interpreted all four backticks as code delimiters and replaced them with HTML tags.

    To avoid this, we turn to a little-known feature that’s been in Markdown from the beginning: you can use multiple backticks as code delimiters, like this:

    To display a message, write ``alert(`hello world!`)``.
    

    This Gist has the details, and it’s written in Markdown so you can look at the source.

    Up next

    Next week, we’ll look at two features that programmers have enjoyed in other languages for decades: one for people who like to avoid an argument where possible, and one for people who like to have lots of arguments. I’m talking about function arguments, of course. Both features are really for all of us.

    We’ll see these features through the eyes of the person who implemented them in Firefox. So please join us next week, as guest author Benjamin Peterson presents ES6 default parameters and rest parameters in depth.

  8. Trainspotting: Firefox 38

    Trainspotting is a series of articles highlighting features in the latest version of Firefox, that are live now in production code, ready for you to use in your work. A new version of Firefox is shipped every six weeks – we at Mozilla call this pattern “release trains.”

    Has it been six weeks already?? Firefox 38 is here, and with it come some snazzy new additions to the Web platform. Here are a few highlights:

    For a full list of changes and additions, take a look at the Firefox 38 release notes.

    Responsive Image Support

    Support for both the <picture> element and <img srcset> are now in a stable Firefox! There are lots of great articles available to get you familiar with the new techniques, and a polyfill available so you can take advantage of them today! There is one caveat for Firefox 38 – responsive images will load using the correct media queries, but presently do not respond to viewport resizing. This bug is being actively worked on and tracked here, and will be fixed in a near-future version of Firefox.

    You got WebSockets in my Web Worker!

    Firefox 38 now allows code running in a Web Worker to open up a WebSocket connection. This is great for games or other collaborative applications, which can now do their multiplayer/realtime logic in a separate thread from the UI.

    HTML5 <ruby> markup support

    Ruby Annotation

    Better typography for Japanese and Chinese language sites is now possible without clunky libraries or extensions by using <ruby> markup.

    BroadcastChannel- postMessage All the Windows!

    If you’re building a webapp with multiple tabs or windows, keeping them all in sync, apprised of events and state changes can be a pain. BroadcastChannel is a fully client-side message passing API that lets any scripts running on the same origin broadcast messages to their peers.

    // one tab
    var ch = new BroadcastChannel('test');
    ch.postMessage('this is a test');
    
    // another tab
    ch.addEventListener('message', function (e) {
        alert('I got a message!', e.data);
    });
    
    // yet another tab
    ch.addEventListener('message', function (e) {
        alert('Avast! a message!' e.data);
    });

    Developer Tools

    Network requests coming from XMLHttpRequest are now marked in the Web Console:

    XMLHttpRequest requests marked in the Web Console

    Need to grab a value from your page? The special copy method available in the Web Console has you covered:

    consolecopy

    But Wait

    There are tons more improvements and bug fixes in Firefox 38 I haven’t covered here – check out the Firefox 38 release notes, Developer Release Notes, or even the list of bugs fixed in this release for more information.

    Enjoy!

  9. ES6 In Depth: Generators

    ES6 In Depth is a series on new features being added to the JavaScript programming language in the 6th Edition of the ECMAScript standard, ES6 for short.

    I’m excited about today’s post. Today, we’re going to discuss the most magical feature in ES6.

    What do I mean by “magical”? For starters, this feature is so different from things that already existed in JS that it may seem completely arcane at first. In a sense, it turns the normal behavior of the language inside out! If that’s not magic, I don’t know what is.

    Not only that: this feature’s power to simplify code and straighten out “callback hell” borders on the supernatural.

    Am I laying it on a bit thick? Let’s dive in and you can judge for yourself.

    Introducing ES6 generators

    What are generators?

    Let’s start by looking at one.

    function* quips(name) {
      yield "hello " + name + "!";
      yield "i hope you are enjoying the blog posts";
      if (name.startsWith("X")) {
        yield "it's cool how your name starts with X, " + name;
      }
      yield "see you later!";
    }
    

    This is some code for a talking cat, possibly the most important kind of application on the Internet today. (Go ahead, click the link, play with the cat. When you’re thoroughly confused, come back here for the explanation.)

    It looks sort of like a function, right? This is called a generator-function and it has a lot in common with functions. But you can see two differences right away:

    • Regular functions start with function. Generator-functions start with function*.

    • Inside a generator-function, yield is a keyword, with syntax rather like return. The difference is that while a function (even a generator-function) can only return once, a generator-function can yield any number of times. The yield expression suspends execution of the generator so it can be resumed again later.

    So that’s it, that’s the big difference between regular functions and generator-functions. Regular functions can’t pause themselves. Generator-functions can.

    What generators do

    What happens when you call the quips() generator-function?

    > var iter = quips("jorendorff");
      [object Generator]
    > iter.next()
      { value: "hello jorendorff!", done: false }
    > iter.next()
      { value: "i hope you are enjoying the blog posts", done: false }
    > iter.next()
      { value: "see you later!", done: false }
    > iter.next()
      { value: undefined, done: true }
    

    You’re probably very used to ordinary functions and how they behave. When you call them, they start running right away, and they run until they either return or throw. All this is second nature to any JS programmer.

    Calling a generator looks just the same: quips("jorendorff"). But when you call a generator, it doesn’t start running yet. Instead, it returns a paused Generator object (called iter in the example above). You can think of this Generator object as a function call, frozen in time. Specifically, it’s frozen right at the top of the generator-function, just before running its first line of code.

    Each time you call the Generator object’s .next() method, the function call thaws itself out and runs until it reaches the next yield expression.

    That’s why each time we called iter.next() above, we got a different string value. Those are the values produced by the yield expressions in the body of quips().

    On the last iter.next() call, we finally reached the end of the generator-function, so the .done field of the result is true. Reaching the end of a function is just like returning undefined, and that’s why the .value field of the result is undefined.

    Now might be a good time to go back to the talking cat demo page and really play around with the code. Try putting a yield inside a loop. What happens?

    In technical terms, each time a generator yields, its stack frame—the local variables, arguments, temporary values, and the current position of execution within the generator body—is removed from the stack. However, the Generator object keeps a reference to (or copy of) this stack frame, so that a later .next() call can reactivate it and continue execution.

    It’s worth pointing out that generators are not threads. In languages with threads, multiple pieces of code can run at the same time, usually leading to race conditions, nondeterminism, and sweet sweet performance. Generators are not like that at all. When a generator runs, it runs in the same thread as the caller. The order of execution is sequential and deterministic, and never concurrent. Unlike system threads, a generator is only ever suspended at points marked by yield in its body.

    All right. We know what generators are. We’ve seen a generator run, pause itself, then resume execution. Now for the big question. How could this weird ability possibly be useful?

    Generators are iterators

    Last week, we saw that ES6 iterators are not just a single built-in class. They’re an extension point of the language. You can create your own iterators just by implementing two methods: [Symbol.iterator]() and .next().

    But implementing an interface is always at least a little work. Let’s see what an iterator implementation looks like in practice. As an example, let’s make a simple range iterator that simply counts up from one number to another, like an old-fashioned C for (;;) loop.

    // This should "ding" three times
    for (var value of range(0, 3)) {
      alert("Ding! at floor #" + value);
    }
    

    Here’s one solution, using an ES6 class. (If the class syntax is not completely clear, don’t worry—we’ll cover it in a future blog post.)

    class RangeIterator {
      constructor(start, stop) {
        this.value = start;
        this.stop = stop;
      }
    
      [Symbol.iterator]() { return this; }
    
      next() {
        var value = this.value;
        if (value < this.stop) {
          this.value++;
          return {done: false, value: value};
        } else {
          return {done: true, value: undefined};
        }
      }
    }
    
    // Return a new iterator that counts up from 'start' to 'stop'.
    function range(start, stop) {
      return new RangeIterator(start, stop);
    }
    

    See this code in action.

    This is what implementing an iterator is like in Java or Swift. It’s not so bad. But it’s not exactly trivial either. Are there any bugs in this code? It’s not easy to say. It looks nothing like the original for (;;) loop we are trying to emulate here: the iterator protocol forces us to dismantle the loop.

    At this point you might be feeling a little lukewarm toward iterators. They may be great to use, but they seem hard to implement.

    It probably wouldn’t occur to you to suggest that we introduce a wild, mindbending new control flow structure to the JS language just to make iterators easier to build. But since we do have generators, can we use them here? Let’s try it:

    function* range(start, stop) {
      for (var i = start; i < stop; i++)
        yield i;
    }
    

    See this code in action.

    The above 4-line generator is a drop-in replacement for the previous 23-line implementation of range(), including the entire RangeIterator class. This is possible because generators are iterators. All generators have a built-in implementation of .next() and [Symbol.iterator](). You just write the looping behavior.

    Implementing iterators without generators is like being forced to write a long email entirely in the passive voice. When simply saying what you mean is not an option, what you end up saying instead can become quite convoluted. RangeIterator is long and weird because it has to describe the functionality of a loop without using loop syntax. Generators are the answer.

    How else can we use the ability of generators to act as iterators?

    • Making any object iterable. Just write a generator-function that traverses this, yielding each value as it goes. Then install that generator-function as the [Symbol.iterator] method of the object.

    • Simplifying array-building functions. Suppose you have a function that returns an array of results each time it’s called, like this one:

      // Divide the one-dimensional array 'icons'
      // into arrays of length 'rowLength'.
      function splitIntoRows(icons, rowLength) {
        var rows = [];
        for (var i = 0; i < icons.length; i += rowLength) {
          rows.push(icons.slice(i, i + rowLength));
        }
        return rows;
      }
      

      Generators make this kind of code a bit shorter:

      function* splitIntoRows(icons, rowLength) {
        for (var i = 0; i < icons.length; i += rowLength) {
          yield icons.slice(i, i + rowLength);
        }
      }
      

      The only difference in behavior is that instead of computing all the results at once and returning an array of them, this returns an iterator, and the results are computed one by one, on demand.

    • Results of unusual size. You can’t build an infinite array. But you can return a generator that generates an endless sequence, and each caller can draw from it however many values they need.

    • Refactoring complex loops. Do you have a huge ugly function? Would you like to break it into two simpler parts? Generators are a new knife to add to your refactoring toolkit. When you’re facing a complicated loop, you can factor out the part of the code that produces data, turning it into a separate generator-function. Then change the loop to say for (var data of myNewGenerator(args)).

    • Tools for working with iterables. ES6 does not provide an extensive library for filtering, mapping, and generally hacking on arbitrary iterable data sets. But generators are great for building the tools you need with just a few lines of code.

      For example, suppose you need an equivalent of Array.prototype.filter that works on DOM NodeLists, not just Arrays. Piece of cake:

      function* filter(test, iterable) {
        for (var item of iterable) {
          if (test(item))
            yield item;
        }
      }
      

    So are generators useful? Sure. They are an astonshingly easy way to implement custom iterators, and iterators are the new standard for data and loops throughout ES6.

    But that’s not all generators can do. It may not even turn out to be the most important thing they do.

    Generators and asynchronous code

    Here is some JS code I wrote a while back.

              };
            })
          });
        });
      });
    });
    

    Maybe you’ve seen something like this in your own code. Asynchronous APIs typically require a callback, which means writing an extra anonymous function every time you do something. So if you have a bit of code that does three things, rather than three lines of code, you’re looking at three indentation levels of code.

    Here is some more JS code I’ve written:

    }).on('close', function () {
      done(undefined, undefined);
    }).on('error', function (error) {
      done(error);
    });
    

    Asynchronous APIs have error-handling conventions rather than exceptions. Different APIs have different conventions. In most of them, errors are silently dropped by default. In some of them, even ordinary successful completion is dropped by default.

    Until now, these problems have simply been the price we pay for asynchronous programming. We have come to accept that asynchronous code just doesn’t look as nice and simple as the corresponding synchronous code.

    Generators offer new hope that it doesn’t have to be this way.

    Q.async() is an experimental attempt at using generators with promises to produce async code that resembles the corresponding synchronous code. For example:

    // Synchronous code to make some noise.
    function makeNoise() {
      shake();
      rattle();
      roll();
    }
    
    // Asynchronous code to make some noise.
    // Returns a Promise object that becomes resolved
    // when we're done making noise.
    function makeNoise_async() {
      return Q.async(function* () {
        yield shake_async();
        yield rattle_async();
        yield roll_async();
      });
    }
    

    The main difference is that the asynchronous version must add the yield keyword each place where it calls an asynchronous function.

    Adding a wrinkle like an if statement or a try/catch block in the Q.async version is exactly like adding it to the plain synchronous version. Compared to other ways of writing async code, this feels a lot less like learning a whole new language.

    If you’ve gotten this far, you might enjoy James Long’s very detailed post on this topic.

    So generators are pointing the way to a new asynchronous programming model that seems better suited to human brains. This work is ongoing. Among other things, better syntax might help. A proposal for async functions, building on both promises and generators, and taking inspiration from similar features in C#, is on the table for ES7.

    When can I use these crazy things?

    On the server, you can use ES6 generators today in io.js (and in Node if you use the --harmony command-line option).

    In the browser, only Firefox 27+ and Chrome 39+ support ES6 generators so far. To use generators on the web today, you’ll need to use Babel or Traceur to translate your ES6 code to Web-friendly ES5.

    A few shout-outs to deserving parties: Generators were first implemented in JS by Brendan Eich; his design closely followed Python generators which were inspired by Icon. They shipped in Firefox 2.0 back in 2006. The road to standardization was bumpy, and the syntax and behavior changed a bit along the way. ES6 generators were implemented in both Firefox and Chrome by compiler hacker Andy Wingo. This work was sponsored by Bloomberg.

    yield;

    There is more to say about generators. We didn’t cover the .throw() and .return() methods, the optional argument to .next(), or the yield* expression syntax. But I think this post is long and bewildering enough for now. Like generators themselves, we should pause, and take up the rest another time.

    But next week, let’s change gears a little. We’ve tackled two deep topics in a row here. Wouldn’t it be great to talk about an ES6 feature that won’t change your life? Something simple and obviously useful? Something that will make you smile? ES6 has a few of those too.

    Coming up: a feature that will plug right in to the kind of code you write every day. Please join us next week for a look at ES6 template strings in depth.

  10. How TV Functionality Leverages Web Technology

    The convergence of Internet-based IPTV, Video-on-Demand (VoD) and traditional broadcasting is happening now. As more and more web technology comes to television, the gap between web apps and native apps is rapidly narrowing.

    Firefox OS now supports the TV Manager API, a baseline of the W3C TV Control API (the editor’s draft driven by the TV Control API Community Group), which allows web-based applications to acquire information such as the Electronic Program Guide (or EPG) from service providers, and also to manage native TV hardware such as tuners and remotes. Firefox OS also relies on multiple API specifications to fully support TV functionality on a web platform. Some APIs are still on the road to becoming standards. Here is an overview of some common TV functions which can be implemented today via these Web APIs.

    FxOS_TV

    Tuner, channel, and EPG management

    One of the primary goals of the TV Control API is to enable standard use cases, such as channel switching and other activities generally available and expected in conventional remote controls. The API exposes specific tuner, channel, and EPG information to the web app and also allows indirect interactions with the tuner modules. Some applications, like virtual remote control, are easy to enable with this API. And the web content has the flexibility to manipulate multiple tuners if resource-permitted. In addition, event-driven notifications about channel scanning status and EPG updates provide a dynamic way to access broadcasting information.

    The following example shows how to get the available tuners and set the current playing source via the API.

        // Retrieve all the available tuners.
        navigator.tv.getTuners().then(function(tuners) {
          // Just use the first tuner.
          var tuner = tuners[0];
    
          // Set the 'oncurrentsourcechanged' event handler.
          tuner.oncurrentsourcechanged = function(event) {
            // The current source has changed.
          };
    
          // Get the supported source types for the tuner. 
          var sourceTypes = tuner.getSupportedSourceTypes();
    
          // Just use the first source.
          tuner.setCurrentSource(sourceTypes[0]).then(function() {
            // Succeeded to set the source.
          }, function(error) {
            // Failed to set the source.
          });
        }, function(error) {
          // Failed to get tuners.
        });
    

    Streaming

    When it comes to TV streaming, multiple web specifications work together. The Media Capture and Streams API enables access to multimedia streams from local devices, and it defines a MediaStream interface to carry video/audio tracks and other stream-relevant attributes. The current streaming data for each tuner can be wrapped in a MediaStream instance and retrieved via the TV Control API. Then the web content can start playing the stream by assigning it to HTML5 <video> elements. Here’s an example:

        // Retrieve all the available TV tuners and then play
        // the stream for the first tuner.
        navigator.tv.getTuners().then(function(tuners) {
          // Assuming a video element is already accessible to
          // variable |video|, just assign the stream to it.
          video.srcObject = tuners[0].stream;
        });
    

    The Media Capture and Streams API and the HTML5 <video> element provide attributes and methods to help manage streaming contents. Combining the APIs and HTML5 elements makes the development of some advanced TV streaming scenarios, such as concurrent display for multiple streams (i.e., Picture-in-Picture), easier to accomplish and more flexible.

    Track management

    While playing video streams, sometimes the media content provides multiple audio channels and even includes subtitles. For instance, a film or a sports show may be broadcast with multiple supported languages available for the viewer to select. Thus, there are two lists of VideoTrack and AudioTrack objects in the HTML5 <video> element to help the web content utilize available video and audio tracks respectively. Meanwhile, the Media Capture and Streams API also provides certain methods to dynamically manage associated media tracks. With this flexibility, web content is able to play a video stream that’s originated from another connected device, such as a camera.

    The HTML5 <video> element has a list of TextTrack instances. These tracks can be associated with a specific video tag to represent different instances, such as subtitles, captions, and metadata. In addition, multiple TextTrackCue objects containing time-sensitive data can be affiliated with them, and used to control timing of the display for subtitles and captions.

    Recording

    The MediaStream Recording API provides a MediaRecorder interface to fulfill recording requirements over the MediaStream. It lets the web content select the appropriate supported encoding format for the stream, and also enables the recorded media to be accessed either as a whole blob or in smaller buffers.

    In cooperation with the Task Scheduler API and Service Workers, you can even add DVR-style scheduling functionality to your web app or web-driven device. On the other hand, the EPG data retrieved via TV Control API may also help the application record specific TV programs.

    Emergency alert

    Sometimes a public alert may be sent out via TV broadcasting or other communication systems when an emergency or natural disaster occurs such an earthquake, tsunami, or hurricane. A corresponding event-triggering mechanism included with the TV Control API can be used to help a web application manage an alert.

       // Assuming variable |currentSource| is associated with
        // the playing TV signal.
        currentSource.onemergencyalerted = function (event) {
          var type = event.type; // i.e. “Earthquake”.
          var severityLevel = event.severityLevel;
          var description = event.description;
          // Display the emergency information.
          // (More attributes could be available.)
        };
    

    Final thoughts

    TV broadcast mechanisms and applications are on a fast track to evolve rapidly, as is the web technology. Since many of the web specifications and APIs mentioned are still in the standardization progress, more functionality or further improvements might be added to make television experience more webby. As always, you can contribute to the evolution of these Web APIs by following along on relevant standards mailing lists and filing bugs when you find them.