Other Features: Variadic Functions

A variadic function can take a variable number of arguments. In PHP, all functions are variadic, even if they don't explicitly say so. So a function that looks like:

function foo ($a, $b) {}

can actually be passed more than 2 arguments. You can access the passed arguments to a function, including the "extra" ones, via func_get_args, func_get_arg and func_num_args.

In Hack, however, you cannot pass more arguments than are specified. A typechecker error will be raised.

<?hh

namespace Hack\UserDocumentation\OtherFeatures\Variadic\Examples\Bad;

function foo(int $a, bool $b): string {
  return "Hello";
}

function run(): void {
  var_dump(foo(4, true, "Bad param"));
}

run();
Output
string(5) "Hello"

Hack has specific notation specify that a function can take extra arguments. By putting ... as the last argument to a function, you are telling the typechecker that the function can take a variable number of arguments.

<?hh

namespace Hack\UserDocumentation\OtherFeatures\Variadic\Examples\Good;

class A {}

function add_or_multiply_all(bool $b, ...$nums): int {
  // $nums is an array of arguments
  // filter out all the non-ints

  $nums = array_filter($nums, $x ==> is_int($x));

  if ($b) {
    return array_sum($nums);
  }
  return array_product($nums);
}

function run(): void {
  var_dump(add_or_multiply_all(true, 3, "Hi", new A(), 4, 9, -2));
  var_dump(add_or_multiply_all(false, 3, "Hi", new A(), 4, 9, -2));
}

run();
Output
int(14)
int(-216)

The types of the variable arguments can be anything you want. Of course, the non-variadic arguments to the function must be of the type specified.

Type Annotations and Variadic Functions

It is important to note that there is a conflict between the typechecker and HHVM when it comes to adding a typehint to a variadic argument.

Basically, although the typechecker allows and supports them, HHVM currently does not. See the above link for details.