Sunday 31 March 2019

Some JavaScript Goodies

Time for an entry with some JavaScript discoveries that I've done recently.

Reading some article I came across some code that I could not understand, something like:

class Person{
 [doSomething](){
 
 }
 
 //more code here
}

Odd, right? Well, that [doSomething] is a symbol, there was a previous declaration in the code like this: const doSomething = Symbol('doSomething'); so all in all this is a way to create private members. Typescript is not using this technique at all, the private methods in TypeScript are only at compile time, while this mechanism makes them private at runtime. Anyway, I don't see myself using it, but at least it's good to know.

The most common use of push and concat in JavaScript is: push to add a single element to an existing array, concat to merge 2 arrays into a new array. But you can use concat also to add a single element (still creating a new array). This detail is really useful to write the most concise function to get unique elements in one array that I can think of:

function getUniqueItems(arr){
 return arr.reduce((difItems, it) => difItems.indexOf(it) == -1 ? difItems.concat(it) : difItems
 , []);  
}

let ar = [1, 4, 5, 4, 1, 3, 2, 3, 2];
console.log(getUniqueItems(ar));
//[ 1, 4, 5, 3, 2 ]

An interesting point is that thanks to the rest/spread operator (...) we can now easily merge an array into an existing one:

let ar = [1, 2];
let ar2 = [3, 4];
ar.push(...ar2);
console.log(ar);
//[ 1, 2, 3, 4 ]

A while ago I posted about the (at that time new) rest/spread operator. Reading these nice snippets I've found many interesting uses of them. One thing that I have to thank to the ... operator is that it's spared me one of those recurrent dubious moments that made me go back to the documentation again and again to be refreshed about the difference between Function.prototype.call and Function.prototype.apply:

the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.

With the ... operator we no longer need apply, we can just use call:

let args = [arg1, arg2];

//rather than:
fn.apply(self, args);

//we can just use:
fn.call(self, ...args);

This led me to wonder how does the compiler spread the array and pass it as arguments? The inverse, rest, is very simple, wherever the operator shows up the compiler will add code to push the elements into an array, that's simple, but how does the compiler/interpreter spread that array into an argument list and pass it over to the function? We don't have anything like that in C# or Java, they work the opposite way. Well, I guess all the magic has to be in the Activation Object. A JavaScript function when invoked (activated) ends up with an execution context that contains in its Activation Object, the arguments and local variables. So I guess the compiler just pushes the elements of the array that it's going to spread into this activation object.

Tuesday 26 March 2019

Switch Expressions

I found out some days ago that Java 12 comes with switch expressions. Doing some googling it seems that C# 8 could also get them added.

The feature seems rather nice (I directly copy/paste the Java sample)

int value = switch (number) {
    case "ONE"   -> 1;
    case "TWO"   -> 2;
    case "THREE" -> 3;
};

I immediately wondered if JavaScript was planning to incorporate this feature, but some googling brought no answers. Well, giving it a second thought, the thing is that with JavaScript's clean and concise syntax we can almost the same by using a dispatch table:

let numStr = "TWO";
let num = {
        "ONE": 1,
        "TWO": 2,
        "THREE": 3
    }[numStr];

It's almost the same, just the switch condition is moved from the beginning to the end of the expression. Doing the same in C# is a bit more verbose mainly because of having to write the type:

var numStr = "TWO";
int item = new Dictionary<string, int>{
 	["ONE"]= 1,
    ["TWO"]= 2,
    ["THREE"]= 3
}[numStr];

Notice that we're using the Dictionary initializer syntax incorporated in C# 6.

By the way, I've never thought about the small performance differences between a switch statement and dispatch table, so this StackOverflow question has been a nice reading.

Monday 18 March 2019

Lune de Miel

A few days ago I watched what I think is the second Romanian film I've ever set my eyes on. The first one was like 10 years ago in the Xixon Film Festival. I don't remember the title or basically what it was about, my only memory is that it was boring and awful, nothing to do with my second approac to Romanian cinema last weekend.

Lune de Miel (Honeymoon) is an intense film telling the story of a Romanian nurse that has immigrated to the USA an got married to one man she met in the clinic. Now she's trying to obtain a green card so that she can remain and work in the country (from a European perspective the situation is rather odd, that after marrying a national of the country she has no right to work there...). Obtaining the so longed card is not an easy taks. The couple has to undergo an evaluation to prove that it's not a convenience marriage, and the man in charge becomes very hard with her. The classic stereotype of USA idiot that thinks that his country is the most perfect creation on earth and that anyone trying to immigrate there is a criminal trying to take profit of the efforts of his ancestors that worked so hard to build such an extraordinary country... The guy will blackmail her trying to force her into having sex with him and the whole thing will break her marriage and leave her (and her son, that has just moved from Romania pursuing the "American Dream") in a rather difficoult situation.

A good story about the Human will to get a better life for us and for ours, and about the Human blind stupidity that will see in "the other" an enemy just because he is "the other". Don't get me wrong, I'm no longer a "no borders, everyone is welcome" leftist asshole. I don't think everyone deserves a place in our society, but I still fiercely think that anyone sharing with us a set of common values and showing a willingness to integrate and contribute to the well working of this society must be allowed to find a place here, wherever he comes from.

Tuesday 5 March 2019

iTables and vTables

It's beautiful to see a mistery unveil before you many years after the first time you tried to disclose it. It suddenly brings you so many memories of the person you were at that time... OK, to the point. It's been more than 15 years since I learnt that the dispatch of virtual methods in languages like C++, Java or C# worked thanks to a memory structure called vTable (Virtual Methods Table). Long in short, the vTable holds function pointers, and the caller knows the index for each method in the table. In a derived class, each method present in the parent class occupies the same position (index) in the child vTable that in the parent vTable, pointing to the new implementation (if the method has been overriden) or tothe same implementation of the father.

That's clear and simple for single inheritance hierarchies, but it's not enough for multiple inheritance (either of classes or interfaces). If we are implementing 2 interfaces, each of them will have a method that should be in position 1 of the table, so what? 15 years ago I could not find a clear explanation of how this issue was solved. I could imagine that there would be additional tables and somehow the code would use one or another structure... but as I've said, I could not find a clear explanation.

Don't ask me how, but for some reason the other day I came across an amazing article providing an excellent explanation. The description of Java's implementation is particularly clear. So in a class implementing 2 interfaces we still have a vTable, and we also have one iTable for each interface. For Interface1.MethodA we'll have and entry for MethodA in iTable1 and another one in the vTable, that obviously hold the same memory address pointing to the corresponding MethodA implementation. Same for Interface2.MethodB (with the entry in iTable2). The big question is how does the runtime select iTable1 or iTable2? Well, each interface has an ID, and the iTables placed in a sort of dictionary using the ID as key. The code invoking the method through the interface uses the interface ID to locate the corresponding iTable. Simple and Brilliant. Just check the aforementioned article to really get it.