Thursday, 18 January 2018

Juger les Djihadistes

The excellent editorial by Riss (La-bas si j'y suis) in last week's Charlie Hebdo reminded me of another stupid debate happening now in France. It deals with whether the Yihadists of French nationality that have been captured in Syria or Irak should be judged in those countries or should be brought back to France to judge them here. The idea is that a French citizen that joins a terrorist organization is already committing a crime under the French law and hence can be judged in France. OK, that sounds correct, but as he has committed crimes (murdering, raping...) in another country for sure the other country has the right to judge him according to its laws. This criminal is already arrested in the country where he has conducted his worst crimes, so for sure he has to be judged there. If hopefully he is sentenced to capital punishment or a life sentence, that's all, if he were setenced to less than that then it would make sense that once he has finished his sentence he is brought to France and judged and condemned in France. Well, indeed that would be a very bad idea, because he would live a few years in prison at the expense of the French tax-payer and then he would be free in our soil, willing to radicalise others and attack again... The best option would be to deprive these beasts of the French nationality and never let them back.

Unfortunately, those who want to bring these bastards back in France have something completely different in mind. They want to bring them back in France now, so that they can scape the sentence in Irak/Syria (where hopefully and most likely they will be executed as they deserve) and be judged by the soft French laws that will just sentence them to staying a few years in a luxury prison where they will be able to radicalise other immates... This is what some stupid "Human Rights" organizations (you can read what I think about these "humans" here), families, Islamist scum and the the criminals themselves think.

So these criminals that hate France and the French society so much, that do not recognize its institutions and have pissed and shit on them for years (first as delinquents in their "quartiers", then trying to spread the Islamist disease, and then by "representing this country" killing innocents and raping...) now suddenly want to return "home" and adhere to the French law... obviously because they want to scape death and get the soft sentence that the lax and weak French Justice system (or any other Western European System) would give them... In the end these pieces of shit are neither so "valerous" as they claim or so "crazy" as the IslamoGauche tries to sell us as a way to excuse Islam... I don't know what "the book" says about it, but maybe being captured and executed does not grant these "warriors" with the promised 72 virgins...

Saturday, 6 January 2018

Devirtualization

When I came across this article a few weeks ago it quite caught me by surprise. They talk about a kind of optimization that I was not aware of and it has helped me to refresh and regain some knowledge, so I'll write down some notes here for further reference. I'll be talking about C#, but the most generic part applies the same to Java (and other static, class based, languages).

Virtual calls are resolved at runtime. Objects point to a VTable, where there is an entry for each virtual method in the class. This way the correct method, Base.Method or Child.Method is called depending on the runtime type of the object. When invoking a method through an interface the thing gets a bit more complicated. As a class can implement multiple interfaces it's no longer a matter of going always to the n slot in the VTable. Years ago I managed to understand how interfaces and their VTables were managed in .Net, but I no longer remember how it worked, and indeed I can read that it has changed (huge article) in the last implementations of the CLR. I'm quite impressed cause it reminds me a bit of how things work in Java with "dynamic"... well, all in all let's just stick with the idea that calling a (virtual) method through an interface is a bit slower than calling it through a class, and of course both are slower than calling non virtual methods, where the compiler can put a direct call rather than the indirection levels involved by the VTables. There are multiple articles about this. Delegate calls are also slower than direct calls, what I don't fully understand is why they are slightly slower than virtual calls (based on some benchmarks), I would say that the levels of indirection involved are just the same.

In those old days when I used to check and even write some IL code I found it odd that calls to instance, non virtual methods are done through the callvirt IL instruction (as for virtual methods) rather than using the call IL instruction (that is used mainly for static methods and structs). The reason for this is that callvirt provides an additional feature, it checks whether the object is null, which is obviously unnecessary for static methods, but much needed for instance methods, regardless of whether they are virtual or not. When the JIT translates a callvirt opcode into real machine code, it will for sure add the null check, and depending on whether the method is virtual or not it will emit code to use the VTable or will insert a direct call to the method address, as explained here. There is another case when the C# compiler can skip the null check and emit a call rather than a callvirt, when the method call is immediately after the object creation, i.e. new myClass().method();

Related to all this I can remember how one friend of mine used to seal his classes due to performance benefits, honestly, I never put much interest in such habit of him. I can read now that sealed classes were not created with performance in mind, but they can incidentally provide performance benefits, due to devirtualization preciselly.

The JITter will sometimes use non-virtual calls to methods in sealed classes since there is no way they can be extended further.

If we have a sealed, child class that either overrides or keeps the original base virtual methods, for the calls to that method done through the child class (not through the base one), given that we are preventing further inheritance we can be sure that the method to be called is the one in the child class, so there's no need to use the VTable at all. The JIT takes this into accout and generates native code that calls the method directly. It's explained in the first linked article:

  • Calling virtual methods on a sealed class.
  • Calling virtual methods on a sealed method.
  • Calling virtual methods when the type is definitely known (e.g. just after construction).

Thursday, 28 December 2017

Je suis Charlie, Plus que Jamais

(I am Charlie, more than ever) If you read this blog I guess you know I love Charlie Hebdo. Those who have never read it will think about it as an irreverent assemblement of cartoons, for me, much above that, they are an amazing set of editorials, interviews, research reports and columns, one of the few remaining works of real jounalism. I won't say that I always fully agree with their cartoons (for sure I 100% subscribe all those critizising religions, but some of those that deal with dead or sickness are sometimes not to my taste), but all in all Charlie Hebdo represents for me Resistence, resistence to the Islamisation of Europe and to the rise of other far-right movements, and the resistence to abandon our believes in an inclusive, multicolor and open society.

This year I can think of at least 3 editorials by Riss that have been just extraordinary, the one about the Islamist attack in Barcelona (that came with the outstanding "Islam, religion of peace... eternal" cover), the one attacking the separatist maphia in Catalonia, and the one before the second round of the French presidential elections. Regarding the cartoons, one of my favorites was a small one about the Islamist attack in Marseille (unfortunately I can not find it now), and for sure I loved the ones about the Tariq Ramadan pig.

I found bad tasted the cover right before the dead of Johnny Halladay. I have a particular respect for illness, so I don't like joking about it. On the other hand, after Johnny's death Riss wrote something really beautiful. He reflected on how Charlie had never been particularly kind to Johnny (I have no opinion on this guy, so I can not say how much criticism he deserved), but anyway, after the Charlie Hebdo massacre Johnny decided not just to be Charlie, but also singing in the hommage. As Riss said, he really didn't have to do it, but he decided to do so, and for that they appreciate it.

There's one weekly column that is sometimes amazingly good. It's written by Philippe Lanconn, who has such a beautiful way to write about life, death, the passage of time and its effects on us. This journalist survived the attack but was badly hurt. His jaw got basically destroyed and he has undergone multiple surgeries after that (and the healing process has not finished yet at all). His columns talk very often about it, about the pain, about the recovery, about how that day changed his life in so many ways (not just for the physical effect of his injuries, but for the moral effect of the lives that were stolen that day), other times he talks about completely different topics. There was one column after Fidel Castro's death that absolutely impressed me, "the third Death of Fidel Castro". Basically this was the third time Philippe was writing an article about Castro's death, as he had already been asked to write articles in 2 previous occasions years ago, when Castro was just about to die. From his articles this year there are 2 closing sentences that I think will remain with me for the years to come.
One of them said something like (I'm in Asturies, so I don't have the magazine with me) "You feel young when there are others that depend on you, you realise that you've got old when now it's you who depends on others".
The other one closed his column from last week, where he talked about the death of Johnny Halladay, and is such a beautiful statement on how some things can bring back memories and parts of our lives that seemed so far away "Une chanson, quoi qu'elle vaille, reveille des morts qu'on a en soi" (One song, whatever it's worth, wakes up the dead that we have inside).

Thursday, 14 December 2017

Lisbon is Booming

I was lucky to live in Lisbon for a couple of months some years ago thanks to a job assignment. I liked the city a lot, and I've gone back as a tourist a couple of times since then, the last time just a few weeks ago. My first time there I enjoyed the city a lot, but I would not have put it in my cities top, at that time I had a sort of obsession with Eastern Europe, and I think Lisbon, while very beautiful, did not feel exotic enough to an Asturian . It's interesting that years later, with the personal evolution brought up by having travelled quite a bit more, having lived for quite a while in another country and just by the passage of time... I've come to consider Lisbon fascinating and a real top city.

It's clear that I'm not the only one, cause the city is booming. When I was there in 2008, just before the start of the crisis, the city center was littered with abandoned buildings and others that while still inhabited where in a total state of disrepair. Now many of those buildings have been totally refurnished (almost rebuilt in many cases) and many more are being rehabilitated (when you enjoy the views from any of the nice viewpoints you'll see construction cranes everywhere due to these intensive rehabilitations). Most of these works are being done by international real state firms targeting foreign customers (the advertisements are mainly in English), so seems like many foreigners are buying, either because they are moving there themselves (living, second residence?) or for renting to others that will move. The city is succeeding in atracting start-ups and creative minds, transforming abandoned factories into incubators, coworking space and so on (the very popular LX factory seems to have been just the beginning

I'll share my reflections about why I think so many people want to live (full or partial time) in the city now. Of course the availability of space in those previously abandoned factories is essential for those wanting to start a business, but there are many formerly industrial cities that have now this kind of availability (to a greater or lesser extent), so which are the other factors that make Lisbon more attractive? Bear also in mind that while I guess that rentals for these work spaces will be cheap, this is not the same for (either for buying or for renting) apartments. What I saw in the window of some real state agency quite shocked me, prices seemed more expensive than France (excluding Paris, of course)

As I said before, the city is very beautiful and charming, but hopefully this is common to so many European cities. There's an essential factor in putting one city out of the rank of "nice to live" places. I explained it here. I'll repeat again how totally absurd (to the point of offensive) it felt to me when time ago I watched a program on TV saying that Warsaw planned to rival Berlin in attracting "creative guys". I think a free and open society is essential for a creative and open mind to consider to join that society, and Eastern Europe is, in general terms, too conservative, religious, nationalistic and xenophobic to be considered attractive. Whatever beautiful the city center of Warsaw (with its cute rebuilt and the new, nearby and shiny skyscrappers), Bratislava, Budapest (and its decadent charm)... could be, when you see bastards attacking the gay pride parade, or demonstrating against any kind of (non-white, blond and blue eyed) immigration... one feels more like putting them out of the European Union than like moving there... Portugal is a normal Western country, some people are more progressive, some are more conservative, but the overall feeling is good (indeed it shares with Spain the honour of not having any Far-Right political party with any significant strenght). So if other conditions are met (and I think they are), it could rival Berlin.

With Eastern Europe (and maybe the Baltic countries also) totally out of the equation. Let's think about other pros on the Lisbon side when compared to other big European cities:

Urban Architecture (from before the 40's) Lisbon architecture is quite unique, with all those buildings with facades covered in tiles. For sure you can not compare it to the wonders of French architecture, so let's say it's on pair with the architecture you'll find in Germany, Belgium, Netherlands, Danmark... but while you can draw more or less similarities between the constructions in these countries, those of Lisbon are totally specific to Portugal. On the bad side, most modern architecture in the city is of no particular interest (and you even have some ridiculously ugly things like the Amoreiras Towers).

Life cost is particularly important if you're planning to move somewhere with a start-up, to work from home, to retire or to live part-time. In those cases your salary is probably not adapted to the place where you are going to live, so you'll like to find a place where these costs are not higher than in your home country. This means that if you don't have a Parisian salary, moving to Paris (the most beautiful city in the world) can be very painful. Same applies to Copenhagen, Amsterdamn... As I've said the high prices of flats in Lisbon quite surprised me, but food, public transport... are in the normal to low spectrum.

Weather. For sure the weather in Lisbon is nice. Sunny and warm most of the year, it rains enough to have a "sufficiently green" landscape for most of the time (so this beats any place in the Spanish Mediterranean). I guess I would miss to go below cero a couple of days per year, but not big trouble. By the way, you have way too many kilometers of beach a step away from the city, and related to this, did you know that there's a good deal of Brazilian immigration in Lisbon? This has to mean that you'll find Brazilian girls on the beach!!! Other than that, if you're into surfing, you have plenty of good spots also.

Diverse life quality factors: Lisbon is a "multiracial" city. You'll have black people from the former colonies, an East-Asian community... Not such a mixed society like other parts of Europe, but for sure much more than Northern Spain. Public transport is good and the airport has cheap flights to almost any other corner of Europe (and though the Metro system covers only some parts of the city, one line will take you to the airport in no time for less than 2 euros!) The city core (the 1/2 million people part) is relatively dense and compact, so no crazy distances between the most interesting areas. Portuguese sweets are pretty good, and coffee is absolutely delicious and cheap. Lisbon also spots some amazing museums. One drawback is that due to it's hilly nature the city is quite bike unfriendly.

These factors explained, there's one city that I love and that indeed reminds of Lisbon in several ways, Marseille. Marseille is amazing, probably one of the most underrated cities that I can think of. The geographical frame of the city is fascinating (better than Lisbon maybe), there's amazing architecture, both old and new, the weather is nice, the beachs are nice and you are 3 hours far by train from Paris. For being France it's a cheap city (flats are cheaper than in Toulouse of Bordeaux), and being France you live in an open and mixed society. Indeed, during my third visit to Marseille it struck me that it could turn into the Mediterranean Berlin, but it seems it's not going to be like that. So why?

Well, the huge advantage of Lisbon over Marseille is not specific to Marseille (and the particularities of its bad reputation), it applies to basically any Western European city/country (save for Portugal, most of Spain and to a lesser extent Italy and Greece). So here it goes, the part that will make this post worth reading if you have managed to get until here... There are no Muslims!!! I mean, the Muslim population is minimal. I did not see any veiled woman in the whole weekend. I did not see any motherfucker with the salafist dress code. I did not see Maghrebian teenagers with their fucking "racaille uniform" comitting petty crimes while waiting to be radicalised. I did not see new mosques sprouting on every corner like poisonous mushrooms (I just remember having seen a big, "historic" one back in 2008. I did not see any fucking poster or sticker against "Islamophobia"...

For sure there are Muslims in Portugal (you even have them in my isolated Asturies...), but the fewer they are the more likely it is that they will try to integrate rather than creating a separate community intending to live by medieval rules and intendending to impose them on others... I have Muslim friends that I really appreciate, but the existence of "nice ones" (even very nice ones) that enrich our societies, can not be a distraction that prevents us from seeing the dangers of the "not good ones" (that as years go by are becoming the norm) and the "very bad ones".

Right now the Muslim problem in France, Belgium, Germany, Sweeden... is still not so dramatic like for forcing you out of the country (unless that you are Jewish) because Muslims are not so many, but you know that they tend to have many kids and that new ones continue to come... so it's clear that in 20 or 30 years they will be the majority in some cities, and some countries will be in the verge of religious war (because I'm pretty sure that many of them won't want to integrate at all). It's already been some time that when I read about one city one of the first things that I do is checking the percentage of Muslim population, to get an idea of to what extent it can be a good place to live. I think more and more people will begin to look into this kind of statistics very seriously, to prepare the scape for when the situation in their cities goes out of control. Lisbon looks like a really good refuge.

Few days after coming back from Lisbon a report showed up in the news with some terrifying (but totally in line with what I expected) predictions about the number of Muslims in Europe by 2050. There are 3 different scenarios depending on the strength of the migration trends, but the worst (and most likely to me) is just devastating. Well, at least France will no longer be the most islamised country in Europe, it will be surpassed by Sweeden (that will "enjoy" of a 30% of Muslims!!!) and Germany. Also the situation in Spain will not be too bad (and I'm completely sure that in Asturies the percentage will continue to be very low).

I had just read some summaries and had not checked the original full report until now. It's amazing to see how correct my "street feeling" was, Portugal is now by far the country in Europe (excluding Eastern/Baltic countries) with the lowest percentage of Muslims, only a 0.4%!!!, and the prediction for 2050 (even in the worst case scenario) is only 2.5%. We've talked a lot about refugees in the last years (war refugees, economical refugees, climate refugees in the future...), n a few years probably we'll have to add a new group to the list, atheist/Christian Europeans becoming "religious refugees", moving from their Islamised cities to the last remaining "normal" countries/regions in "non-conservative" Europe (Portugal, Northern Spain...)

Saturday, 9 December 2017

Lambas vs Arrows

I pretty like that anonymous functions via arrow functions in Javascript use the same syntax that anonymous methods (that involve the creation of delegates) via lambda expressions and statements in C# (=> rather than -> in Java). Notice that the C# Expression Bodied Members about which I wrote some time ago, are a different story, they do not involve delegates and indeed are not anonymous.

Apart from the common syntax, there are some differences and similarities that I'd like to remark

C# lambdas

  • They can be async and contain await:

    Func<string, Task<string>> asyncFn = async (txt) => {
                    Console.WriteLine("before");
                    await Task.Delay(2000);
                    Console.WriteLine("after");
                    return txt.ToUpper();
                };
    

    but they can not contain a yield. So can not be used for Iterator methods. This code:

    //error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression
                Func<IEnumerable<string>> IteratorFn = () => {
                    yield return "A";
                    yield return "B";
                };
    

    will throw this compilation error: error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression

  • They can be immediately invoked, but you need to provide the type of the delegate that you are creating. So this will fail to compile:

    //basically the compiler can not work out the delegate type to be created
    string result = ((string txt) => txt.ToUpper())("hi");
    string result = ((string txt) => txt.ToUpper()).Invoke("hi");
    

    but this verbose code will work:

    string result = ((Func<string, string>)((txt) => txt.ToUpper()))("hi");
    result = new Func<string, string>((txt) => txt.ToUpper())("hi");
    Console.WriteLine(result);
    

    The reason why it fails in the first case is that the compiler can not infere the Delegate type that it has to create. It's well explained here.

  • Lambdas can be recursive. Thought they are anonymous we can recursively invoke them by using the name of the variable it has been assigned to and that has been trapped in a closure. The odd thing is that the variable has to be declared before, in a separate line from the assignment).
    So while this does not compile (Use of unassigned local variable Error):

     Func<string, int, string> recursiveExpand = (txt, n) => {
      if (n == 0)
                        return "";
                    if (n == 1)
                        return txt;
                    return txt + recursiveExpand(txt, --n);
                };
    

    This will compile fine

    Func<string, int, string> recursiveExpand = null;
                recursiveExpand = (txt, n) => {
                    if (n == 0)
                        return "";
                    if (n == 1)
                        return txt;
                    return txt + recursiveExpand(txt, --n);
                };
    

JavaScript arrows

  • Same as in C# they can be async and contain await:

    let asyncFn = async (txt) => {
     let res = await new Promise((resolve, reject) => setTimeout(() => {
      resolve(txt.toUpperCase());
     }, 3000));
     console.log("processing done");
     return res;
    };
    

    but they can not contain a yield. So can not be used for generator functions. In Javascript a generator function has to be defined with function*, you can not define it with *(). It seems the reason for this is simply that the ES6 designers did not feel this feature worth the effort it would need to be implemented.

  • Arrows can be immediately invoked. This code will run fine:

    let salesSeason = true;
    let obj = {
     name: "Soumission",
     price: (()=>{
      let basePrice = 400;
      if (salesSeason){
       return basePrice - (basePrice * 0.10); 
      }
      return basePrice;
     })()
    };
    console.log(JSON.stringify(obj));
    
  • You can define recursive arrows with no need to declare the function variable in a separate line.

    let recursiveExpand = (txt, n) => {
     if (n == 0)
      return "";
     if (n == 1)
      return txt;
     return txt + recursiveExpand(txt, --n);
    };
    console.log(recursiveExpand("A", 3));
    

Saturday, 2 December 2017

TypeScript Typing

I have to admit that I'd never had any particular interest in JavaScript "superset-style" languages. I've loved JavaScript since I first understood how its base features: prototypes, object expansion and closures worked, and as over the years it has been getting more and more features, I'd never seen the point of moving to one of these "compile to javascript" languages (CoffeeScript, TypeScript...). With this in mind, my only reason to learn TypeScript seemed to be that it's becoming almost compulsory in some environments.

Well, I have to say that I'm amazed. The first beautiful surprise is that as it incorporates all the last-generation ES features, you can just use it as a "javascript version X" to "javascript version X-n" compiler. In that sense it's a nice replacement for Babel.js. It's interesting for example to see the different compiled code of a source that uses async/await. Compiling to es2016 will use a generator, compiling to es2017 will directly use async/await. Apart from this, some people will just use it as if it just were a sort of statically-typed Javascript.

This statically-typed vision is pretty limiting. You can use the language like that if you want, but indeed the "typing discipline" used by TypeScript is much more than that. You'll read in several places that TypeScript uses Duck Typing, well, from my understanding this is not correct, it uses Structural Typing. Even the TypeScript documentation does not seem to care and uses both terms as synonymous here, so I'll try to explain how I see the difference between both terms. It's normally said that Structural Typing is Compile-time Duck Typing, but I think the thing is a bit more complex. This article quite a bit of light on it.

Duck Typing. Duck Typing (like in JavaScript) only cares about the properties or methods that you are accessing (or will be accessing) at runtime. You don't define contracts (specify the type of an argument or variable), you just try to access to a property/method and if it fails you get an error. This is normally done at runtime and that's why we associate Duck Typing with dynamic languages, but it seems there are languages which compilers can do these checks at compile time: C++ and D templates

Structural Typing. This has been a pretty interesting discovery for me. You define contracts (for example the type of arguments to your method) and these contracts are checked at compile-time. In TypeScript you define these contracts via classes, interfaces or just via inline type definitions. The important thing is that contrary to what is done in C# or Java, in order to verify that contract the compiler will not check if the object is an instance of a class in which type hierarchy you can find the class or interface of the contract (this is called nominal typing, because you are checking type names). What the TypeScript compiler does is checking Type compabiliby by checking the shape (structure) of the object with the shape defined by the class or interface. If the shape matches (the object has the requested methods and properties), the contract is fullfilled, regardles of the names of the types in that object type hierarchy.

An interesting point is that with runtime Duck Typing a calling a function passing it the same object could succeed of fail depending of other factors, for example in this JavaScript code the first call works fine, but the second one throws an exception:

function getTax(item){
 if (salesSeason){
  return 0.10 * item.getSalesPrice(); 
 }
 else{
  return 0.10 * item.getPrice(); 
 }
}

var salesSeason = false;
let item = {
 name: "black jeans",
 getPrice(){return 21;}
};
getTax(item);//Works fine

salesSeason = true;
getTax(item); //throws exception, TypeError: item.getSalesPrice is not a function

However, in this TypeScript code Structural Typing will make the compiler give us errors for both calls:

interface ISalesItem{
 getPrice(): number;
 getSalesPrice(): number;
}

function getTax(item: ISalesItem){
 if (salesSeason){
  return 0.10 * item.getSalesPrice(); 
 }
 else{
  return 0.10 * item.getPrice(); 
 }
}

var salesSeason = false;
let item = {
 name: "black jeans",
 getPrice(){return 21;}
};
getTax(item); //compiler error

salesSeason = true;
getTax(item); //compiler error

Just to end this post, another beautiful idea in TypeScript is that the compiler was designed since its inception with a Language Service layer. I guess it was a quite natural decision for Anders Hejlsberg, that at that time had been working very hard on Roslyn.

Sunday, 26 November 2017

AsyncFunction and GeneratorFunction

Since ES6 not all JavaScript functions have the same behaviour. Depending on whether they have been created using the function statement, via the method definition sugar inside a class or as an arrow function they will spot different features. You can read about it here, but basically, arrow functions can not be called as constructors and use a static, lexical this; methods (created via method definitions) can not be called as constructors; super can only be used inside methods...

Anyway, I thought that in spite of having different features all function objects where directly instances of Function but I've found out that this is not the case, and we have 2 additional function types (both inheriting from Function): AsyncFunction and GeneratorFunction. When you define and async function, either directly as a "normal" function, via the method syntax or as an arrow function, you are creating an instance of an AsyncFunction, and when you define an async method, as a "normal" function or via method syntax (you can not use arrows to create generators), you are creating an instance of a GeneratorFunction. You can run this code to see that I'm not lying.

class Person{
 constructor(){
 }
 
 sayHi(){
 }
}

function sayBye(){
}

let saySomething = (msg) => console.log("saying: " + msg);

function* myGeneratorFunc(){
 yield "hi";
}

async function myAsyncFunc(){
}

console.log(Person.constructor.name);

console.log((new Person()).sayHi.constructor.name);

console.log(sayBye.constructor.name);

console.log(saySomething.constructor.name);

console.log("-----------------------");

console.log(myGeneratorFunc.constructor.name);
console.log(myGeneratorFunc.constructor.constructor.name);

console.log(myAsyncFunc.constructor.name);
console.log(myAsyncFunc.constructor.constructor.name);

console.log(myGeneratorFunc.constructor.constructor === Function);
console.log(myAsyncFunc.constructor.constructor === Function);

/*
Function
Function
Function
Function
-----------------------
GeneratorFunction
Function
AsyncFunction
Function
true
true
*/

And as I said above both function types inherit from Function (xxx.constructor.constructor === Function)