Showing posts with label Tutorials. Show all posts
Showing posts with label Tutorials. Show all posts
Saturday, August 30, 2014
Asynchronous Programming in Hack - Example Code

Asynchronous programming allows a script to run multiple tasks in parallel. These tasks are usually input/output operations that rely on operations that are run by separate servers or other OS processes.

Traditionally PHP executes those tasks and waits for them to finish before it returns the control to your script. This is called synchronous programming. Also, PHP has limited support for asynchronous programming, and it does not provide a clean and consistent solution.

With synchronous programming each task can only be started after the previous task has finished. Imagine a script that collects information from different sites. Each one will hold your script for as long as the servers take to respond. Thus, synchronous programming is often a waste of performance.

Hack made it easy to do asynchronous programming cleanly, and also without the pain of callbacks used by JavaScript solutions. It introduced the async keyword which you can assign to functions to tell that it can be executed asynchronously. There is also an await keyword, which is used to suspend the execution of the code that follows the statement, even if it is doing something asynchronous like waiting for some IOs or network connections etc.

This is a very elegant asynchronous programming solution because you do not have to be concerned with callbacks or internal event loops, to make your script hold in a certain position while parallel tasks keep running and do other things. This is definitely one of the best features of the Hack language.

class Foo {}

class Bar {
    public function getFoo(): Foo {
        return new Foo();
    }
}

async function gen_foo(int $a): Awaitable<?Foo>; {
    if ($a === 0) return null;

    $bar = await gen_bar($a);
    if ($bar !== null) {
        return $bar->getFoo();
    }

    return null;
}

async function gen_bar(int $a): Awaitable<?Bar> {
    if ($a === 0) return null;
    return new Bar();
}

gen_foo(4);

Important Language Features of Hack: An Overview


Hack has introduced many new features that are used for different purposes, such as Error Prevention, Code Reuse, Performance Optimization etc. Following are some of the important language features of Hack:

Type Annotations

Type Annotations allow for PHP code to be explicitly typed on parameters, class member variables and return values. They are like type declarations, except they are optional.

class MyClass {
    const int MyConst = 0;
    private string $x = '';
    public function increment(int $x): int {
        $y = $x + 1;
        return $y;
    }
}

Nullable Types

Nullable types is an extension of type annotations used to specify that a value maybe of a certain type or NULL. They are supported by Hack through use of a question mark operator. This introduces a safer way to deal with nulls and is very useful for primitive types that don’t generally allow null as one of their values, such as bool and int. The operator can be used on any class or type.

function check_not_null(?int $x): int {
    if ($x === null) {
        return -1;
    } else {
        return $x;
    }
}

Collections

Collections enhance the experience of working with PHP arrays, by providing first class, built-in parameterized types such as Vector, Map, Set and Pair. Collections allow to detect attempts to set values to incorrect types due to application bugs.

/*  Like all objects, collections has "reference-like"
    semantics for assignment, parameter passing, and
    foreach. */

function foo($v) {
    $v[1] = 7;
}

function main() {
    $v1 = Vector {1, 2, 3};
    $v2 = $v1;
    foo($v2);
    var_dump($v1);
    echo "\n";
    foreach ($v1 as $key => $value) {
        echo $key . " => " . $value . "\n";
        if ($key == 0) {
            $v1[2] = 9;
        }
    }
}

main();

Generics

Generics allow classes and methods to be parameterized in the same way as statically type languages like Java and C#). Generics are basically code templates. This allows to create classes that perform the same operations using the same code on classes of different types (such as integers or floating point numbers etc.)

class Box<T> {
    protected T $data;

    public function __construct(T $data) {
        $this->data = $data;
    }

    public function getData(): T {
        return $this->data;
    }
}

There are other features too which include Shapes, Async support, Type Aliasing and much more.