Hello Internals,
We currently have a null coercion operator: ??, but we lack an
anti-null coercion operator.
For example, if I wanted to operate on a header, if-and-only-if it
exists, I'd have to write something like this one-liner:
fn() =>
($_SERVER['HTTP_X_MY_HEADER'] ?? null)
? md5($_SERVER['HTTP_X_MY_HEADER'])
: null;
Or something like this:
function() {
if(!empty($_SERVER['HTTP_X_MY_HEADER']) {
return md5($_SERVER['HTTP_X_MY_HEADER']);
}
return null;
}
This is rather tedious when you have to do it, so, I'd like to discuss
adding a new "anti-null coercion" operator: ?!
This would collapse the previous verbose code into:
fn() =>
$_SERVER['HTTP_X_MY_HEADER']
?! md5($_SERVER['HTTP_X_MY_HEADER'];
When it is null, it will stay null, thus the above is the same as:
fn() =>
$_SERVER['HTTP_X_MY_HEADER']
?! md5($_SERVER['HTTP_X_MY_HEADER']
?? null;
It would have a lower precedence than ?? so that the above line would
read from left to right without requiring parenthesis/brackets. The
operator would only return the right-hand side if the left-hand side
exists (aka, not null), otherwise, it would return null.
I'm not particularly attached to the ?! syntax (since it does, in
fact, look very similar to ?:), so perhaps focusing on the merits of
the idea first, then bikeshedding the syntax later would be a good
approach?
Thoughts?
Robert Landers
Software Engineer
Utrecht NL
Hello Internals,
We currently have a null coercion operator: ??, but we lack an
anti-null coercion operator.
For example, if I wanted to operate on a header, if-and-only-if it
exists, I'd have to write something like this one-liner:
fn() =>
($_SERVER['HTTP_X_MY_HEADER'] ?? null)
? md5($_SERVER['HTTP_X_MY_HEADER'])
: null;
Or something like this:
function() {
if(!empty($_SERVER['HTTP_X_MY_HEADER']) {
return md5($_SERVER['HTTP_X_MY_HEADER']);
}
return null;
}
This is rather tedious when you have to do it, so, I'd like to discuss
adding a new "anti-null coercion" operator: ?!
This would collapse the previous verbose code into:
fn() =>
$_SERVER['HTTP_X_MY_HEADER']
?! md5($_SERVER['HTTP_X_MY_HEADER'];
When it is null, it will stay null, thus the above is the same as:
fn() =>
$_SERVER['HTTP_X_MY_HEADER']
?! md5($_SERVER['HTTP_X_MY_HEADER']
?? null;
It would have a lower precedence than ?? so that the above line would
read from left to right without requiring parenthesis/brackets. The
operator would only return the right-hand side if the left-hand side
exists (aka, not null), otherwise, it would return null.
I'm not particularly attached to the ?! syntax (since it does, in
fact, look very similar to ?:), so perhaps focusing on the merits of
the idea first, then bikeshedding the syntax later would be a good
approach?
Thoughts?
Robert Landers
Software Engineer
Utrecht NL
--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi Robert,
Why don’t you combine the two examples and use a regular ternary operator along with isset/empty()?
fn() =>
!empty($_SERVER[‘HTTP_X_MY_HEADER’])
? md5($_SERVER[‘HTTP_X_MY_HEADER’])
: null;
It’s only ever so slightly longer than the proposed ?! operator, but way more powerful. You explicitly control the evaluation expression along with the default value.
Regards,
Sergii
Following the php logic, maybe !??
Hello Internals,
We currently have a null coercion operator: ??, but we lack an
anti-null coercion operator.For example, if I wanted to operate on a header, if-and-only-if it
exists, I'd have to write something like this one-liner:fn() =>
($_SERVER['HTTP_X_MY_HEADER'] ?? null)
? md5($_SERVER['HTTP_X_MY_HEADER'])
: null;Or something like this:
function() {
if(!empty($_SERVER['HTTP_X_MY_HEADER']) {
return md5($_SERVER['HTTP_X_MY_HEADER']);
}return null;
}This is rather tedious when you have to do it, so, I'd like to discuss
adding a new "anti-null coercion" operator: ?!This would collapse the previous verbose code into:
fn() =>
$_SERVER['HTTP_X_MY_HEADER']
?! md5($_SERVER['HTTP_X_MY_HEADER'];When it is null, it will stay null, thus the above is the same as:
fn() =>
$_SERVER['HTTP_X_MY_HEADER']
?! md5($_SERVER['HTTP_X_MY_HEADER']
?? null;It would have a lower precedence than ?? so that the above line would
read from left to right without requiring parenthesis/brackets. The
operator would only return the right-hand side if the left-hand side
exists (aka, not null), otherwise, it would return null.I'm not particularly attached to the ?! syntax (since it does, in
fact, look very similar to ?:), so perhaps focusing on the merits of
the idea first, then bikeshedding the syntax later would be a good
approach?Thoughts?
Robert Landers
Software Engineer
Utrecht NL--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi Robert,
Why don’t you combine the two examples and use a regular ternary operator along with isset/empty()?
fn() =>
!empty($_SERVER[‘HTTP_X_MY_HEADER’])
? md5($_SERVER[‘HTTP_X_MY_HEADER’])
: null;It’s only ever so slightly longer than the proposed ?! operator, but way more powerful. You explicitly control the evaluation expression along with the default value.
Regards,
Sergii
Hey Sergii,
Why don’t you combine the two examples and use a regular ternary operator along with isset/empty()?
Because falsy is different than null/non-existent. The closest
equivalent is "array_key_exists" (instead of empty/isset) but this
proposal isn't just applicable to arrays. I run into this pattern of
"if not null, then do something with the value" pretty often and it is
tedious to type it out.
Robert Landers
Software Engineer
Utrecht NL
Because falsy is different than null/non-existent. The closest
equivalent is "array_key_exists" (instead of empty/isset) but this
proposal isn't just applicable to arrays. I run into this pattern of
"if not null, then do something with the value" pretty often and it is
tedious to type it out.
In terms of falsy values, null coalescing operator ?? is a syntactic sugar for isset().
So, ?! operator will be equivalent to !isset() expression in the ternary.
For the reference:
https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
Hi Robert
Hello Internals,
We currently have a null coercion operator: ??, but we lack an
anti-null coercion operator.
...
fn() =>
($_SERVER['HTTP_X_MY_HEADER'] ?? null)
? md5($_SERVER['HTTP_X_MY_HEADER'])
: null;
...
This is rather tedious when you have to do it, so, I'd like to discuss
adding a new "anti-null coercion" operator: ?!This would collapse the previous verbose code into:
fn() =>
$_SERVER['HTTP_X_MY_HEADER']
?! md5($_SERVER['HTTP_X_MY_HEADER'];
This does not seem significantly less verbose to me. The main
motivation for ?? was that it avoids repeating the expression over
something like ?:. I would see a stronger argument for this feature if
it offered the same benefit. E.g.
$_SERVER['HTTP_X_MY_HEADER'] ?! md5($$)
It would have a lower precedence than ?? so that the above line would
read from left to right without requiring parenthesis/brackets. The
operator would only return the right-hand side if the left-hand side
exists (aka, not null), otherwise, it would return null.
I think it should have a higher precedence.
$_SERVER['HTTP_X_MY_HEADER'] ?! md5($$) ?? 'abc'
==>
($_SERVER['HTTP_X_MY_HEADER'] ?! md5($$)) ?? 'abc'
Otherwise the result is NULL
if the header is missing, given that the
coalesce operator is never executed.
That said, while I've certainly encountered this situation, it's
nothing a temporary variable can't fix. I don't personally believe
there's a strong need for such an operator.
Ilija
Hi Robert
Hello Internals,
We currently have a null coercion operator: ??, but we lack an
anti-null coercion operator.
...
fn() =>
($_SERVER['HTTP_X_MY_HEADER'] ?? null)
? md5($_SERVER['HTTP_X_MY_HEADER'])
: null;
...
This is rather tedious when you have to do it, so, I'd like to discuss
adding a new "anti-null coercion" operator: ?!This would collapse the previous verbose code into:
fn() =>
$_SERVER['HTTP_X_MY_HEADER']
?! md5($_SERVER['HTTP_X_MY_HEADER'];This does not seem significantly less verbose to me. The main
motivation for ?? was that it avoids repeating the expression over
something like ?:. I would see a stronger argument for this feature if
it offered the same benefit. E.g.$_SERVER['HTTP_X_MY_HEADER'] ?! md5($$)
It would have a lower precedence than ?? so that the above line would
read from left to right without requiring parenthesis/brackets. The
operator would only return the right-hand side if the left-hand side
exists (aka, not null), otherwise, it would return null.I think it should have a higher precedence.
$_SERVER['HTTP_X_MY_HEADER'] ?! md5($$) ?? 'abc'
==>
($_SERVER['HTTP_X_MY_HEADER'] ?! md5($$)) ?? 'abc'Otherwise the result is
NULL
if the header is missing, given that the
coalesce operator is never executed.That said, while I've certainly encountered this situation, it's
nothing a temporary variable can't fix. I don't personally believe
there's a strong need for such an operator.Ilija
Another point to note is that for objects, we already have ?->, which effectively serves this purpose. It is sugar for:
is_null($o) ? null : $o->whatever()
So any new operator would only be relevant for free-standing variables (which is automatically a code smell) or arrays, and I'm not convinced the latter is a large enough use case in a decently written code base. (You really should know what your data is, and the best way to do that is map it into a proper object, at which point ?-> comes into play.)
--Larry Garfield