Saturday, 31 October 2020

Top and Bottom Type

When reading this post by Axel Rauschmayer about any being a "top type" in TypeScript, I found particularly interesting one of the comments, that argues that it's both a top and a bottom type:

1. any is like a top type in that you can assign values of all other types to it: let a: any = x works whatever type x has.
2. any is like a bottom type in that you can assign values with an any type to all other types: let a: any; let x: T = a is allowed for all types T (except never).

This made me revisit the behaviour of the dynamic keyword in C#. It's clear that it behaves as a top type, but I was a bit dubious about how the compiler dealed with it and to what extent it could be also considered a bottom type. Some code to the rescue:



    interface ITalkative
    {
        string SayHi();
    }
    
    class Person: ITalkative
    {
        public string SayHi()
        {
            return "Bonjour";
        }
    }

    class Printer
    {
        public static void Print(ITalkative t)
        {
            Console.WriteLine("[" + t.SayHi() + "]");
        }
    }

    class Cat
    {
        public string SayHi()
        {
            return "Miau";
        }
    }

 
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Started");
            dynamic ob = new Cat();

            try{
                Printer.Print(ob);
            }
            catch(Exception ex){
                Console.WriteLine("1. " + ex.Message);
                //The best overloaded method match for 'Dynamic.Printer.Print(Dynamic.ITalkative)' has some invalid arguments
            }
            
            try{
                Person p = ob;
            }
            catch(Exception ex){
                Console.WriteLine("2. " + ex.Message);
                //Cannot implicitly convert type 'Dynamic.Cat' to 'Dynamic.Person'
            }

            try{
                Printer.Print(ob as Person); //casting returns null and then Print fails
            }
            catch(Exception ex){
                Console.WriteLine("3. " + ex.Message);
                //Object reference not set to an instance of an object.
            }

            try{
                Person p1 = ob as Person;
            }
            catch(Exception ex){
                Console.WriteLine("4. " + ex.Message);
            }

  
        }
    }

I'm particularly interested in the first case. I was not sure if the compiler would allow that, but it does. So the compiler allows me to invoke a method that expects ITalkative with just a "dynamic" value, so yes, we can say that dynamic is a bottom type. Notice however that dynamic in C# has nothing to do with Duck Typing (or TypeScript's structural typing), so it's obvious that this will fail at runtime. The method invocation Printer.Print fails cause the runtime checks (it's different from a cast error) if the parameter implements ITalkative, as that is not the case, we get a The best overloaded method match for 'Dynamic.Printer.Print(Dynamic.ITalkative)' has some invalid arguments exception.

A decade ago (puff...) I had posted about Duck Typing in C# and dynamic, but probably I was thinking that we would already get a compiler error in this situation, rather than a runtime one.

Tuesday, 13 October 2020

Sin Fin

Sin Fin is a beautiful Spanish film. It combines Drama, Romance and Science Fiction. The Science Fiction element (time travelling from 2015 to 1993) is there just to allow the story to happen, the romance part leads to the drama, that is the prevailing element.

A story about how the purchase of a dream brings about the destruction of who has been devoted to you for 20 years, about devoting the rest of your broken life so that the materialization of the dream can erase the nightmare, about correcting in 1 day the errors of 2 decades...

I have a particular appreciation for any art piece (whatever the form) that portrays the passage of time, distant moments of one life, that reminds us of our temporarity, that confronts us to how what we do today determines our future, and how maybe one day in that future we'll look at that distant "today" with sorrow and tears or with joy and reverence, with a desire to erase or repeat that day. This film is about making mistakes and being given the chance to travel in time to correct those mistakes, to save a life, to save two lives.

The story stars in 1993, with a boy and a girl of around 20, in that moment in your existence where you have that sacred power to dream and shape your future, where a single day can determine the joys and pains of the ensuing decades. It's such a power and such a responsibility that it gives me vertigo now. I was not aware of that power when I had it, it was not until a couple of years ago that I started to look back at that time in my life with a sort of nostalgia, but a healthy one, with a sort of gratitude for still having a present now, and for not being so fully aware of how each decision at that time was drawing a path for which there would not be way back...

Twenty years later the energetic, dreamy girl has turned into a depressive adult with no other prospect that putting an end to everything. The genious guy obsessed with creating something "big" is now an unhappy adult with that same obsession that so far has not done other thing than destroying their lives... I'll stop here, it should have been enough to wake up your interest or to bore you even more than usual.

It's a slightly rainy autumn afternoon in Toulouse, a vacation day in the first year of the pandemia. I'm listening to Yarostan and Les deux minutes de la Haine, 2 bands that I already knew, but that did not fully get my attention until I listened to their stuff in the best record of this year?... and I'm giving these details beacause I think they play well with the melancholy in this post, and if some day in the future I read back these paragraphs I'll enjoy being reminded of these details, details that make up a life...

Saturday, 3 October 2020

Defend Armenia

I'm not religious, but as a proud European I clearly adhere to Eric Zemmour's mantra about the roots of European civilization: "Europe is the Greek Culture, the Roman Culture and Christianism". Yes, we have the Celts, the Germanic tribes... but 90% of what we are as Europeans come from those 3 cultural and moral frameworks.

Armenia, (by the way, the first Christian nation) is part of our Western civilization, as obviously, Greece is. Last month Turkey (the reverese reflection of everything European Civilization stands for, our eternal enemy) was threatening Greece with war as Turkey intends to steal part of Greece's maritime space to leverage the gas fields that are supposed to be there. Most of Europe said nothing, it was only France who clearly stood by our European Brothers. On the other side, Germany, terrified by the enormous amount of Turkish invaders that have settled on the country in the last 50 years and how they (particularly the neo-fascist, paramilitary organization grey wolves) could react setting the country in flames... did as much as possible to avoid any sort of common European action that could bother the neo-sultan Erdogan... 

This last week, Azerbaijan (this is a different country, but Azerbaijanis are a Turkic ethnic group, so they are not much different from the Turkish (scum) people, by the way, obviously both of them are Muslims) has launched an attack on the Armenian people living in the Nagorno Karabakh region. Almost immediatelly Erdogan expressed his support for his ethnic, muslim brothers and made it clear that he would help them by any means.

Turks have a tradition of killing (and torturing, and enslaving, and raping and whatever...) Christians, particularly Armenians and Greeks (but also Serbians, Romanians... well any sort of Europeans... haven't you heard about the Ottoman pirates?) so this new war against Armenia (as the low level conquest war that ultranationalist-islamist Turkish criminals fight everyday in the unfortunate European cities where they have settled). In the last decades the Turkish government had favored to kill and torture Kurds and now they aim to leverage the knowledge that they gained while massacring the Kurds in Northern Syria to slaughter the Armenians. At least, they are sending against the Armenians some of the same Jihadist mercenaries that they paid for to try to annihilate the Kurds. If you think I'm a delirious European nationalist... well, you can see that it's not just me, it's Emmanuel Macron also who says it.


 

In the last decades, cowardice, self-hate and the absolute ignorance of almost any lesson drawn from our history... have fed the decadence of European civilization. Supporting our Armenian and Greek brothers (by any means necessary) against our common enemy should be a first step in regaining our dignity as a people and reconquering our lands.

I've found interesting this article about the influential Armenian diaspora getting ready to support the land of their ancestors. And well, this picture of a 106 years old Armenian woman during the previous chapter of this war (back in the 90's) is an incarnation of courage and dignity.

 


 

Saturday, 26 September 2020

JavaScript Arrays Oddities

As almost everything in the language, Arrays in JavaScript are not exactly the same as in other languages. In principle one thinks of an array as a continuous section of memory, where each item has the same size and hence it can be easily located based on its numeric index (you know: startAddress + (index * itemSize))... Well, this is not always the case in JavaScript.

First, in JavaScript arrays can be sparse (rather than dense). This means that if you create an array of a given size (e.g.: new Array(200);) but you only assign a value to some of those 200 positions, the unassigned ones are "holes" and do not take up space. Accessing one of those holes will retun an undefined value, traversing the array with for-of will also return undefined values, but traversing it with .forEach will skip the "holes". If we really had "holes" in the array (rather than having those positions pointing to "undefined") the Array can not be just a continuous piece of memory... Well, this article explains how it's implemented in the v8 engine. You can read there that for small arrays, a real array (continuous memory space) is used, with those empty spaces containing a "hole" value, so there's not any saving in memory space. If the array is big, then "a low level array" is no longer used, but a dictionary where the numeric indexes are the keys.

The article stops there, but there are more oddities with arrays. If you are familiar with Python (or with the last C# addition, indexes) maybe you have tried to use a negative index with your array. That sort of works in JavaScript, but not as you would expect. array[-1] does not refer to the last item in the array, but to a "-1" property (indeed as if you use any other string). So doing ar[-1] = "ax"; will add a property to the object:

 

> let ar = ["a","b"];
> ar;
[ 'a', 'b' ]
> ar[-1];
undefined
> ar[-1] = "Bonjour";
'Bonjour'
> ar[-1];
'Bonjour'
> ar;
[ 'a', 'b', '-1': 'Bonjour' ]
> 

So in a case like that I don't know how it is implemented. Maybe the "normal" part of the Array is maintained as a low level array and a dictionary is used only for the non numeric indexes, or maybe a dictionary is used for both numeric and non numeric indexes.

One additional comment. Both numeric and non numeric indexes are considered as "own properties" of the array. However, holes in the sparse array are not "own properties".

 

> ar;
[ 'a', 'b', '-1': 'Bonjour' ]
> ar.hasOwnProperty(1);
true
> ar.hasOwnProperty(-1);
true
> ar.hasOwnProperty(-2);
false

> let sparseAr = new Array(5);
> sparseAr[2] = "aa";
> sparseAr;
[ <2 empty items>, 'aa', <2 empty items> ]
> sparseAr.hasOwnProperty(0);
false
> sparseAr.hasOwnProperty(2);
true


Saturday, 19 September 2020

Canvas Double Buffering

In the past I did a bit of Html Canvas programming (for example: this), and I never needed to resort to double buffering to avoid flickering. I did not pay much attention to it at the time, but the other day I came across some discussion as to whether double buffering was necessary. Though you can find some discrepancies and some samples claiming to cause flickering, the main answer is that No, you don't need to implement double buffering, which leads us to something more interesting, why not?

The fiddle in this answer is rather instructive, but what the author says Lucky for us every canvas implementation implements it (double buffering) behind-the-scenes for you. could be misleading.

If we have an understanding of how the event loop works in the Browser (or in node), we know that user interactions, timeouts, requestAnimationFrame... enqueue tasks in a macrotask queue (for the current discussion we can omit the microtask queue), and that the event loop will take tasks from that queue one by one, executing the corresponding javascript code, and updating the DOM (rendering) after each task is completed. This "updating the DOM after the ask is completed" is essential for this explanation. From the article:

Rendering never happens while the engine executes a task. It doesn’t matter if the task takes a long time. Changes to the DOM are painted only after the task is complete.

So if we are drawing animations to a canvas (normally based on requestAnimationFrame), each animation frame javascript code will run as part of a Task, and when that frame code is completed, the rendering will happen. So all the sequential drawing calls that we do to the Canvas Context (clear the canvas, draw a rectangle, draw a circle...) won't be visible until the whole sequence of drawing operations is complete (the task is complete) and then the rendering-drawing takes place.

I don't think the Canvas element uses a second (hidden) canvas to draw on it during the Task (javascript) execution phase, and then draws that Canvas on screen during the rendering phase, I just think that all those drawing operations are stored, and then, during the rendering phase, they are painted to the canvas.

Tuesday, 8 September 2020

Promise Inspection Part 2

In my previous post I said that probably there was an easier way than inheritance to implement synchronous inspection in Promises, so that's what this post is about.

This mechanism is used differently from the one shown last week. Rather than receiving an executor function and creating a Promise from it, we receive an existing Promise, and chain to her a new Promise that is expanded with the expected inspection methods (isFulfilled(), isRejected(), getValue(), getReason()). The code is pretty straight forward. The new Promise waits for the original Promise and when this one is completed or rejected it sets her inpection properties accordingly.

An interesting point is that indeed the new Promise does not hold the isFullfilled, value, reason... values (used by the corresponding isFullfilled(), getValue()... expansion methods) as data fields (that hence could be set from outside), but as variables that get trapped by the closures used for each of those expansion methods. This is an old trick used for creating private fields in JavaScript.

Donc, voilĂ  le code:

 

//returns a new Promise expanded with inspection methods
function enableSyncInspect(pr){
    //we trap these variables in the closure making them sort of private, and allow public access only through the inspection methods that we add to the new promise
    let isFulfilled = false;
    let value = null; //resolution result
    
    let isRejected = false;
    let reason = null; //rejection reason
    
    let isPending = true;

    //create a new promise that gets resolved-rejected by the original promise and gets expanded with inspection methods
    let prWrapper = pr.then(_value => {
        isPending = false;
        isFulfilled = true;
        value = _value;
        return _value;
    }, _reason => {
        isPending = false;
        isRejected = true;
        reason = _reason;
        return _reason;
    });

    prWrapper.isFulfilled = () => {
        return isFulfilled;
    }

    prWrapper.getValue = () => {
        return isFulfilled 
            ? value
            : (() => {throw new Error("Unfulfilled Promise");})(); //emulate "throw expressions"
    }

    prWrapper.isRejected = () => {
        return isRejected;
    }

    prWrapper.getReason = () => {
        return isRejected
            ? reason
            : (() => {throw new Error("Unrejected Promise");})(); //emulate "throw expressions"
    }

    prWrapper.isPending = () => {
        return isPending;
    }

    return prWrapper;
}


That we can use like this:

 

function formatAsync(msg){
    return new Promise((resFn, rejFn) => {
        console.log("starting format");
        setTimeout(() => {
            console.log("finishing format");
            resFn(`[[${msg}]]`);
        }, 2000);
    });
}

function printValueIfFulfilled(pr){
    if (pr.isFulfilled()){
        console.log("Promise resolved to: " + pr.getValue());
    }
    else{
        console.log("Promise NOT resolved yet");
    }
}

//async main
(async () => {
    let pr1 = formatAsync("Bonjour");
    let syncInspectPr = enableSyncInspect(pr1);

    console.log("isPending: " + syncInspectPr.isPending());

    //this fn runs in 1 seconds (while the async fn takes 3 seconds) so it won't be fulfilled at that point)
    setTimeout(() => printValueIfFulfilled(syncInspectPr), 1000);

    let result = await syncInspectPr;
    console.log("result value: " + result);
    
    printValueIfFulfilled(syncInspectPr);

})();

//Output:
// starting format
// isPending: true
// Promise NOT resolved yet
// finishing format
// result value: [[Bonjour]]
// Promise resolved to: [[Bonjour]]


As usual I've uploaded it into a gist.

Tuesday, 1 September 2020

Promise Inheritance and Synchronous Inspection

The other day, taking a look into the advanced Promises provided by bluebirdjs I though about how to implement a very small and basic part of the funcionality, the Synchronous Inspection, that basically stores the value resolved by a Promise and allows accessing to it synchronously (read the doc for a real explanation). There are other ways to implement it, but I decided to use inheritance, and has been interesting enough to post it here.

In a previous post I already made use of Promise inheritance, but I did not need to take into account the resolve and reject callbacks passed to the executor function received by the constructor. In this case I wanted to override those resolve-reject callbacks, so that I would add my additional logic (setting the isFulfilled and value or isRejected and reason values) and then invoke the originals (the parent ones let's say) so that they perform their magic logic of invoking the continuations (the "then"-"catch" handlers). These callbacks are not exposed as methods in the Promise class (one could think of having implemented them as protected methods in another language...), so in order to get hold of them to use them, we create an internal Promise with an executor function that just will give us a reference to those original callbacks, and then we call the original executor function passing to it resolve-reject callbacks that perform our extra logic and then invoke the originals. Our "then" overriden method invokes the internal Promise parent method, so that all the logic performed by the Promise class to set the continuations is run.

The explanation above is really confusing, so you better just check the code of my SyncInspectPromise class:

 


class SyncInspectPromise extends Promise{
    constructor(executorFn){
        //compiler forces me to do a super call
        super(() => {});

        this._isFulfilled = false;
        this._value = null; //resolution result
        
        this._isRejected = false;
        this._reason = null; //rejection reason
        
        this._isPending = true;
        
        //we need to be able to invoke the original resFn, rejFn functions after performing our additional logic
        let origResFn, origRejFn;
        this.internalPr = new Promise((resFn, rejFn) => {
            origResFn = resFn;
            origRejFn = rejFn;
        });

        let overriddenResFn = (value) => {
            this._isPending = false;
            this._isFulfilled = true;
            this._value = value;
            origResFn(value);
        };

        let overriddenRejFn = (reason) => {
            this._isPending = false;
            this._isRejected = true;
            this._reason = reason;
            origRejFn(reason);
        };

        executorFn(overriddenResFn, overriddenRejFn);
    }

    isFulfilled(){
        return this._isFulfilled;
    }

    getValue(){
        return this.isFulfilled() 
            ? this._value
            : (() => {throw new Error("Unfulfilled Promise");})(); //emulate "throw expressions"
    }


    isRejected(){
        return this._isRejected;
    }

    getReason(){
        return this.isRejected()
            ? this._reason
            : (() => {throw new Error("Unrejected Promise");})(); //emulate "throw expressions"
    }

    isPending(){
        return this._isPending;
    }

    then(fn){
        //we set the continuation to the internal Promise, so that invoking the original res function
        //will invoke the continuation
        return this.internalPr.then(fn);
    }

    catch(fn){
        //we set the continuation to the internal Promise, so that invoking the original rej function
        //will invoke the continuation
        return this.internalPr.catch(fn);
    }

    finally(fn){
        return this.internalPr.finally(fn);
    }
}


And we can use it like this:

 

function sleep(ms){
    let resolveFn;
    let pr = new Promise(res => resolveFn = res);
    setTimeout(() => resolveFn(), ms);
    return pr;
}

function printValueIfFulfilled(pr){
    if (pr.isFulfilled()){
        console.log("Promise resolved to: " + pr.getValue());
    }
    else{
        console.log("Promise NOT resolved yet");
    }
}

(async () => {
    let pr1 = new SyncInspectPromise(res => {
        console.log("starting query");
        setTimeout(() => {
            console.log("finishing query");
            res("hi");
        }, 3000);
    });
    console.log("isPending: " + pr1.isPending());

    //this fn runs in 1 seconds (while the async fn takes 3 seconds) so it won't be fulfilled at that point)
    setTimeout(() => printValueIfFulfilled(pr1), 1000);

    let result = await pr1;
    console.log("result value: " + result);
    
    printValueIfFulfilled(pr1);

})();

//output:
// starting query
// isPending: true
// Promise NOT resolved yet
// finishing query
// result value: hi
// Promise resolved to: hi

As usual I've uploaded it into a gist.