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

ES6 Features 7: Destructuring

This week's ES6 Features post is going to be on some rather new syntactic sugar, called destructuring. Please be aware that neither Node.js or io.js support this syntax, and the only browser to have a decent level of support is Firefox.

Destructuring allows you to take an array's contents and assign it's values to multiple variables at once. Whereas before you would probably do this:

> var locations = [ "Paris", "New York" ];
undefined
> var first = locations[0], second = locations[1];
undefined
> first
'Paris'
> second
'New York'

You can now do this:

> var locations = [ "Paris", "New York" ];
undefined
> var [ first, second ] = locations;
undefined
> first
'Paris'
> second
'New York'

Destructuring also supports the rest operator (...), so you can assign the rest of the values in an array to a variable too:

> var fruits = [ "orange", "apple", "banana", "kiwi", "avocado" ];
undefined
> one
"orange"
> two
"apple"
> var [one,two,three,...rest] = fruits
undefined
> three
"banana"
> rest
["kiwi", "avocado"]

Destructuring in Ecmascript 7 can also be used on objects too, allowing you to set multiple variables equal to the value of a property in any object:

> var item = { "name": "compass", "quantity": 1, "value": 250 };
undefined
> var {name, quantity, value} = item;
undefined
> name
'compass'
> quantity
1
> value
250

In order for object destructuring to work, the variable names you are declaring must have the same name as the property of the object that you want to destructure.

Destructuring also works in a function context too! If you specify an object as the only parameter to a function, you can destructure it's contents into multiple variables. This looks like a good way to simplify complex functions that have a lot of arguments.

> function test({ x: x, y: y }) { return `(${x}, ${y})`; }
undefined
> test({ x: 250, y: 50 });
'(250, 50)'

That concludes this ES6: Features post on destructuring. To summarise, destructuring is a way simplify the assigning of multiple variables at once to the values in an array. The rest operator can be used to gather up the rest of the elements left in an array. Objects can be destructured too, by both variable assignments and the arguments of a function.

Destructuring isn't generally available yet though. Just before I end this post, here's a table of who supports it:

Environment Support?
Internet Explorer 11 No
Microsoft Edge No
Chrome 44 No
Firefox 39 Yes
Opera Beta 31 No
io.js v2.3.1 No
Node.js 0.12 No
Babel Yes

Ecmascript 6 Features 6: const

We have reached the 6th post in the ES6 features series! This series of posts has to be my longest yet. This week's post is a short one about a new keyword that has been added in ES6: const. If you know any C♯, then this keywrod may already be familiar to you. It's purpose is to define a variable (called a constant) that cannot be changed or redefined.

As with normal variables, constants are function scope. When defined outside a function, they become part of the global scope. Example:

> const max_value = 64;
undefined
> max_value
64

Since constants can't be changed, setting them to a different value has no effect (but doesn't throw an error - wait, what?):

> max_value = 128;
128
> max_value
64

Redefining a constant throws an error:

> max_value
64
> const max_value = 128
TypeError: Identifier 'max_value' has already been declared

And they can't be deleted either:

> delete max_value
false
> max_value
64

It seems that you can't define a constant as a property of an object though (makes sense - then it would be a property and not a variable I suppose, though having the the syntax work like that would make things so much more readable). For that, you'll have to use Object.defineProperty() with the writable: false option.

> settings = {};
{}
> const settings.seed = 47264;
SyntaxError: Unexpected token .

Other than that, they behave like normal variables. For example you can convert a constant number to a string as normal:

> max_value.toString(2)
'1000000'
>

Though curiously, mutators on constants work correctly and change the original variable (perhaps this is a bug in io.js?):

> const y = [1,2,3]
undefined
> y
[ 1, 2, 3 ]
> y.reverse()
[ 3, 2, 1 ]
> y
[ 3, 2, 1 ]

That concludes this experimentation-heavy post on constants. To summarise:

  • Constants are variables that can't be changed (except by mutator methods)
  • You can't define a constant as the property of an object (though I wish you could)
  • Reassigning a constant has no effect (but doesn't throw an error)
  • Redefining a constant causes an error to be thrown
  • Deleting a constant has no effect and returns false

Hopefully this was useful to someone. Next time, I might take a look at some of the new additions to the Math object while I try and get my head around destructuring.

Ecmascript 6 Features 5: Spread and Rest

Unfortunately I have been rather busy this week so far, but I managed to find time to write up another post for you. This week's ES6 features are spread and rest. They go hand in hand, so I thought I would cover them both at once.

Spread

The spread operator lets you spread an array's contents out as the arguments when calling a function. It works like Function.apply, but it looks much neater :)

function multiply(a, b, c)
{
    return a * b * c;
}

var numbers = [4, 7, 2];

console.log(multiply(...numbers)); // 56

Before you might have had to do something like this:

console.log(multiply.apply(this, numbers)); // 56

Personally, I think that the new addition make a lot more sense than the old apply function, although you will still need to use Function.apply() if you want to customise the execution context of the function.

Rest

The spread operator, as you might expect, spread an array of things out to different arguments. But what if you wanted to bunch them back up again? ES6 can handle that too, through the rest operator. The rest operator allows you to bunch the rest of the arguments passed to a function into an array:

function log_adv(who, ...what)
{
    "use strict";
    var str = `[ ${new Date().toLocaleString()} ] [ ${who} ] `;
    for(let thing of what)
    {
        str += JSON.stringify(thing) + " ";
    }
    console.log(str);
}

var x = Math.random(),
    y = Math.random() * 2;

// Logs something like:
// [ 08/07/2015, 11:51:14 ] [ program ] "x is" 0.051463941344991326 "y is" 1.5026674889959395 
log_adv("program", "x is", x, "y is", y);

So there you have it! Two more new features of ES6. Next time I might look into arrow functions. Also, this Friday I will be posting about a PHP hashtag-to-title converter that I wrote for a project that I am working on for someone I know.

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.

Find treasure with sound

The Audio Treasure hunter

Hello again!

Today I have a small minigame to show you. There is some treasure hidden in your browser window, so naturally it is your job to find it. Make sure your sound is turned on and then press <space> to hear where the treasure is. Then click somewhere on the page and listen to the sound that each location makes. Try and match the sound you hear from clicking with the sound you hear when pressing space.

Link: Audio Treasure Hunter

The sound that is made consists of two tones. The first one is tied to the horizontal position of your cursor. The left side has a low sound, and the right side has a high sound. The second tone is tied to the vertical position of your cursor. As you would expect, the bottom of your screen has a low sound and the top, a high sound.

If your are finding it too easy or hard, your can cycle through the different modes by pressing <m>. The harder modes decrease the time between the two tones and reduce the size of the treasure.

I can do it in ~3-4 clicks if I try hard enough. What is your best?

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.

Page Position Bookmarklet

Hello!

Today I have a trio of related javascript bookmarklets for your browser. They allow you to save / restore / clear your position on any web page. It persists across sessions / reboots / page navigations too. It does this by saving the position in your local storage for each path at each domain. This means that you can save your place on multiple pages (even on the same domain!) and they will all be saved until you use the clear bookmark on each page you saved it on or clear your local storage.

I will probably come back and write an upgraded version of these later, but for now they only save one position per page. It would be neat if the saved positions acted like a stack, so you could save multiple positions on each page.

Link: Page Position System

Art by Mythdael