Tuesday 28 April 2020

Switch Expressions 2

Last year I did a short write-up about switch expressions, and I have now something to add.

In effect, C# 8 includes this feature, let's see:

var country = city switch
            {
                "Paris" => "France",
                "Berlin" => "Germany",
                "Stockholm" => "Sweden",
                _ => "France"
            };

Nice, but there's something that initially seemed a bit odd to me, the value-switch order. It would seem more natural to me to write country = switch city {. Well, there's one explanation for the order choice, chaining. Thanks to the value-switch order we can chain switch expressions like this:

            return city switch
            {
                "Paris" => "France",
                "Berlin" => "Germany",
                "Stockholm" => "Sweden",
                _ => "France"
            } 
            switch
            {
                "France" => "French",
                "Germany" => "German",
                "Sweden" => "Swedish",
                _ => "French"
            };

In my post from last year I had shown that though JavaScript lacks switch expressions we could write similar code via object literals like this:

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

Something missing in the above code is a default case. In order to manage that I've generalized the above code into a function (switchFn):

function switchFn(value, body, defaultFn){
 let caseFn = body[value];
 return caseFn !== undefined
 ? caseFn(value)
 : (defaultFn)
 ? defaultFn(value)
 : null;
}

To be used like this:

stringValue = "ONE";
numValue = switchFn(stringValue,{
     "ONE": () => 1,
     "TWO":  () => 2,
     "THREE": () => 3
 },
 () => 10
);
console.log(`numeric value for ${stringValue} is ${numValue}`);

We can chain switchFn calls like this

stringValue = "ONE";
position = switchFn(
 switchFn(stringValue, 
 {
  "ONE": () => 1,
  "TWO":  () => 2,
  "THREE": () => 3
 }, () => 0),
 { 
  1: () => "First",
  2:  () => "Second",
  3: () => "Third"
 }, () => "Unknown"
);
console.log(`position value for ${stringValue} is ${position}`);

The above code is not too immediate to read. If we curry (via lodash) the switchFn function, apart from doing the selection logic reusable, we do the chaining a bit more clear. Notice that as we want to fix the second and third parameter to the partially applied function that we obtain, and keep the first parameter "free", we are using the _ placeholder for it (it's something that I have just learned):

let curriedSwitch = _.curry(switchFn);
let numberSelector = curriedSwitch(_, 
 {
  "ONE": () => 1,
  "TWO":  () => 2,
  "THREE": () => 3
 }, () => 0);

let positionSelector = curriedSwitch(_, 
 { 
  1: () => "First",
  2:  () => "Second",
  3: () => "Third"
 }, () => "Unknown");

stringValue = "TWO";

positionValue = positionSelector(numberSelector(stringValue));

console.log(`position value for ${stringValue} is ${positionValue}`);

Additionally, we can compose the selection functions with the lodash flow function.

let positionFromStringNumber = _.flow(numberSelector, positionSelector);
stringValue = "THREE";
positionValue = positionFromStringNumber(stringValue);
console.log(`position value for ${stringValue} is ${positionValue}`);

Monday 13 April 2020

What keeps the Application running

Thinking a bit about the JavaScript Event Loop I realised of an interesting difference between 2 pieces of similar code in JavaScript - Node.js and .C# - Net.

Let's say I want a program that just does a http GET call and prints the retrieved string.

In JavaScript - Node we would write this:

async function getAndPrintText(){
    console.log("inside getAndPrintText");
    try{
  let response = await fetch("http://localhost:8080");
  if (!response.ok) {
   throw new Error('Network response was not ok');
  }
  let txt = await response.text();
  console.log("txt: " + txt);
 }
 catch(ex){
  console.log("something went wrong: " + ex.message);
 }
}

console.log("Started");
getAndPrintText();
console.log("After invoking GetAndPrintText");

//Output:
Started
inside getAndPrintText
After invoking GetAndPrintText
txt: "the returned html here"

Notice that I've not put an await for the getAndPrintText() call, so the "After invoking" is printed right after the call; before we obtain the result. That console.log is the last visible line in our script but anyway somehow the application waits for the http call to complete before it exits, how?
Well, it's the Event Loop. Node runs our script and then enters in the event loop to check for events coming from the asynchronous operations (and timeouts). The call to fetch() will be registered so that the event loop will be alive until it's completed.

The thing is a bit different in C# and .Net. Translating the above code to C# we would have:

    class Program
    {
        static HttpClient client = new HttpClient();

        static async Task GetAndPrintText()
        {
            Console.WriteLine("inside GetAndPrintText");
            try
            {
            HttpResponseMessage response = await client.GetAsync("http://localhost:8080/index.html");
            response.EnsureSuccessStatusCode();
            string responseBody = await response.Content.ReadAsStringAsync();

            Console.WriteLine("text: " + responseBody);
            }
            catch (Exception ex)
            {
                Console.WriteLine("something went wrong: " + ex.Message);
            }
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Started");
            GetAndPrintText();
            Console.WriteLine("After invoking GetAndPrintText");
        }
}

Running the above the program will finish without printing the retrieve http content. The main application Thread finishes after doing the Console.WriteLine, and there's nothing to keep the application alive. A thread from the I/O TreadPool has been set to wait in the IOCP for the client.GetAsync to complete, but this is a background thread, so it won't keep the application alive if the main Thread reaches its end. You can read more about IOCP in this previous post

For the application to wait for the http call to complete we have to add an await in our Main (and turn it into an async Main), like this:

        static async Task Main(string[] args)
        {
            Console.WriteLine("Started");
            await GetAndPrintText();
            Console.WriteLine("After invoking GetAndPrintText");
        }

I already talked about async Main in the past. The main application Thread will be waiting in the hidden, compiler-generated application entry function for our async Main to complete, and our async Main is waiting for the http call. That's how the application is kept alive, nothing to do with an Event Loop as in Node.js

Saturday 11 April 2020

Some Linux Tricks

There are some basic linux tricks that I occasionally need and that I'd like to share:

  • Passing the output of a program/command as argument to another program/command Notice that when using pipes "|" we are passing the stdout as stdin to second program. What I mean here is passing it as argument. Let's say we have a file that contains the path to a folder which contents we want to list. We have 2 ways to achive this, with the $() "operator" or with the xargs tool that seems to be installed in most modern systems:
    ls $(cat fileContainingPath.txt)
    cat fileContainingPath.txt | xargs ls
  • Find what application has a file open (one of the main reasons to make me launch SysInternals Process Explorer in Windows). It's that simple as doing:
    lsof filename
  • See the shared libraries (.os files, equivalent to Windows .dlls) loaded by a process. We'll use again lsof, this time like this:
    lsof -p PIDofTheProcess | grep '\.so$'
  • Find to what process does a window belong to* (this is another of the main reasons for me to launch Process Explorer in Windows):
    xprop | grep PID

Sunday 5 April 2020

The French Connection

I've recently watched 2 really excellent crime films (or should I better call them "film noir"? well, I keep that for the experts). The French Connection and French Connection II are inspired by the real drug trafficking scheme operating between the 1930's and 1970's and that transported heroin from Turkey to France and from there to the USA. The 2 central cities in this trafficking were Marseille and New York.

The first film (from 1971) is really good, but the second one is just outstanding. The first installment has some scenes shot in Marseille but most of the story happens in New York. The second installment is 100% shot in Marseille. Given my love for the gorgeous Mediterranean city one can think that it plays a role in my predilection for the second film. Well, for sure it does, but anyway the story in the second film is much more aggressive, gripping, even extreme (the detective striving to overcome the heroin addiction forced on him by the gangsters). It also has some funny moments with the culture shock of the New York detective experiencing France.

For a Marseille lover like me that only knows the city (pretty well I think I can say, I've been there many times) since 2014, the images of 1975 Marseille are really interesting. On one side there are so many familiar things, the forts and the Vieux Port, some of those high-rise buildings that emerged in the 50's - 60's... On the other side the ugly port facilities right below the cathedral have disappeared (replaced by the rather interesting EuroMed development, indeed Marseille has become along with Bilbao one of the most reknown examples of tranformation of an ugly centrally located industrial area into a trendy, architecturally noteworthy space loved by its cicizens).

One obvious negative change that clearly slaps you in the face is the change in the population make up. In those images from the 70's one perceives a European society (where there is the normal and healthy gradient of skin colors from "very white" to "very black", but everyone seems to share a same culture). This has little to do with the current city where estimates say that more than a 30% of the population is Muslim, and even worse, most of them consider themselves Algerians rather than French...). The criminality levels have totally changed. In the 70's you had these criminal gangs importing, cooking and exporting heroin and for sure there was violence among them and against the police, certainly the drug addicts posed a problem... but that's nothing compared with the current massive violence exerted by the Islamists (mostly cultural violence, but also physical violence) and with the neighbourhoods controlled by the drug dealers and/or the Islamists...