Pages

Friday, October 31, 2014

How does Hacklang work

I must admit that I am not a fan of Facebook. Unlike 90% of the world, I do not, and have no intention of, ever owning an account. The list of reasons are long, and some of the things on that list have more to do with the people using it, rather than the service itself. Something just happens to normal people when entering the website, it's like watching one of the many talk-shows and reality programs on TV.

But although this article is about Facebook, it is not about the service that they are most famous for. This article is about a small extension to the PHP programming language, created by Facebook, called Hack, and the related Virtual Machine called HHVM. If you are a PHP programmer and either do not know about this or if you have not yet tried it, then I'll suggest you have a look at it. This extension provides features that PHP should have had ages ago. This article will not get into what Hack and HHVM is, I'll suggest that you visit the website http://hhvm.com if you are not already familiar with it.

What this article will focus on, is how HHVM/Hack acts. PHP is normally a dynamic typed language, but Hack introduces static typed features, and at the same time keeps compatibility with regular PHP. It's like mixing oil and water, and actually making them mix. The way it works, is that the VM mostly upholds the rules of PHP while the type checker upholds the rules of Hack. In other words, you can without any issues execute code that is not acceptable by the rules of static typing, but you will get errors when parsing it through the optional type checker. The errors from the type checker can also be removed by changing how strict it should be, which can be set pr. file. This allows you to mix dynamic typing and static typing, and still be able to use the type checker on the strict files.

class MyClass {
    public function test1(): void {
        $this->internal( Map{"key"=>1} );
    }

    public function test2(): void {
        $this->internal( Vector{true} );
    }

    private function internal(Map<string, bool> $param): void {
        // Code ...
    }
}

If we execute test1() from a browser, HHVM would not generate any errors. It would simply allow it. If we execute test2(), HHVM would break the request with an error. The reason for this is that HHVM follows PHP rules, which does not provide any generics. PHP however does allow one to define parameter type, which is the only thing that is being monitored for. The type checker on the other hand, would print a lot of errors here, first complaining about the wrong generics types in test1() and then complain about the wrong data type in test2().

class MyClass {
    public function test(): bool {
        return 1;
    }
}

The same applies for the return type. The above example will not conflict with HHVM. The only way to catch this problem, is by the type checker.

So the way that Hack is able to work along side PHP, is that the VM does not enforce any Hack rules. If you want to check your code for type safety, you will have to check it using the type checker. For the most part this will suffice. But the type checker is still a work in progress, and it does contain a few bugs.

class MyClass {
    public function test1(): void {
        $this->internal(Map{"key"=>new Map(array(
            "key"=>1
        ))});
    }

    public function test2(): void {
        $this->internal(Map{"key"=>Map{
            "key"=>1
        }});
    }

    private function internal(Map<string, Map<string, string>> $param): void {
        // Code ...
    }
}

Both test1() and test2() will parse the exact same value to internal(). However the type checker will only report an error on test2(). The wrong generics type in test1() will not be caught.

No comments:

Post a Comment