Search code examples
phpoperatorsnull-coalescing-operatorassociativity

Right associativity of PHP's null coalesce operator


According to PHP documentation, the null coalescing operator ?? is right-associative, i.e.

$a ?? $b ?? $c

is equivalent to

$a ?? ($b ?? $c)

What is the significance of this? Does it make any difference for developers that it is left-associative or right-associative?

To those who are thinking it will call less functions, this is not true because the right operand will not be evaluated if the left operand is not null according to my test:

function f(string $a) : string {
    echo "f($a)\n";
    return $a;
}
var_dump(f("a") ?? f("b") ?? f("c") ?? f("d"));
echo "===\n";
var_dump(((f("a") ?? f("b")) ?? f("c")) ?? f("d"));

Output:

f(a)
string(1) "a"
===
f(a)
string(1) "a"

Solution

  • I am thinking about performance issues, where you have to evaluate ?? multiple times (if the first value is non null) if it is left-associative while once only if it is right-associative. Compare these two cases:

    (("a" ?? "b") ?? "c") ?? "d"
    "a" ?? ("b" ?? ("c" ?? "d"))
    

    On the first line, after the second (inner) parentheses ?? "b" is resolved, the value inside the first (outer) parentheses ?? "c" is resolved, then the final ?? "d" is resolved. ?? is performed 3 times.

    On the second line, since "a" is not null, the whole chunk of ("b" ?? ("c" ?? "d")) does not need to be resolved. ?? is only performed once.

    Although the right-hand-side value is not resolved, checking !== null fewer times might still be beneficial.

    (Still, I wonder if this is the only reason?)