Sunday, 23 August 2020

Method Composition

Every now and then I'll find something that will remind me again of how beautiful a language JavaScript is. This time I came up with a not much frequent need, Method Composition. Function Composition is quite popular, and libraries like lodash-fp with its Auto-Curried, iteratee-first, data-last approach make composition really powerful.

In this case I'm talking about composing methods. May seem a bit odd, but I came up with a case where it could be rather useful. I have several methods that modify (yes, in spite of the immutability trend I continue to use mutable objects on many occasions) the object on which they are invoked, and I'm calling several of them in a row, to the point where it would be useful to add a new method to the class that just performs all those consecutive calls. Adding a new method to the "class" is so easy as adding the new function to the prototype of the "class" (if I just wanted to add it to an specific instance I would add it to the instance __proto__ (or instance [[Prototype]])). In order to invoke the sequence of methods we have to bear in mind that each method can have a different number of parameters, but Function.length comes to our rescue.

It's more useful to just see the code than further explaining it, so here it goes the factory function that composes the different methods:

 

function composeMethods(...methods){
    //use a normal function, not an arrow, as we need "dynamic this"
    return function(...args) {
        methods.forEach(method => {
            let methodArgs = args.splice(0, method.length);
            method.call(this, ...methodArgs);
        })
    }
}

And given a class like this:

 

class Particle{
    constructor(x, y, opacity){
        this.x = x || 0;
        this.y = y || 0;
        this.opacity = 1;
    }

    move(x, y){
        this.x += x;
        this.y += y;
    }

    fade(v){
        this.opacity += v;
    }
}

We'll use it this way to compose the "move" and "fade" methods into a new "moveAndFade" method:

 

//composing "move" and "fade" and adding it as a new "moveAndFade" method
Particle.prototype.moveAndFade = composeMethods(Particle.prototype.move, Particle.prototype.fade);

let p1 = new Particle();
console.log(JSON.stringify(p1));

//x, y, v
p1.moveAndFade(4, 8, -0.1);
console.log(JSON.stringify(p1));

p1.moveAndFade(2, 3, -0.2);
console.log(JSON.stringify(p1));

// {"x":0,"y":0,"opacity":1}
// {"x":4,"y":8,"opacity":0.9}
// {"x":6,"y":11,"opacity":0.7}


I've uploaded it into a gist.

Saturday, 22 August 2020

Fix Broken Folder

I'll share this experience here in case it can help anyone. This morning I was copying a bunch of films on Ubuntu from my laptop to and external NTFS disk. The copying got stuck at 50% and after a while I cancelled it. The usb disk seemed to be still in use but anyway I disconnected it (as so many times before). When connecting it again it looked fine, save for the folder "Films" on which I was copying the files. Opening the folder from the UI it showed up empty. From the command line I could do a cd into it, but doing a ls would return reading directory '.': Input/output error

I did not enter into panic as all the other folders with important stuff (and already backed up in other disks) like personal pictures, documents... seemed intact, so I was only losing like 400 films... (many of them scattered over other old, smaller, external disks). Anyway, managing to recover the folder would be nice...

The first thing I found about was running the badblocks command to verify that the disk was physically OK (I honestly thought so, as all the other folders looked good I was more leaning to think of a file system error). badblocks was taking so long, so I did a fast search and found that it could take up to 70 hours!!! and just to verify something, not to fix the disk...

I read by passing something that I already knew but was missing, that even if NTFS disks are perfectly supported in Linux since a very long while... it's Microsoft who has the full knowledge of the system, so I thought I could check if Windows was able to recognize the folder.

Rebooting my laptop on Windows and trying to navigate the folder I got this error:
The File or Directory is Corrupted and Unreadable

A fast search brought up this article, that recommended doing a chkdsk /f on the problematic disk.

After a few seconds the first messages stating that some error had been found and had been fixed showed up, so it was quite reassuring. After less than 10 minutes (for a 2TBs disk with a 30% use disk), the procedure was finished and the contents of my "Films" folder were back again! I'm putting below some of the fix messages that chkdsk returned:

Saturday, 8 August 2020

Reconcile the French People

There's much talking (but no acting at all) in France about the Islamisation, communitarism-separatism (immigrant communities rejecting to integrate and assimilate, and creating their own close, xenophobic and medieval communities), the skyrocketing levels of criminality and violence (now we call it "ensauvagement"), the ridiculous laxity of the justice system (particularly when the criminals are part of a so called "minority")... and bla, bla, bla...

Regarding this separatism, there's a nice and well thought (as usual, it's interesting how much someone like me that has swung to the center-right continues to respect these "traditional left" guys) set of writings/drawings in Charlie Hebdo issue 1461, 600 jours pour rabibocher les Francais/600 days to reconcile the French people. From all of them, there's one by Riss that particularly stands out, so I'm translating it here (sorry for my lack of translation skills):

Travelling educates the young people

Young people between 15 and 25 years old having committed repeated criminal acts will be comdemned to spend the prison sentence expected for adults by the Penal Code, not in prison, but in a foreign country, in a French NGO. 10 months of prison will become 10 months to be spent in New Delhi taking care of people infected with leper or tuberculosis. 12 months of prison will become 12 months in a Health center in a slum in Haiti. The aim is to move these young people away from their environmnet and to make them discover new horizons. At the end of their condemnation purged this way, they'll get a job offering in France, related to the activities conducted in the NGO that has taken them in and educated them.

As I have little trust in some humans I'm not sure to what extend this could work, but for sure it's a better option than the ridiculous prison sentences in a comfortable French prison and the social aids that the tax payers will pay them once they are out committing crimes again... The other options that I would favor: removing their French nationality if they are bi-nationals, penal labour or plain-good-old capital punishment... I guess are not acceptable by our naive European societies...

 

 

Sunday, 2 August 2020

Retry Async Function

The other day I had an async function that could fail (rejecting its promise) quite often and wanted to retry it a few times if needed. In the end I wanted to generate a new function with the retry functionality in it. I had done this in the past with pure promises and had been a bit more complex (it was something along the lines of what you can find here), but with async-await the code is so simple that I'm not sure why I'm posting it here, anyway:

 

//wrap setTimeout with an async-await friendly function
function sleep(ms){
    console.log("sleep starts");
    let resolveFn;
    let pr = new Promise(res => resolveFn = res);
    setTimeout(() => {
        console.log("sleep ends");
        resolveFn();
    }, ms);
    return pr;
}

//fn: function returning a Promise
//if the Promise is rejected we'll retry up to "attempts" times, with a "timeout" in between
//returns a new function with retry logic
function addRetryToAsyncFn(fn, attempts, timeout){
    return async (...args) => {
        while (attempts--){
            try{
                return await fn(...args);
            }
            catch(ex){
                console.log("attempt failed");
                if (!attempts)
                    throw ex;
            }
            await sleep(timeout);
        }
    };
}

//given an async function: getAndFormatNextTicket
//we'll use it like this:
let formattedTicket = await addRetryToAsyncFn(getAndFormatNextTicket, 5, 1000)("Francois");

Thanks to async/await the retry code for an async function is basically the same as the one for a normal function:

 

function addRetry(fn, attempts){
    return (...args) => {
        while (attempts--){
            try{
                return fn(...args);
            }
            catch(ex){
                console.log("attempt failed");
                if (!attempts)
                    throw ex;
            }
        }
    };
}

You can see a full example here.

Saturday, 1 August 2020

Tour In Nova, Bordeaux

Last week I did a day-trip to Bordeaux (the so beautiful "La belle-endormie"). As the train approached Saint Jean (the gorgeous main train station nicelly refurnished a few years ago) I could see in the distance a new addition to the city's skyline, the Tour In Nova. Bordeaux is a low rise city, with whole neighbourhoods made up by 1 - 2 stories buildings (though not as low rise as Toulouse, probably the lowest-rise mid-size city in the world). This listing about Bordeaux buildings seems quite accurate to me. As you can see it got 3 (unappealing I can say) administrative towers in the 70's, peaking at 90 meters, and then some residential towers that I assume are mainly in Grand Ensembles.

However, in the last years some new, interesting "towers" (in France anything above 40 meters is a tower) and modern neighborhoods have been-are being built. La Cité du Vin is a prominent example. This building is located in the new Bassins a Flot area, where you'll find tons of 8-9 stories residential (and some office) buildings with interesting shapes, roofs and facades.

The other most notorious development area is the Euratlantique district, close to the main train station. I've seen this area emerge over the last years and I was feeling a bit disappointed so far, but the Tour In Nova has been a great surprise. Though not reaching 60 meters in height it's well visible when you enter the city, and the upper block looks really, really nice to me. It reminds me of the BEC tower in Bilbao (that is higher, but not that beautiful). It's a real shame that the crazy French security laws concerning high-rise buildings, that force you to keep a dedicated security team in place in buildings higher than 60 meters (well, it's a simplification, but you get the idea) prevented it from getting some additional floors (with 5-6 extra floors to reach 75-80 meters it would certainly stand out quite more). Anyway, if it had not been that law it would have been some "rednecks against modernity" citizens group who would have fight against such a "skyscraper"...

I can not close this post without mentioning the main reason for my last trip to Bordeaux, Les Bassins de Lumières. Some French people still have amazing ideas, living up to the glorious cultural traditions of the country. To leverage an enormous submarine base created by Fascist Italy and Nazi Germany during the occupation, to create a massive Digital art center (that opened just one month ago) is for sure one of those amazing ideas. Bordeaux is well worth a several days visit, and this new cultural space is well worth an afternoon.