Sunday 26 November 2017

AsyncFunction and GeneratorFunction

Since ES6 not all JavaScript functions have the same behaviour. Depending on whether they have been created using the function statement, via the method definition sugar inside a class or as an arrow function they will spot different features. You can read about it here, but basically, arrow functions can not be called as constructors and use a static, lexical this; methods (created via method definitions) can not be called as constructors; super can only be used inside methods...

Anyway, I thought that in spite of having different features all function objects where directly instances of Function but I've found out that this is not the case, and we have 2 additional function types (both inheriting from Function): AsyncFunction and GeneratorFunction. When you define and async function, either directly as a "normal" function, via the method syntax or as an arrow function, you are creating an instance of an AsyncFunction, and when you define an async method, as a "normal" function or via method syntax (you can not use arrows to create generators), you are creating an instance of a GeneratorFunction. You can run this code to see that I'm not lying.

class Person{
 constructor(){
 }
 
 sayHi(){
 }
}

function sayBye(){
}

let saySomething = (msg) => console.log("saying: " + msg);

function* myGeneratorFunc(){
 yield "hi";
}

async function myAsyncFunc(){
}

console.log(Person.constructor.name);

console.log((new Person()).sayHi.constructor.name);

console.log(sayBye.constructor.name);

console.log(saySomething.constructor.name);

console.log("-----------------------");

console.log(myGeneratorFunc.constructor.name);
console.log(myGeneratorFunc.constructor.constructor.name);

console.log(myAsyncFunc.constructor.name);
console.log(myAsyncFunc.constructor.constructor.name);

console.log(myGeneratorFunc.constructor.constructor === Function);
console.log(myAsyncFunc.constructor.constructor === Function);

/*
Function
Function
Function
Function
-----------------------
GeneratorFunction
Function
AsyncFunction
Function
true
true
*/

And as I said above both function types inherit from Function (xxx.constructor.constructor === Function)

Friday 24 November 2017

Multiple Iteration

I've come across with a pretty interesting difference in the behaviour of JavaScript generator functions/methods and that of C# iterator methods. Though the names are different (a very wrong decision on Microsoft side, using enumerable/enumerator/iterator rather than iterable/iterator/generator, that is what most other languages do), in both cases we talk about those magic funtions/methods that contain some yield statement and that the compiler will translate into a state machine.

In Javascript a generator function returns a generator object, an object that is both an iterable and an iterator. When you ask the generator object for an iterator (via [Symbol.iterator]) it returns itself. Because of this, trying to iterate multiple times on the same generator object will result in that the iteration will only take place the first time, for the ensuing ones, as the iterator is already at the end, no iteration will happen. I mean:

function* getCities(){
 yield "Toulouse";
 yield "Xixon";
 yield "Berlin";
}

let citiesGenOb = getCities();

let citiesIterator1 = citiesGenOb[Symbol.iterator]();

console.log(citiesGenOb === citiesIterator1 ? "same object" : "different object"); //same object

console.log("- first iteration:");
for (let city of citiesGenOb){
 console.log(city);
}

console.log("-------------");

console.log("- second iteration:");
//no iteration is done, citiesGenOb[Symbol.iterator] is returning the same object
//that was already iterated to the end in the previous loop
//very interesting, this behaviour is different from C#, here the generator object (this is both iterable and iterator) is returning itself, rather than a copy
for (let city of citiesGenOb){
 console.log(city);
}

let citiesIterator2 = citiesGenOb[Symbol.iterator]();
console.log(citiesGenOb === citiesIterator2 ? "same object" : "different object"); //same object


/*
same object
- first iteration:
Toulouse
Xixon
Berlin
-------------
- second iteration:
same object
*/

The generator and the iterator (returned by the implicit call to citiesGenOb[Symbol.iterator] done by the "for...of" loop) are the same object, so once we have iterated the first time, the iterator is at the end and trying to iterate it again will iterate nothing.

In C#, an iterator method returns an object of a class created by the compiler and that implements both the IEnumerable and IEnumerator interface. Based on the Javascript behaviour one could expect that invoking the GetEnumerator method of an instance of this class would return the same instance, but the C# compiler is doing different, let's see some code:

private static IEnumerable<string> GetCountries()
{
 yield return "France";
 yield return "Belgium";
 yield return "Portugal";
}

IEnumerable<string> countries = GetCountries();
var enumerator1 = countries.GetEnumerator();

Console.WriteLine((enumerator1 == countries) ? "Same reference" : "Different reference"); //Different

//the Iterator method is returning an IEnumerable/IEnumerator object, but the thing is that calling to GetEnumerator returns a new instance, rather than the object itself
//Because of that the 2 loops do a whole iteration, and enumerator1 and 2 are different objects.
Console.WriteLine("- first iteration:");
foreach(string country in countries)
 Console.WriteLine(country);

Console.WriteLine("- second iteration:");
foreach(string country in countries)
 Console.WriteLine(country);

enumerator1 = countries.GetEnumerator();

Console.WriteLine((enumerator1 == countries) ? "Same reference" : "Different reference"); //Different


var enumerator2 = countries.GetEnumerator();
Console.WriteLine((enumerator1 == enumerator2) ? "Same reference" : "Different reference");

/*
Same reference
- first iteration:
France
Belgium
Portugal
- second iteration:
France
Belgium
Portugal
Different reference
Different reference
*/  

What seems to happen is that when you call GetEnumerator in your IEnumerable/IEnumerator object, if the object has not been iterated yet, you obtain the same object (that's the first case, where I get "Same reference"), but if it has alredy been enumerated, you get a new instance!. This way you can iterate multiple times the same IEnumerable/IEnumerator object (as you can see, both "first iteration" and "second iteration" do a complete iteration).

Decompiling the IEnumerable/IEnumerator class created by the compiler (instances of which are created by the Iterator method) we can see:

Notice that in Javascript if we have function that expects an iterable that it will iterate several times, rather than passing it a generator object, we should pass the generator function itself, so we can invoke it each time we want to perform the iteration.

Wednesday 15 November 2017

Javascript Default Parameters

As default parameters, Object.assign and destructuring assignment have made it into the language the way to work with optional parameters and default values has changed. I've been writing some examples to get used to the current options and I'll be explaining it here:

Let's say we have a function (or method, but not a constructor) expecting a few parameters. The old-school way to deal with default values was this:

function formatString(st, pre, post){
 pre = pre || "[";
 post = post || "]";
 return pre + st + post;
}

That was a nice Javascript idiom, but since default parameters were added to the language we can do just this:

function formatString(st, pre="[", post= "]"){
 return pre + st + post;
}

That's nice for functions expecting just a few parameters, but if we have many values to pass, we will be joining them in an "options object". This is not just a consequence of javascript missing named arguments, even if we had them (like in C#) having a method signature with a large list of parameters is rather painful and an "options object" is a much better option. For this case we can use destructuring assignment like this:

function formatString(st, {
   pre = "[",
   post = "]"
  } = {}){
 return pre + st + post;
}

console.log(formatString("hi"));
console.log(formatString("hi", {pre: "X"}));
console.log(formatString("hi", {pre: "X", post: "X"}));

If we have a constructor function where we are receiving several values to be assigned to the instance being created, we can do like in the first 2 examples above:

class Formatter{
 constructor(pre, post){
  this.pre = pre || "[";
  this.post = post || "]";
 }

}

class Formatter{
 constructor(pre="[", post= "]"){
  this.pre = pre;
  this.post = post;
 }
} 

But if we are passing an options object which properties we will be assigning to this, we'll have to use Object.assign:

class Formatter{
 constructor(options){
  let defaults = {
   pre: "[",
   post: "]"
  };
  Object.assign(this, defaults, options);
 }
 
 formatString(st){
  return this.pre + st + this.post;
 }
}
 
let formatter = new Formatter();
console.log(formatter.formatString("hi"));

formatter = new Formatter({pre: "X"});
console.log(formatter.formatString("hi"));

formatter = new Formatter({pre: "X", post: "X"});

Given that I mention Object.assign, ES Next features a pretty nice way to join several objects into a new one by means of the spread in object literals

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };

// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

Tariq the Rapist

Some weeks ago Charlie Hebdo published an excellent article comparing the "Law of Silence" in Hollywood around the sexual aggressions to women with the "Law of Silence" around radical Islamists in most of the islamized (occupied) neighbourhoods in France (and Belgium for the matter). They proposed to start a campaign similar to "#balancetonporc" (report your pig), that should be called "balancetonyihadist". I absolutely like the idea, but indeed I would prefer a "report the Islamist", as I don't care if they have already, or are about to commit violent actions, as long as they follow an Islamist/Salafist/rigorist Islam they are our enemies and should be expelled from our countries (or imprisoned for life if there's no other choice). Also, unfortunately I think the "Law of Silence" around Islamists is not only a matter of fear ("they'll burn my shop or my car if I inform on those beasts in the 'quartier'"). I think in too many cases the sense of community (that has moved from a positive "help each other" to disgusting, segregationist "communitarism") plays a huge role. I think too many muslims think like this: "I don't fully agree with these 'radicals', but they are 'my people', not like the 'white (or yellow) French infidels'.

Anyway, there has been some nice news in the last weeks. Given the hate and despite that Islamists feel for women, it's not strange that Islamists show up in the list of sex-abusers being reported. Some weeks ago the Islamist scum Tariq Ramadan was accused by Henda Ayari, a woman that after having being brainwashed into Salafism managed to escape from this sect and embrace freedom and dignity some years ago. During the dark times when she was an Islamist she was raped by one of the most popular Islamists, that bastard so admired by the "Islamo-Gauche", Tariq Ramadan. After her, more women have reported being raped by him. You can say that he has not been judged and I should be applying the "Presumption of Innocence" principle. On one side, that principle applies to Human beings, not to medieval beasts. Bearing in mind that for an Islamist abusing, punishing and raping women is just like breathing, I don't think this principle should be applied. If one has to choose between believing what normal people (the abused women) say, and believing what a beast full of contempt for anyone not belonging to the "Islamist clan" says, the choice is pretty clear to me. On the other side, anything that can damage the image of this motherfuckers seems good to me, so the faster and louder we spread the news, the better.

Charlie Hebdo did some excellent cartoons of this "cool and calm" Islamist shithead, and received (once again) dead threats for it...

The official media of the anti-Laique, anti-French, pro-Islam, pseudo-left "movement", Mediapart, was fast to attack Charlie-Hebdo again, and in a delirious statement accused them of being part of a lost left which obsession against Islam sides them with the far-right... I would love to see the offices of Mediapart (assuming that they have physical offices for putting online the hate-speech of a bunch of islamo-collaborationists) burnt to ashes, and the traitor Edwy Penel searching for a job in Qatar...

HUNT DOWN THE ISLAMISTS AND THEIR COLLABORATORS!!!

Wednesday 1 November 2017

Async Recursion

For no particular reason the other day it came to my mind how recursion and asynchrony played together. I've played with some examples and I'm putting them here.

Let's just start with the synchronous, recursive version:

function syncOperation(item){
 return item * item;
}

function recursiveCalculation(items){
 if (items.length == 0){
  return 0;
 }
 
 let curItem = items.shift();
 return syncOperation(curItem) + recursiveCalculation(items);
}

let items = [5, 4, 8];
console.log("result:" + recursiveCalculation(items));

Next the function becomes asynchronous and will invoke a callback function once it's finished. This is similar to asynchronous loops where in the callback you invoke a function that will launch the next iteration of the loop. Here in the callback we invoke a function that will launch the next recursive call.

function asyncOperation(item, callback){
 console.log("asyncOperation");
 setTimeout(function(){
  let res = item * item;
  callback(res);
 }, 1000);
}




function bootStrapRecursion(items, endCallback){
 let result = 0;
 let processItems = (items, newResult) => {
  result += newResult;
  if (items.length == 0){
   endCallback(result);
  }
  else{
   let curItem = items.shift();
   asyncOperation(curItem, newResult => {
    processItems(items, newResult);
   });
    
  }
 };
 processItems(items, 0);
}

let items = [5, 4, 8];
bootStrapRecursion(items, function(result){
 console.log("async result: " + result);
});

Now We move into the modern world, the asynchronous function returns a Promise rather than invoking a callback.

function promisifiedAsyncOperation(item){
 return new Promise((resolve, reject) => asyncOperation(item, resolve));
}

I've come up with 2 ways of using it. Either we return a Promise that we will resolve from the end condition of the recursion


function bootStrapPromisifiedRecursion(items){
 return new Promise((resolve, reject) => {
  let result = 0;
  let processItems = (items, newResult) =>{
   result += newResult;
   if (items.length == 0){
    resolve(result);
   }
   else{
    let curItem = items.shift();
    promisifiedAsyncOperation(curItem).then((newResult) => processItems(items, newResult));
     
   }
  };
  processItems(items, 0);
 });
}

 let items = [5, 4, 8];
 bootStrapPromisifiedRecursion(items).then(result => console.log("promisified result: " + result));

Or we do Promises nesting


function bootStrapPromisifiedRecursion2(items){
 let result = 0;
 let processItems = (items, newResult) =>{
  result += newResult;
  if (items.length == 0){
   return Promise.resolve(result);
  }
  else{
   let curItem = items.shift();
   return promisifiedAsyncOperation(curItem).then((newResult) => processItems(items, newResult));
    
  }
 };
 return processItems(items, 0);
}
let items = [5, 4, 8];
bootStrapPromisifiedRecursion2(items).then(result => console.log("promisified result: " + result));

Finally, we move into next generation javascript using the async/await magic words. This way the code looks almost the same as in the non asynchronous initial sample


async function recursiveCalculationAsyncAwait(items){
 if (items.length == 0){
  return 0;
 }
 
 let curItem = items.shift();
 let auxRes = await promisifiedAsyncOperation(curItem);
 return (await recursiveCalculationAsyncAwait(items)) + auxRes; 
}

async function runAsyncAwait(){
 let items = [5, 4, 8];
 let result = await recursiveCalculationAsyncAwait(items);
 console.log("async/await result: " + result);
}
runAsyncAwait();

One important point to bear in mind is that with asynchronous recursive calls we won't have stack overflow issues whatever deep our recursion is. Being asynchronous we are not pushing frame after frame in the stack. The asynchronous call returns immediatelly and the stack frame is released.