Thursday 23 August 2018

Function Currying

The other day somehow I came across some discussion about Currying. Currying in computer programming is a confusing technique, first because quite a few times the term is wrongly used for referring to Partial Application, and second, because I've always found it pretty difficult to find it any use (contrary to Partial Application, that for sure can be pretty useful).

After some thinking I've managed to envision one use case for currying, and indeed it has led me to do a sort of variation over the normal currying. I'll show it here. If you want an explanation of Currying vs Partial Application, you can for example check it here.

Lodash provides a curry function, but anyway I've written my own basic implementation:

function curry(fn){
 let args = [];
 let originalFunc = fn;
 let argsNum = fn
 return function curriedFunc(arg){
  args.push(arg);
  if (args.length >= originalFunc.length){
   return originalFunc(...args);
  }
  else{
   return curriedFunc;
  }

 }
}

And now the difficult part, coming up with one case where currying could be useful!
Well, let's say that I have a function "retrieveAndProcess", that takes care of retrieving items one by one (through a "getNextItem" function), and then passes all those items to a second function "processItems". The thing is that our main function does not know how many items "processItems" needs. So our main function contains a loop that calls to getItem and processItems until this second one returns the processing result, rather than a function. This "curried" processItems is a closure that can keep the different items that it receives until that it gets all the ones that it needs and can process them all at once. Let's see an example:

function* userDataGenerator(){
 yield "Francois";
 yield "Toulouse";
 yield 42;
}


function format(name, city, age){
 return "My name is: " + name + ", I live in: " + city + " and I'm " + age;
}


function getUserDataAndFormat(formatFunc){
 let generatorObj = userDataGenerator();
 let formattedData = curriedFormatFunc(generatorObj.next().value);
 while(typeof formattedData == "function"){
  formattedData = formattedData(generatorObj.next().value);
 } 
 return formattedData; 
}

let curriedFormatFunc = curry(format);
console.log("Formatted user data: " + getUserDataAndFormat(curriedFormatFunc));

After writing that sample I realised of a variation of function currying that could be useful. Let's say that we have a function that can work with a variable number of parameters (imagine we had an Array.prototype.sum). It could be interesting to create from it a curried function that works for a specific number of parameters. For example I have a function that calculates the average of any number of items, and I want to create a curried version that will work for just 3 elements. Let's see what I mean:

//expects a function that can work with a variable number of parameters 
//and returns a curried version that will work for a concrete number of parameters (argsNum)
function curryWithMaxParameters(fn, argsNum){
 let args = [];
 let originalFunc = fn;
 if (argsNum === undefined){
  argsNum = fn.length;
 }
 return function curriedFunc(arg){
  args.push(arg);
  if (args.length >= argsNum){
   return originalFunc(...args);
  }
  else{
   return curriedFunc;
  }

 }
}


function* ageGenerator(){
 yield 10;
 yield 12;
 yield 14;
}

function average(...args){
 return args.reduce((it1, it2) => it1 + it2) / args.length;
}


function requestAndCalculateAverage(averageFunc){
 let generatorObj = ageGenerator();
 let averageAge = averageFunc(generatorObj.next().value);
 while(typeof averageAge == "function"){
  averageAge = averageAge(generatorObj.next().value);
 } 
 return averageAge; 
}

console.log("testing currying for a given number of parameters");

let curriedAverage3ItemsFunc = curryWithMaxParameters(average, 3);
console.log("average age: " + requestAndCalculateAverage(curriedAverage3ItemsFunc)); //12

Friday 17 August 2018

Paris Futur

I love cities and architecture and though I have to admit that I have a rather particular taste, the fact that I consider Paris as the most beautiful place on earth does not deviate so much from standard liking. Anyway, apart from my obvious fascination with historical Paris, I find also an enormous delight in modern Paris. One could think it boils down just to La Defense, but there are quite a few more interesting planned, new, recent or relatively recent, modern developments in Paris. For example I pretty much appreciate the Biblioteque Francois Mitterrand, the modern, mid-rise buildings in the Rive Gauche and Batignoles ZACS (notice also that both ZACs are crowned up with one/two skyscrappers) and of course, the so disliked Tour Montparnasse (it seems like years ago it ranked second in a web poll about the ugliest buildings in the world). I absolutely love how majestic it looks isolated in the middle of classic, Hausmannian Paris, a reference point visible from anywhere in the city. I admit that its dark, "sad" exterior is not its strong point, so finding out that the tour is going to be fully revamped has been pretty nice news (moreover considering that in the last decade several conservative candidates to the mayor's office had proposed to demolish it...). You can read here that Montparnasse will get a vegetalized, transparent facade, and will even grow 18 meters thanks to a greenhouse on its top!

Searching more information about it I've come across an excellent site referencing some of the main new architectural projects in Paris, Paris Futur. I already knew about many of the projects shown there, but it's really nice and convenient to have them listed together in the same place. La Defense continues to thrive, with the construction of 2 new skyscrappers already started (Tour Hekla and Jardins de l'Arche), and other 2 projects almost ready to start (tours Sisters and the new headquarters for Total). On the other side, high rise buildings in Paris intramuros continue to be controversial to say the least, and the opposition of different groups of rednecks continues to hinder the construction of the amazing Tour Triangle. There's one project that is not mentioned in ParisFutur but that has managed to defeat the "Anti-Tour" opposition and is well under construction, Les Tours Duo by Jean Nouvelle. Right in the border with Ivry sur Seine, but still inside the Peripherique!

Monday 6 August 2018

Task.Run in JavaScript

Web Workers have been for sure a great addition to Javascript, but its usage has always seemed a bit odd to me. So you create an "execution unit" (the spec does not say if it'll be implemented as a threat or a process) from a js file that contains the code for that execution unit, and communicate with it via messages. So these messages should prompt the worker to run some action which result will be returned to you via a message. Comparing it to other environments, one could think of this as if each Web Worker were a ThreadPool of a single thread to which I send actions. This is fine, but I felt as if there was an scenario that was missing.

My first experiences with threads (in C#, like 15 years ago) involved creating a Thread object and passing to it a function object (a delegate). That code would be run by the thread and the thread would finish. This is quite close to how things work at the OS level with the CreateThread Win32 API. Creating Threads on your own this way is no longer recommended in the .Net world, as thread creation is expensive and we should leverage the Thread Pool. Task.Run provides us with a familiar "interface" (we pass it a delegate to be run), leverages the thread pool and furthermore returns a Task, so we can easily chain the next code to run (via ContinueWith or even better with await).

Let's say that I don't care that much about the code running in the ThreadPool or in a new one, what I really like is the "interface" provided by Task.Run: pass the code to run as a function and await for its result. So, could I somehow replicate it in Javascript? A web worker receiving a function to be run and returning a Promise on which I could await. Hopefully yes, we can do it

There are some ingredients that we have to mix to make this possible:

  • We have to create a Promise
  • We have to create a Web Worker and pass it a function via postMessage. The Web Worker should run this function. We can not directly post a function to the worker, so we'll pass it serialized into a string, and then the Web Worker will run it via eval
  • Once the function is finished, the Web Worker has to resolve (or reject) the Promise

The code for the Web Worker itself is pretty simple, in principle we'll put it in a separate "WebWorkerCode.js" file and pass its url to the Worker constructor

//e is an array with 2 elements: the function in string format and an array with the arguments to the function
onmessage = function(e){
    let fnSt = e.data[0];
    let args = e.data[1];
    
    //we need the () trick for eval to return the function
    let fn = eval("(" + fnSt + ")");
    let workerResult = fn(...args);
    console.log('Posting result back to main script: ' + workerResult);
    postMessage(workerResult);

}

Then we have a class (PromiseWorkerHelper) with a run method. The "constructor" creates a worker that waits for us to post it the function to execute. The "run" method creates a Promise, gets hold of the resolve/reject handlers of the Promise and posts the function to the worker. Once the worker finished with running the function will post a message with the result, that will be received by PromiseWorkerHelper that at this point will resolve the promise.

class PromiseWorkerHelper{
    constructor(){
        //one shot object, we create it and invoke its run method just once
        this.alreadyCalled = false;

        //this.worker = new Worker("WebWorkerCode.js");
        this.worker = this._createWorkerFromString();

        //this is executed when the worker posts a message
        this.worker.onmessage = (msg) => this.resolveFunc(msg.data);
        this.worker.onerror = (msg) => this.rejectFunc(msg); 
        this.resolveFunc = undefined;
        this.rejectFunc = undefined;
    }

   

    run(fn, ...args){
        if (this.alreadyCalled){
            throw "already used once";
        }
        this.alreadyCalled = true;

        let pr = new Promise((resolve, reject) => {
            this.resolveFunc = resolve;
            this.rejectFunc = reject;
        });

        this.worker.postMessage([fn.toString(), args]);
        return pr;

    }

   _createWorkerFromString(){
        let workerOnmessageHandler = function(e){
            let fnSt = e.data[0];
            let args = e.data[1];
            
            //we need the () trick for eval to return the function
            let fn = eval("(" + fnSt + ")");
            let workerResult = fn(...args);
            console.log('Posting result back to main script: ' + workerResult);
            postMessage(workerResult);
        
        };

        let str = "onmessage = " + workerOnmessageHandler.toString() + ";";
        let blob = new Blob([str], {type: 'application/javascript'});
        return new Worker(URL.createObjectURL(blob));

    }
}

The "_createWorkerFromString" private method is a nice addition. Rather than having the worker code in a separate file, we can have it here, create a Blob, create a URL for that in memory object and pass it to the Worker constructor. I learned this trick here

We can run it as easily like this:

function longFormatting(txt, formatCharacter){
    console.log("starting longFormatting");
    let res = formatCharacter + txt + formatCharacter;
    start = Date.now();
    while(Date.now() - start < 1000){}
    console.log("finishing longFormatting");
    return res;
}

function main(){
    document.getElementById("launchCalculationBt").addEventListener("click", async () => {
        console.log("Main.js, inside button handler");

        let txt = "hello";
        let formatCharacter = "---";

        let promise = new PromiseWorkerHelper().run(longFormatting, txt, formatCharacter);
        
        let res = await promise;

        console.log("Main.js, result: " + res);

    });
}

window.addEventListener("load", main, false);

I've put the code in a gist, and you can run it from here (check the debug console for the output).

Notice that we are passing to the run method the function and the parameters to that function, while Net Task.Run receives just the function. In .net if our original function expects parameters we have to create a closure to trap those parameters and invoke the original function with them. In JavaScript, as in the end we have to pass the function as a string to the Worker, the closure is not an option.

Wednesday 1 August 2018

Well Done Denmark

It seems like there's still some hope for those resisting islamisation. Today, August 1st, a law that forbids wearing the burqa or niqab in public spaces has come into force in Denmark. The Scandinavian country joins France, Belgium, Austria, Latvia, Bulgaria... (you can read a listing here) in the fight against intolerance and communitarism.

There are many reasons for banning those disgusting face veils from the public space (security, women's rights, religious neutrality...) but the fundamental reason for me is that the burqa and niquab represent a declaration of war against our Western freedoms and lifestyle. A man forcing a woman to wear the full face veil, or a woman that decides to do so on her own accord, are following a fundamentalist vision of Islam where those who are not Muslims, the infidels, are their enemies, that must be converted, avoided or murdered. Such an interpretation of Islam is not compatible with our Western values, and as such, can not be allowed here. Furthermore, as such a symbol of hatred, they must not just be forbidden from being worn, their sale must be forbidden also. Wearing a burqa or niqab is just the same as sporting a swastika, it must be banned and punished.

For those radical Muslims that consider that not being allowed to hide their faces is discriminatory and "Islamophobic", I have a simple solution, EMIGRATE to a Fundamentalist Muslim country, unfortunately there's a broad list of destinations for your choice... Of course, you can also take with you all those "left-wing feminists" that support you right to wear the full veil, sure they will appreciate the freedom that as infidel women they will enjoy in such countries...