Sunday 26 January 2020

Proxying an Object with sync and asycn Methods

The other day came to my mind the idea of how to intercept asynchronous method calls. I'm talking about JavaScript and the typical case where we use a Proxy and a get trap to intercept all method calls to one object, running some code before and after calling the original method.

First we have to check if the intercepted method is sync or async (we'll just check if it returns a Promise). If it's async, the main issue is with the "after call" action. We have to run this extra code after the async method is completed and before the client receives this result. Well, it's just a matter of adding a .then() call to the original promise, running our code inside this "then", and returning to the client the promise created by "then" (promise that we'll resolve to the value returned by the initial promise). All in all, we can write a proxy that intercepts properly both sync and async methods in an object like this:

let proxiedObj = new Proxy(obj, {
 get: function(target, property, receiver){
  let it = target[property];
  if (typeof it !== "function"){
   return it;
  }
  return function(){
   console.log("before invoking");
   
   //we're not trapping additional calls done from this method, so we invoke the original method via "target" rather than "this"
   let result = target[property](...arguments);
   //let result = it.call(target, ...arguments);
   
   if (result instanceof Promise){
    return result.then(res => {
     console.log("after completion of async function");
     return res;
    });
   }
   else{
    console.log("after completion of sync function");
    return result;
   }
  };
 }
);

There's an interesting point. We could think of using await in the returned function rather than then(), something like this:

  //I can not do it like this, cause with the async I would be returning a Promise in both cases, so for the invoker of a sync function he gets a promise of X rathern than X, so that's not what he's expecting
   return async function(){
   //I'm not trapping additional calls done from this object
   console.log("before invoking");
   
   let result = target[property](...arguments);
   //it.call(target, ...arguments);
   
   if (result instanceof Promise){
    let resolvedResult = await result;
    console.log("after completion of async function");
    return resolvedResult;
   }
   else{
    console.log("after completion of sync function");
    return result;
   }
  };

This will work for asynchronous methods, but will break synchronous ones. As we know when a function is marked as async, the compiler modifies the function so that it returns a Promise that resolves to the value returned by the return statement. So if a client is calling a function that returns a string and we intercept it by means of the above get trap, he will receive a Promise of a string...

I've uploaded it to a gist

Monday 20 January 2020

Constructors

I've been reviewing lately (with some help from: [1] and [2] how default constructors, calls from the derived constructor to the parent one and so on... in both JavaScript and C#, work, and it'll be good to serialize it here.

JavaScript

If we don't define a explicit constructor in our class the compiler will add a default one for us. In a base class it'll just add this:

constructor( ) { }

and in a child class this:

constructor(...args) {
    super(...args);
}

So the child default constructor will call the base constructor passing over all the parameters it has received. This is possible cause in our dynamic JavaScript regardless of the arity defined in a function signature we can call it passing as many parameters as we want, then the function will use them or not.

C#

If we don't define a constructor in a base class the compiler will add a default constructor (a parameterless one). In a derived class, if we don't define a constructor, the compiler will try to add a parameterless contructor that will call the parameterless constructor in the base class. If the base class lacks that parameterless constructor (for example it has one expecting a string) we'll get a compilation error:

There is no argument given that corresponds to the required formal parameter 'a' of 'Parent4.Parent4(string)'

There's an important difference between JavaScript and C#. In C#, if we don't write a explicit call from a explicit derived constructor to the parent constructor, and the parent constructor has a parameterless one (explicit or implicit) the C# compiler will add a call to this constructor (base()). This is different in JavaScript, the compiler won't add a super() call from a explicit constructor, we'll have to add it ourselves, otherwise we'll get an error like this:

ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

If you want to see some code:

JavaScript

class Parent1{
 constructor(){
  console.log("Parent1: " + Array.from(arguments));
 }
}

class Child1 extends Parent1{
 //no need to declare a constructor, the implicit one added by the compiler will call the base one with all the parameters
}

//Parent constructor gets called from the default Child constructor with the parameters list
new Child1("Bonjour", "Bonsoir");
 
console.log("----------------------");
 
class Parent2{
 constructor(){
  console.log("Parent1: " + Array.from(arguments));
 }
}

//I need to explicitly call the Parent constructor (contrary to C# where if the Parent has a parameterless constructor the base() call is atomatically added), otherwise we get an error:
//ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
class Child2 extends Parent2{
 constructor(){
  super(...arguments);
  console.log("Child2: " + Array.from(arguments));

 }
}

C#

    class Parent1{
        public Parent1(){
            Console.WriteLine("Parent1");
        }
    }

    class Child1: Parent1
    {
        //the default parameterless constructor invokes the Parent parameterless constructor
    }

    //----------------------------------
        
    class Parent2
    {
    }

    class Child2: Parent2{
        //it invokes the Parent default, Parameterless constructor (base())
        public Child2(string a)
        {
            Console.WriteLine("Child2");
        }
    }

    //----------------------------------

    
    class Parent3
    {
        public Parent3()
        {
            Console.WriteLine("Parent3");
        }
    }

    
    class Child3: Parent3{
        //No need to explicitly call the Parent constructor, compiler already adds a base() call
        public Child3(string a)
        {
            Console.WriteLine("Child3");
        }
    }

    //----------------------------------


    class Parent4
    {
        public Parent4(string a)
        {
            Console.WriteLine("Parent4");
        }
    }

    //I need to explicitly call the Parent constructor 
    class Child4: Parent4{
    //public Child4(string a)
    //the above does not compile as there's not a parameterless constructor in the base class
    //"There is no argument given that corresponds to the required formal parameter 'a' of 'Parent4.Parent4(string)'"
 
    public Child4(string a): base(a)
    {
  Console.WriteLine("Child4");
 }
}

Sunday 12 January 2020

For Await Of

The other day I came across something I had missed regarding for-await-of loops (the ones for traversing Async Iterables), they also work with Synchronous Iterables!. It's explained here:

for-await-of handles synchronous iterables by converting them to asynchronous iterables. Each iterated value is converted to a Promise (or left unchanged if it already is a Promise) via Promise.resolve(). That is, for-await-of works for iterables over Promises and over normal values.

We can see a simple example:

let cities = ["Toulouse", "Lyon", "Xixon"];

async function* asyncCities(){
		for (let city of cities){
			yield await new Promise(res => setTimeout(() => res(city), 700));
		}
}


async function print(items){
	for await (let it of items){
		console.log(it.toUpperCase());
	}
}

(async () => {
	await print(cities);
	console.log("------");
	await print(asyncCities());

})();

This comes in line with the feature that in javascript we can await for a non-promise value (the runtime will convert it into a Promise by calling Promise.resolve [1]).

This fits perfectly in a dynamic language like JavaScript. We can think of an scenario for example where we can receive either an iterable of cached values, or an iterable that has to retrieve those values asynchronously. The same function can receive one or another itarable and iterate it with for-async-of.

In the other language that I know with a similar feature, C# and its Async Streams, things are much more rigid. The await-foreach loop will only work with IAsycnEnumerables. If we try to iterate with it an IAsyncEnumerator we get a compilation error of this sort:

Asynchronous foreach statement cannot operate on variables of type 'List' because 'List' does not contain a public instance definition for 'GetAsyncEnumerator'.

Even if we were allowed to do this, it would not be much useful. IAsyncEnumerable does not inherit from IEnumerable, so the case that I've just mentioned of a same method receiving either an IEnumerable of cached values or an IAsyncEnumerable that retrieves the values asynchronously, does not apply.

Sort by Multiple Criteria

In Linq ordering a collection by multiple criteria is done by invoking OrderBy with the first criteria and then chaining calls to ThenBy with each additional criteria. In order for the additional criterias to work on the collection ordered by the first criteria, we need a collection that keeps information about which items are equals based on the applied criteria and hence must be taken into account in additional criterias. This is why OrderBy and ThenBy do not return just an IEnumerable, but an IOrderedEnumerable.

In JavaScript we don't have any kind of thenBy method to apply to a sorted array, we just have the Array.prototype.sort method that sorts the array in place, so in order to sort by multiple criteria, we'll have to pass those criteria to the sort method. How? Well, pretty simple, we'll combine these criteria into a single function that we'll pass to the sort method. Let's see the code:

// Factory Function to combine multiple sort criteria
// receives functions representing sorting criteria
// returns a function that applies these criteria 
function sortByMultipleCriteriaFactory(...sortFuncs){
    return (it1, it2) => {
        for (sort of sortFuncs){
            let res = sort(it1, it2);
            if (res !== 0){
                //for this criteria items are not equal (in sorting terms) so no more criteria to apply
    return res;
            }
        }
        return res;
    };
}

So for each pair of values if the current criteria tells us that the items have the same order, we move to the next criteria in the loop, else, we just quit the loop as the other criteria are not relevant for this pair. I've put up a full example in this gist

Friday 3 January 2020

Polymorphic this Types

The other day I came across for the first time with Polymorphic this types. I would say that I've never needed this feature so far (I think I've never designed a fluent interface, at least in a static language), but the sample is pretty clear of how useful it can be when you're using a language where types bring you security but also restrictions. What we get here is that when we are in a derived class and invoke a method of the parent class that returns "this", the compiler understands that such "this" is now an instance of the derived class, not just of the parent class. Notice that in the method signature you have to specify that you return "this":
public add(operand: number): this {
(the typescript compiler won't apply this feature just by seeing that you are doing "return this" at the end of the method.

This said, and given that C# is missing this feature, how can we make a fluent API like the one in the sample work? Using just a simple "casting" with as quickly becomes pretty dirty as we need to do more and more "castings":

 v = (new ScientificCalculator(2)
   .Multiply(5) as ScientificCalculator)
   .Sin()
   .Add(1);
 Console.WriteLine(v.CurrentValue());
 
 //starts to look uglier as we start to add more and more initial parenthesis
 v = ((new ScientificCalculator(2)
   .Multiply(5) as ScientificCalculator)
   .Sin()
   .Add(1) as ScientificCalculator)
   .Sin();
 Console.WriteLine(v.CurrentValue());

A solution that occurred to me and that I think looks a bit better is wrapping the as operator into a generic chainable method. Thanks to Extension methods we can do something like this:

 static class Extensions
    {
        public static T AsType<T>(this object obj) where T: class
        {
            return obj as T;
        }
    }

 v = new ScientificCalculator(2)
   .Multiply(5).AsType<ScientificCalculator>()
   .Sin()
   .Add(1);
 Console.WriteLine(v.CurrentValue());


 v = new ScientificCalculator(2)
   .Multiply(5).AsType<ScientificCalculator>()
   .Sin()
   .Add(1).AsType<ScientificCalculator>()
   .Sin();