Starbeamrainbowlabs

Stardust
Blog


Archive


Mailing List Articles Atom Feed Comments Atom Feed Twitter Reddit Facebook

Tag Cloud

3d 3d printing account algorithms android announcement architecture archives arduino artificial intelligence artix assembly async audio automation backups bash batch blender blog bookmarklet booting bug hunting c sharp c++ challenge chrome os cluster code codepen coding conundrums coding conundrums evolved command line compilers compiling compression conference conferences containerisation css dailyprogrammer data analysis debugging defining ai demystification distributed computing dns docker documentation downtime electronics email embedded systems encryption es6 features ethics event experiment external first impressions freeside future game github github gist gitlab graphics guide hardware hardware meetup holiday holidays html html5 html5 canvas infrastructure interfaces internet interoperability io.js jabber jam javascript js bin labs latex learning library linux lora low level lua maintenance manjaro minetest network networking nibriboard node.js open source operating systems optimisation outreach own your code pepperminty wiki performance phd photos php pixelbot portable privacy problem solving programming problems project projects prolog protocol protocols pseudo 3d python reddit redis reference release releases rendering research resource review rust searching secrets security series list server software sorting source code control statistics storage svg systemquery talks technical terminal textures thoughts three thing game three.js tool tutorial twitter ubuntu university update updates upgrade version control virtual reality virtualisation visual web website windows windows 10 worldeditadditions xmpp xslt

Ecmascript Features 4: Let and use strict

Sorry there wasn't a post in this series last week - I wasn't feeling so good. I am better now though.

This week's ES6 post will cover the let keyword. Normally in Javascript variables are declared with var and are function level. This means that once you declare a variable in a function (even if it is inside a nested block like a loop, it is available until that function's scope is removed from memory (note that a function's scope can stick around even after it completes in certain asynchronous cases).

The let keyword offers more control over the lifetime of your variables by reducing the scope of variables declared to block level. This means that once a block is removed from memory (again, this is usually when it completes - but there are certain asynchronous exceptions) the variable is destroyed.

For example, the following would work:

var foo = true;

if(foo) {
    var bar = "oranges";
}
console.log(bar);

But this wouldn't work:


var foo = true;

if(foo) {
    let bar = "oranges";
}
console.log(bar);

As of the time of writing, there are actually 2 problems with the second example. The first problem, as you have probably guessed, is that the let keyword is used inside the if block to declare a variable called bar, but the new variable is referenced outside of the if block's scope - causing a problem.

The second problem is to do with the second half of the title of this post. At the current time the above will also cause the following error in chrome based consoles:

Uncaught SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

What is going on here? What is strict mode?

Strict mode has actually been floating around the internet for a while now (you might have heard of it) and it prevents you from doing the following by throwing an error (normally these just silently fail):

  • accidentally creating new global variables by mistyping a variable name
  • changing the type of something once created
  • assigning to a getter only property
  • adding to a fixed object
  • deleting undeletable properties
  • duplicating argument names in function definitions
  • using the with keyword
  • puts eval()ed code into it's own sandbox
  • deleting variables
  • and a whole bunch of other stuff

It's a long list, right?! Either way, turning on strict mode will help you to both catch bugs quicker and write better code to begin with. To turn it on, just put the following at the beginning of your script or function:

"use strict";

Since this is only a string, it makes it backwards compatible with older browsers, too!

That concludes this post. Next time, I will probably be taking a look at the rest and spread operators.

ES6 Features 3.5: More Generators

While following the rest of David Walsh's generator tutorial (link here!), I discovered a really neat trick that combines both Promises with generators. Basically you can write a promise based function and then yield it's return value. Then if you write an engine function that runs a generator to completion that passes in the yield value via Iterator.next, you can use an asynchronous function as if it were synchronous:

function do_work()
{
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(Math.random());
        }, 1000);
    });
}

function do_hard_work()
{
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(Math.random());
        }, 3000);
    });
}

function *async_test()
{
    var number1 = yield do_work();
    console.log(`Number 1: ${number1}`);
    var number2 = yield do_hard_work();
    console.log(`Number 2: ${number2}`);

    console.log(`Result: ${number1 + number2}`);
}

In the above example, I have 2 promise-based asynchronous functions called do_work() and do_hard_work(). In reality you would have some functions that were actually useful (e.g. that performed a GET request and returned the result, for example), but this is just a demonstration. The generator yields the return value of the two async functions.

A function something like this can be used to run the generator:

// run (async) a generator to completion
// Note: simplified approach: no error handling here
function run_generator(g) {
    var it = g(), ret;

    // asynchronously iterate over generator
    (function iterate(val){
        ret = it.next( val );

        if (!ret.done) {
            // poor man's "is it a promise?" test
            if ("then" in ret.value) {
                // wait on the promise
                ret.value.then( iterate );
            }
            // immediate value: just send right back in
            else {
                // avoid synchronous recursion
                setTimeout( function(){
                    iterate( ret.value );
                }, 0 );
            }
        }
    })();
}

(credit: David Walsh's Going Async With ES6 Generators)

If you ran the above generator you might get something like this:

$iojs async-generators.js
Number 1: 0.07386422459967434
Number 2: 0.7089381434489042
Result: 0.7828023680485785

How cool is that?! This will simplify complex async javascript so much. I think I am going to put this technique to work in my next rewrite of Bloworm's web based client...

Suggestions for next week's ES6 feature 'tutorial' are welcome in the comments.

EcmaScript 6 Features 3: Generators!

Sorry this didn't come out last week - there is a lot to generators, and I wanted to cover as much as I could. This post took quite a while to put together! Anyway, lets get into the subject of this post: Generators! Generators are a special type of function that return multiple values through the yield keyword (we will get into this in a minute). They can maintain an internal state and return as many values as you like (even an infinite number!). Here is a very simple generator:

function *first_test()
{
    yield "Hello!";
    yield "I am a generator!";
    yield "This is the last thing I will yield.";
}

(gist: todo) Note the asterisk (*) at the beginning of the function name. This is the bit that tells the javascript runtime that the function we are defining is a generator, and not an ordinary function. The next question is how do we actually call the generator? This is actually quite simple:

var test = first_test();

console.log(test.next().value);
console.log(test.next().value);
console.log(test.next().value);

Firstly, we need to create an instance of the generator. This is done by just calling the function normally and storing the result. The technical name for the result we store here is an iterator. To actually extract values from our new generator iterator, we call the next() function on the instance that we created. This returns an object, which contains 2 things:

  1. The next value that the generator yields
  2. Whether the generator is finished

The above isn't very elegant - we can do much better than:

var test = first_test(),
    next = test.next();

do {
    console.log(next.value);
    next = test.next();
} while(!next.done);

The above stores the last yielded result in a variable, outputs the value to the console, and grabs the next result until the generator has finished. Note that if you try to get the next value when the generator has finished, the value will be undefined.

But wait! There is an even better solution to this: a for..of loop.

for(var str of first_test())
{
    console.log(str);
}

The above utilises special for loop construct to create an instance of our generator (remember this is called in iterator) and loop over it's return values until it is finished, all in one! Neat or what?!

This is cool, but generators get better. You could use one to generate IDs:

function *get_id(start)
{
    var current = start;
    while(true)
    {
        yield start.toString(16);

        start++;
    }
}

var id_generator = get_id(100);

for(var i = 0; i < 10; i++)
{
    console.log(id_generator.next());
}

In the above example I am taking advantage of the fact that you can pass parameters to a generator upon creation like any normal function to set the first ID. This Will produce the following:

next id: 194
next id: 195
next id: 196
next id: 197
next id: 198
next id: 199
next id: 19a
next id: 19b
next id: 19c
next id: 19d

Also, this id generator will never complete, so we will always have a source of unique IDs for our program to use.

You can also pass in a single argument when you call next() too. In this way we can create a fancy counter:

"use strict";

function *counter(base)
{
    var number = base;
    while(true)
    {
        number += yield number;
    }
}

var generator = counter(100);

for(var i = 0; i < 10; i++)
{
    let next = generator.next(Math.floor(Math.random() * 10))
    console.log(next.value);
}

The above generator keeps a counter variable and increments it by the amount that is passed in when the next() function is called. In this case, we are passing in a random number between 0 and 10. It might output something like this:

100
101
104
112
114
114
122
125
134
134

This could be useful for maintaining an internal state while serving HTTP requests with Node / io.js perhaps? The possibilities are endless...!

This post was put together with the help of this tutorial: ES6 Generators - davidwalsh.name. This is a really good and thorough tutorial on ES6 generators.

By the looks of the tutorial I followed (link above!), we have only just scratched the surface of ES6 generators. I might have to write another blog about them...

The code I wrote while learning about generators and putting this post together can be found here: https://gist.github.com/sbrl/98cd9bde4d06da5ad5ec

EcmaScript 6 Features 2: Binary and Octal Literals

This week's ES6 feature is binary and octal literals. Generators will be coming next week!

In JS you can specify a number in hex like so:

> 0x3ef
1007

If you wanted to specify a number in octal or binary, previously you would have to use parseInt:

> parseInt("012362", 8)
5362
> parseInt("110010100", 2)
404

If your environment supports it, you can use the new literals.

> 0b110010100
404
> 0o767
503

For octals, you simply prefix the number with 0o (zero then 'o'). For binary, you prefix it with 0b (zero then 'b'). The new octal literal could be used to specify file permissions more easily, I suppose.

The next one in this series will be more interesting :)

EcmaScript 6 Features 1: String Interpolations

Welcome to a new series of short posts on the new features of EcmaScript 6. EcmaScript is the technical name for Javascript - and currently I have been writing in version 5. Since version 6 is gaining support quickly, I think it is time that I learnt about all the new features.

This series will be conducted using the latest version of io.js. I will not be investigating features that don't have support in io.js.

First up: String Interpolation. This is just a fancy name for inserting the contents of variables into strings. PHP has this already:

<?php
$total = 456;
echo("Total: $total");
?>

Results in:

Total: 456

Now this is coming to Javascript. If you use the %60 (back-tick) character to open and close your strings, you can insert the values of things into a string with ${}:

var name = "Orange";

console.log(`Name: ${name}`);

Outputs:

Name: Orange

You can also use this to pull the values from an object, too. I have recorded a demo with asciinema:

I have also written a test for your browser:

Next up will probably be generators (which are really cool by the way). These posts will also be the first to stick to a (semi) formal schedule: A new one will come out every Tuesday.

Art by Mythdael