On 23/03/2025 12:52, Robert Chapin wrote:
Hi PHP folks,
I submitted a proposal on Monday that received no replies. The idea
was about adding a functional construct nullc() that could act as an
inline null coalesce for a variable. That task is currently not
possible in a nullc() user function, but instead requires an
expression like ($var ?? null) with mandatory extra parentheses.
I'm sympathetic to the problem you're trying to solve - the precedence
of ?? isn't always helpful - but I'm not sure I like the proposed
solution, for 3 reasons.
1) The name "nullc" is over-shortened and cryptic. The "c" looks almost
like an accident, and it doesn't actually do anything if given a null.
2) With only one argument, it isn't really "coalescing" anything, it's
just suppressing errors. It's telling that all your examples with ?? put
a value other than null on the right-hand side.
If the default is not one of the normal values, the effective default
depends on how you use it:
if (nullc($test) === 'on')
if (nullc($test) !== 'off')
In my experience, a lot of people struggle to follow logic like this,
and it can easily lead to subtle bugs. Compare the same logic with
explicit defaults:
if (nullc($test, 'off') === 'on')
if (nullc($test, 'on') !== 'off')
3) The function-like syntax doesn't seem to gain us much; it has to be a
language construct not a true function, so it won't be usable with
things like array_map, and with two arguments, nullc($foo, $bar) and
($foo ?? $bar) look very similar.
All of which makes me look to the COALESCE function from SQL:
- The name is short but not cryptically abbreviated, and will be
familiar to most PHP users.
- The function is variadic - you can pass just one argument, but can
also pass three, or ten.
- The parameters are evaluated lazily, like they would be with an operator.
I've seen and implemented many variations of this in userland, although
obviously using `$arg !== null` rather than `isset($arg)`.
There is a small risk that some people might have an existing function
with different behaviour, e.g. a test on "emptiness" with `$arg !=
false`, and need to rename it when upgrading PHP.
I'm still only lukewarm on including it, because it's mostly just
reminding you to include a pair of parentheses:
if (($_POST['input'] ?? null) === 'yes') echo 'success';
if (coalesce($_POST['input']) === 'yes') echo 'success';
if (coalesce($_POST['input'], null) === 'yes') echo 'success';
if (($_POST['input'] ?? $_GET['input'] ?? 'N/A') !== 'N/A') echo
'meaningful value provided';
if (coalesce($_POST['input'], $_GET['input'], 'N/A') !== 'N/A') echo
'meaningful value provided';
--
Rowan Tommins
[IMSoP]