PHP's First-Class Callable Syntax
Published: 2023-06-23 01:43:47

This awesomess introduced in PHP 8.1 does not get the attention it deserves, IMO. I intend to use this post to show how cool it is!

PHP 8.1 introduces a more streamlined way to create callable functions, called the "first-class callable syntax".  Let's dive in a littel bit into this syntax.

## A little backtrack...
Previously, we use `Closure::fromCallable` to turn a function or method into a callable object. This function takes in a PHP callable (which could be a function name, a method, or even an anonymous function) and spits out a Closure object. A typical example would be converting the `strtoupper` function into a callable:

```php
$callable = Closure::fromCallable('strtoupper');
echo $callable('foo'); // Outputs 'FOO'
```

This method gets the job done, but isn't it a bit too verbose? Or perhaps we can make it a tad better. PHP 8.1's new syntax seeks to eliminate this extra clutter.

## The new sauce 🪄
With the new syntax, you simply call the function or method followed by ellipsis (`...`) to create a first-class callable. That way, you can create a callable from the `strtoupper` function like this:

```php
$callable = strtoupper(...);
echo $callable('foo'); // Outputs 'FOO'
```

Now I will say _that_ is so much more cleaner! You can create first-class callables from function names, class methods, static methods, and anonymous functions. Just remember that the ellipsis (...) isn't a placeholder for any specific parameter.

## Hold up now, soldier!
Here's where you need to be careful though. While the new syntax seems to hint at partial function application (the idea that you can fix a number of arguments to a function), PHP doesn't currently support it. So, attempting to pass any parameters to the callable would result in a syntax error.

```php
// Assume $text is a defined variable

$callable = str_contains($text, ...);
// A syntax error, as partial function application is not supported.
```

## Other Considerations
The ellipsis (`...`) have other uses as well. One is in creating 'variadic functions', or functions that can take an indefinite number of arguments. The ellipsis also comes in handy when we want to 'spread' or distribute elements of an array or object to a function.

However, even with the introduction of first-class callables using the ellipsis, these existing uses of the ellipsis in PHP remain unchanged. So, there's no need to worry about the new callable syntax causing any disruptions to your previous work.

Also note that you can't use the syntax to instantiate new objects with the `new` keyword, or to declare null-safe methods or attributes.

## Scope
One cool aspect of first-class callables is that they carry the scope of the location where they were created. This means a first-class callable can access private methods, as long as it's created within the object's scope.

## Compatibility
This feature is new to PHP 8.1 and so can't be used with older versions. If you need to maintain compatibility with older versions, you'll have to stick with `Closure::fromCallable`. But if you're using PHP 8.1 or later, you'll surely love the simplicity and efficiency the first-class callable syntax brings to your coding!

I hope you found this explanation both interesting and informative. You can read more [in the official docs](https://www.php.net/manual/en/functions.first_class_callable_syntax.php). The journey of PHP continues, and I can't wait to see where it takes us next. Keep coding, keep learning!