.hhconfig
file in it. This will be the root of your project.$ mkdir my_project
$ cd my_project
$ touch .hhconfig​
my_project/hello.hack
with the following code:use namespace HH\Lib\IO;
<<__EntryPoint>>
async function main(): Awaitable<void> {
await IO\request_output()->writeAllAsync("Hello World!\n");
}​
$ cd my_project
$ hh_client
No errors!​
5. Run Your Program : HHVM provides the Hack runtime. You can run your program as follows :$ cd my_project
$ hhvm hello.hack
Hello World!​
$ cd my_project
$ hhvm -m server -p 8080​
Hello World!
" in your browser. Advantages :
1. Type System : Hack introduces a static type system, which allows for catching type-related errors during the development process rather than at runtime. This feature enhances code reliability and makes it easier to detect and fix bugs early on.Disadvantages :
1. Learning Curve : If you are familiar with PHP, transitioning to Hack may require some learning and adjustment. The static type system and additional features introduced by Hack might have a learning curve for developers who are new to the language.function
` keyword followed by the function name, parameter list, return type, and the function body. Here's the syntax for declaring functions in Hack:function functionName(parameter1: Type1, parameter2: Type2): ReturnType {
// Function body
// Code statements
return value; // Optional return statement
}​
:
`) and the parameter type.void
` type.return
` statement is only required if your function is expected to return a value.
Here's an example of a function that takes two integers as parameters and returns their sum :function addNumbers(a: int, b: int): int {
$sum = $a + $b;
return $sum;
}​
addNumbers
` takes two parameters, `a
` and `b
`, both of type `int
`. It calculates their sum and returns the result, which is an `int
` value. for
` loop is used to iterate a specific number of times. It consists of an initialization statement, a condition, an increment/decrement statement, and the loop body.for ($i = 0; $i < 5; $i++) {
// Loop body
// Code statements
}​
$i
` is less than 5. The `$i
` variable is incremented by 1 in each iteration.foreach
` loop is used to iterate over arrays and other iterable data structures, such as collections or maps. It automatically traverses each element in the data structure without the need for an explicit counter.foreach ($array as $element) {
// Loop body
// Code statements
}​
$array
` is an array, and `$element
` represents the current element being iterated. The loop body will execute for each element in the array.
3. While Loop : The `while
` loop repeatedly executes a block of code as long as a given condition is true. It evaluates the condition before each iteration.while (condition) {
// Loop body
// Code statements
}​
while
` loop, the condition is checked, and if it evaluates to true, the loop body is executed. The loop continues until the condition becomes false.do-while
` loop is similar to the `while
` loop but with a crucial difference: it executes the loop body at least once before checking the condition.do {
// Loop body
// Code statements
} while (condition);​
do-while
` loop, the loop body is executed first, and then the condition is evaluated. If the condition is true, the loop continues, otherwise, it terminates.1. Throwing an Exception :
To indicate an error or exceptional condition, you can throw an exception using the `throw
` keyword. An exception is an object that represents an error or exceptional situation.throw new Exception("An error occurred.");​
Exception
` class is created and thrown. You can pass an error message as a parameter to the exception constructor to provide additional information about the error.2. Catching an Exception :
To handle exceptions and prevent them from causing a program to terminate abruptly, you can use the `try
` and `catch
` blocks. The `try
` block contains the code that may throw an exception, and the `catch
` block is used to catch and handle the exception.try {
// Code that may throw an exception
} catch (Exception $e) {
// Exception handling code
}​
try
` block is executed, and if an exception is thrown, it is caught by the `catch
` block. The exception object is assigned to the variable `$e
`, which can be used to access information about the exception, such as the error message.
3. Multiple Catch Blocks : You can have multiple `catch
` blocks to handle different types of exceptions separately. This allows you to handle different exceptional situations differently.try {
// Code that may throw an exception
} catch (ExceptionType1 $e) {
// Exception handling code for ExceptionType1
} catch (ExceptionType2 $e) {
// Exception handling code for ExceptionType2
}​
ExceptionType1
` is thrown, it will be caught by the first `catch
` block, and if an exception of `ExceptionType2
` is thrown, it will be caught by the second `catch
` block.finally
` block after the `catch
` block(s). The code within the `finally
` block is executed regardless of whether an exception is thrown or not. It is typically used to perform cleanup tasks or release resources.try {
// Code that may throw an exception
} catch (Exception $e) {
// Exception handling code
} finally {
// Code to be executed regardless of exceptions
}​
finally
` block will always be executed, regardless of whether an exception is thrown or caught.try-catch
` mechanism, you can handle errors in a controlled manner, catch and handle specific types of exceptions, and ensure that your program gracefully handles exceptional conditions. Set<T>
`, which stores elements of a specific type, and `Keyset<T>
`, which stores unique keys of a map. Sets are useful for membership testing and eliminating duplicate entries.Map<K, V>
`, where keys and values can be of any type, and `Dict<K, V>
`, where keys must be of a specific type. Maps are useful for efficient lookup and retrieval of values based on keys.
5. Tuples : Tuples are fixed-size collections that can hold a fixed number of elements of different types. They provide a convenient way to group multiple values together.Deque<T>
` (double-ended queue), `Pair<T1, T2>
` (a pair of values), and `VectorMap<K, V>
` (a combination of a vector and a map), among others.function greet(string $name): string {
return "Hello, ".$name;
}​
greet
` is annotated with the `string
` type for both the parameter `$name
` and the return type.function addNumbers(int $a, int $b): int {
return $a + $b;
}
$sum = addNumbers(5, 10); // $sum is inferred as int​
$a
`, `$b
`, and `$sum
` are inferred based on their usage and the annotated return type of the `addNumbers
` function.
3. Type Checking : During the compilation process, the Hack type checker examines the annotated types and performs static type checking. It verifies that the types of variables, expressions, function parameters, and return values are consistent and compliant with the defined types.function greet(string $name): string {
return "Hello, ".$name;
}
$greeting = greet(42); // Type error: expecting string, int given​
greet
` function is of type `int
`, which does not match the expected `string
` type.function greet(string $name): string {
return "Hello, ".$name;
}​
string
` is used as a type annotation for both the parameter `$name
` and the return type.null
` in addition to the specified type. This is denoted by adding a `?
` before the type annotation.function findUserById(int $id): ?User {
// ...
}​
User
` object or `null
`.const
` keyword to annotate constants.const int MAX_COUNT = 10;​
MAX_COUNT
` is annotated as a constant of type `int
` with a value of 10.
4. Enum Annotations : Enum annotations define enumerations, which are a set of named constant values. You can use the `enum
` keyword to annotate an enumeration.enum UserRole: string {
const ADMIN = 'admin';
const USER = 'user';
}​
UserRole
` is an annotated enumeration with two constant values: `ADMIN
` and `USER
`.< >
`) to provide type parameters.class Stack<T> {
// ...
}​
T
` is a generic type parameter for the `Stack
` class.<<__Override>>
` annotation to specify this.class ChildClass extends ParentClass {
<<__Override>>
public function someMethod() {
// ...
}
}​
someMethod
` in `ChildClass
` is annotated as overriding the corresponding method in `ParentClass
`. Test.hack
` or `_Test.hack
` to distinguish them from regular code files.// MyCode.hack
function addNumbers(int $a, int $b): int {
return $a + $b;
}
// MyCodeTest.hack
function testAddNumbers(): void {
$result = addNumbers(2, 3);
assert($result === 5, "Expected result is 5, but got $result");
}​
assert($result === 5, "Expected result is 5, but got $result");​
The above assertion verifies if the `$result
` variable is equal to 5. If the condition fails, the assertion throws an exception with the provided error message.__Memoize and __MemoizeLSB
attributes in Hack support experimental options that control how the function behaves with respect to an Implicit Context value.$e = MyDsl`foo() + 1`;​
// You write code like this:
$e = MyDsl`1 + 2`;
// Hack runs the following "desugared" code:
$e =
MyDsl::makeTree<MyDslInt>(
($v) ==> $v->visitBinop(
$v->visitInt(1),
'__plus'
$v->visitInt(2))
);​
// The type checker will also check that this "virtualized" expression is correct,
// even though this virtualized code isn't executed.
(MyDsl::intType())->__plus(MyDsl::intType());​
async
` keyword before the function declaration. An async function returns an `Awaitable<T>
` object, where `T
` represents the type of the eventual result.async function fetchData(): Awaitable<string> {
// Perform asynchronous operations
// ...
return $result;
}​
fetchData
` function is defined as an async function, indicating that it can be executed asynchronously. It returns an `Awaitable<string>
` object representing a future result of type `string
`.await
` keyword to pause the execution and wait for the completion of an asynchronous operation. The `await
` expression is used to retrieve the eventual result of an `Awaitable` object.async function processAsync(): Awaitable<void> {
$result = await fetchData();
// Process the result
// ...
}​
await
` expression is used to pause the execution of the `processAsync
` function until the `fetchData
` async function completes. The value of `$result
` will be the eventual result of the asynchronous operation.
3. Async Control Structures : Hack provides async versions of control structures like `if
`, `foreach
`, and `while
` that allow you to work with async operations.async function processListAsync(array<int> $numbers): Awaitable<void> {
foreach async ($numbers as $number) {
$result = await processNumberAsync($number);
// Process the result
// ...
}
}​
foreach async
` loop allows you to iterate over the `$numbers` array asynchronously, processing each number using the `processNumberAsync` function.HH\Asio\v()
` function, also known as the "vector await
" function, which allows you to execute multiple async operations in parallel. It takes an array of `Awaitable` objects and returns an `Awaitable<array<mixed>>
` object representing the results.async function fetchMultiple(): Awaitable<void> {
$results = await HH\Asio\v(fetchData(), fetchOtherData());
// Access individual results
// ...
}​
fetchData()
` and `fetchOtherData()
` functions are executed concurrently using `HH\Asio\v()
`, allowing the async function to await both operations in parallel.