haphpiness

These are things in PHP which make me genuinely_happy();

Partial Function Application — The Callback You Meant to Write

Not out yet. PHP 8.6 is due 19 November 2026, and this one is written and voted through.

PHP 8.1 gave us first-class callables: strlen(...) hands you the function as a value. Lovely, until you need to bind an argument, at which point you are back to writing a closure whose only job is to forget most of its parameters.

// The thing you want: str_replace with two arguments already decided.
$arr = array_map(fn ($s) => str_replace('hello', 'hi', $s), $arr);

// Same story, every time you use a callback:
usort($users, fn ($a, $b) => compareBy('surname', $a, $b));

Partial application lets you write the call you mean and leave holes in it. ? marks one argument you will supply later. ... stands for all the rest.

// One placeholder: the subject arrives later.
$arr = array_map(str_replace('hello', 'hi', ?), $arr);

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

$c = stuff(1, ?, 3.5, ?, ?);        // three holes to fill
$c = stuff(1, 'hi', ...);           // bind two, leave the rest
$c = stuff(?, ?, f: 3.5, p: $point, ...);  // named arguments work too

// All arguments bound, nothing called: a thunk.
$later = stuff(1, 'hi', 3.4, $point, 5, ...);
$result = $later();                 // runs now

The result is an ordinary Closure, so everything that already takes a callable takes this. It builds on the same engine machinery as first-class callable syntax, which is why foo(...) and foo(1, ?) are the same idea at different levels of completeness.

What makes it more than sugar: the arity and types are known at the point you write the partial, not deferred into a closure body the engine cannot see through. The intent that used to live inside an arrow function is now in the signature, where static analysis can read it.

Significance: Functional Joy

Every functional language has this, and PHP has been circling it for a decade: create_function, then closures, then arrow functions, then first-class callables. Each step removed some ceremony from "here is a function, with some parts decided". Partial application is the end of that road. The tell that it belongs in PHP is how boring it looks in real code, which is exactly what you want from syntax you will type a hundred times a week.