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]

Reply via email to