Get "PHP 8 in a Nutshell" (Now with PHP 8.5)
Amit Merchant
Amit Merchant

A blog on PHP, JavaScript, and more

Partial Function Application is coming in PHP 8.6

Ever reach for a simple callback and end up writing a tiny novella—an arrow function stuffed with types, reordered parameters, and boilerplate just to pass one value through?

Well, it looks like PHP 8.6 is set to make our lives easier with the introduction of Partial Function Application.

What is Partial Function Application?

Partial Function Application in PHP 8.6 will let you write a “pre‑configured” callable by calling a function with some arguments and using placeholders for the rest. Instead of executing, PHP returns a Closure whose parameter list is auto‑derived from the missing parts.

Placeholders are:

  • ? for “exactly one argument here”
  • for “forward any remaining arguments”

Here’s a basic example of how it works.

function add4(int $a, int $b, int $c, int $d): int {
    return $a + $b + $c + $d;
}

// Fill some now, leave one for later:
$f = add4(1, ?, 3, 4);
// Equivalent to:
$f = static fn(int $b): int => add4(1, $b, 3, 4);

echo $f(2); // 1+2+3+4 = 10

As you can see in the example above, we created a new callable $f by partially applying the add4 function with some arguments and using a placeholder for the missing argument. We can then call $f with the remaining argument to get the final result.

You can also call PFA an extension of first-class callables.

You can leave multiple holes as well.

$f = add4(1, ?, 3, ?);
// Equivalent:
$f = static fn(int $b, int $d): int => add4(1, $b, 3, $d);

echo $f(5, 7); // 1+5+3+7 = 16

And “Everything else” with

$f = add4(1, ...);
// Equivalent:
$f = static fn(int $b, int $c, int $d): int => add4(1, $b, $c, $d);

echo $f(2, 3, 4); // 10

With PFA, callbacks become concise and intention-revealing. No more boilerplate arrow functions just to rearrange or fix arguments. Just plug in ? and where needed, and PHP does the rest.

$strings = ['hello world', 'hello there'];

// Without PFA (verbose):
$result = array_map(static fn(string $s): string => str_replace('hello', 'hi', $s), $strings);

// With PFA:
$result = array_map(str_replace('hello', 'hi', ?), $strings);
// Each element is fed into the ? at the $subject position.

It’s also pipe operator-friendly.

$foo
  |> array_map(strtoupper(...), ?)
  |> array_filter(?, is_numeric(...));
// Right side of the pipe needs a unary callable; PFA supplies it concisely.

Named arguments and order.

function stuff(int $i, string $s, float $f, Point $p, int $m = 0): string { /* ... */ }

// Named values out of order still work:
$c = stuff(?, ?, f: 3.5, p: $point);
// Closure expects (int $i, string $s)

// Named placeholders define their own parameter order:
$c = stuff(s: ?, i: ?, p: ?, f: 3.5);
// Closure expects (string $s, int $i, Point $p)

Variadic functions.

function things(int $i, ?float $f = null, Point ...$points) { /* ... */ }

// Keep variadic open:
$c = things(1, 3.14, ...);
// Closure expects (Point ...$points)

// Force exact count (variadic becomes required slots):
$c = things(?, ?, ?, ?);
// Closure expects (int $i, ?float $f, Point $points0, Point $points1)

You can also implement Thunk functions easily with PFAs.

function expensive(int $a, int $b, Point $c) { /* heavy work */ }

// Prefill all, delay execution:
$thunk = expensive(3, 4, $pt, ...); // Closure with zero required params

// Later:
$result = $thunk();

You cannot partially apply constructors (new). Instead, you can use static methods or factory functions.

$maker = Widget::make(?, size: 10); // OK
$new = new Widget(?, 10);           // Compile error

Common PFA patterns

Here are quick patterns that can be associated with PFAs.

  • Unary callback: array_map(in_array(?, $allowed, strict: true), $input)
  • Fill “from the left,” leave rest: stuff(1, 'two', …)
  • Named setup, leave rest: stuff(f: 3.14, s: 'two', …)
  • First‑class callable (degenerate case): func(…)

In closing

Partial Function Application will be a powerful addition to PHP 8.6 that can significantly reduce boilerplate and improve code clarity when working with callbacks. By allowing you to pre-configure functions with placeholders, PFA makes it easy to create concise, intention-revealing callables without the need for verbose arrow functions.

Read more about Partial Function Application in the official RFC.

Now Available → PHP 8.5
Learn the fundamentals of PHP 8 (including 8.1, 8.2, 8.3, 8.4, and 8.5), the latest version of PHP, and how to use it today with my book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

👋 Hi there! This is Amit, again. I write articles about all things web development. If you enjoy my work (the articles, the open-source projects, my general demeanour... anything really), consider leaving a tip & supporting the site. Your support is incredibly appreciated!

Comments?