php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #79669 Nullable variables
Submitted: 2020-06-03 09:20 UTC Modified: 2020-06-03 18:51 UTC
From: valentiny510 at gmail dot com Assigned:
Status: Suspended Package: Variables related
PHP Version: Next Major Version OS: nix
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2020-06-03 09:20 UTC] valentiny510 at gmail dot com
Description:
------------
The coalescing operator is one of the best life (or write) savers,
and still in some situations became a bit redundant, assuming $b is not set...

$a = $b ?? null; meaning "if is null, null, else null"

And we have to do this only to avoid the errors flooding the log...
(yes, I know we can disable it with error_reporting, but that will also disable other errors that we may want to see)

Another good thing is the nullable type, but sadly it only apply to... types

So, my request is to extend the "nullable" to other... things,
like variables for instance, and I think will be a great life saver

Ex: $a = ?$b;

Seeing the above assignment, probably will be better to create a new operator,

=?

Meaning of course, assign the right side if isset, otherwise null

Thank you


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-06-03 09:29 UTC] danack@php.net
-Status: Open +Status: Feedback
 [2020-06-03 09:29 UTC] danack@php.net
I have no idea what you are saying. Please write clearly:

i) The code that you are currently writing that you don't like.
ii) a description of why that is a problem.

I get that you want something to be shorter, but you haven't said what.
 [2020-06-03 11:18 UTC] valentiny510 at gmail dot com
Deeply in my heart I want the error removed, "Undefined variable: x"
is absolutelly useless and "too verbose" for my taste
I want to be able to assign a variable without knowing if is set or not
$a = $b; or $a = $c['d']['e'];
In the mayority of cases you need to check if is null anyways
if ($a)... or if (!is_null($a))...

But, since this is very unlikely to occur, at least, Yes, I want a shorter
version of the coalesce operator, Like I already said...
$a = $b ?? null; means "if is null, null, else null"
and I want...
$a = $b; meaning "if is null and I don't have any other option, then leave it null"
The parse could simply ask
"is set $b ?" then evaluate to null (as it already does), then ask again
"I have ?? after $b?" if no, return the null that Already Evaluated...
Is simple,
and maybe... maybe may cause (in some extraordinary exceptions)
some issues where you can have two options,
1. that $b can be set but have null assigned
2. is not set
and you can not decide, but I think that is isset( ) function for

So, if none of this is possible, at least I want to be extended the
"nullable things" to variables and maybe other objects like classes

$a = ?(new some_class); # nullable class/object (very unlikely but...)
in this case if some_class doesn't exists, can be converted automatically to a
"new null" where all functions return always null (maybe similar to stdClass)
and yes, I know I can implement that in the autoloader but maybe you don't want
that all classes be converted to null
and yes, you can also do $a = class_exists(...) ? new ... : new Null; but...

In this bug/request I want at least one of this two things
$a = ?$b;               # nullable variable, or
$a =? $b;               # nullable operator...

More feedback?

Thank you
 [2020-06-03 11:24 UTC] bugreports at gmail dot com
> I want to be able to assign a variable without knowing if is set or not

$x ??= 'my default'; does exactly that
 [2020-06-03 11:38 UTC] valentiny510 at gmail dot com
Not in 7.4.3
What version? I have seen the RFC, but I don't think is implemented yet
 [2020-06-03 11:42 UTC] valentiny510 at gmail dot com
btw, thank you

and still ??= is 1 character larger than =?
:P
it should be only ?= just like the others += *= etc...
 [2020-06-03 11:50 UTC] bugreports at gmail dot com
> What version? I have seen the RFC, but I don't think is implemented yet

why don't you just do your homework and at least read the feature page of each new release or at least try it out instead of thinking?

> and still ??= is 1 character larger than =?

that's ridiculous and null coalescing is always ?? so you don't have any point because it's more important to be consistent within a programming language instead save one char

https://www.php.net/manual/de/migration74.new-features.php
Null coalescing assignment operator ΒΆ

<?php
$array['key'] ??= computeDefault();
// is roughly equivalent to
if (!isset($array['key'])) {
    $array['key'] = computeDefault();
}
?>
 [2020-06-03 11:51 UTC] valentiny510 at gmail dot com
oh sorry, is implemented, BUT... it DOESN'T do what I want, 
I don't want to set a "default"
$a ??= $b;
where $b doesn't exists, still throw the error "Undefined variable: $b"
 [2020-06-03 12:02 UTC] bugreports at gmail dot com
> $a ??= $b;
> where $b doesn't exists, still throw the error "Undefined variable: $b"

which is a good thing, i haven't seen "Undefined variable" in code which should not be fixed the last 15 years and you should ask yourself why $b is undefined here
 [2020-06-03 12:05 UTC] valentiny510 at gmail dot com
The example you gave $array['key'] ??= computeDefault(); is pointless,
To ASSIGN a default value for $a can be achived "normally"
$a = $b ?? compute_default( );
I want the ASSIGNMENT of $a to be NULLABLE if $b is NOT SET
$a = $b;
var_dump($a); null (without any errors!)

So I don't want the MANUALLY write
$array['key'] ??= NULL;
COMPRENDE? 

Is the Exact behaviour I was talking about...
Damn, you guys confused me for a bit
 [2020-06-03 13:39 UTC] cmb@php.net
-Status: Feedback +Status: Suspended
 [2020-06-03 13:39 UTC] cmb@php.net
This is obviously controversial (and there may be alternative
solutions), so requires discussion for which this bug tracker is
not suitable.  Instead, please send a mail to the internals
mailing list[1].  For the time being, I'm suspending this ticket.

Thanks.

[1] <https://www.php.net/mailing-lists.php#internals>
 [2020-06-03 14:30 UTC] valentiny510 at gmail dot com
To resume...
Yes, having the "Undefined variable: x" error is good, unless you Specifically
supress that error with a mechanism like, $a = @$b; (btw this doesn't work either...)

When I say I was looked at the RFC before, it was because I thought for a split second
that the equal sign changed the behaviour and NULLIFY the $b variable, but then
I was like "nah.. not possible", and of course is not...

The coalesce operator is Great, with the small exception that you
MUST have a FALLBACK value, EVEN IF that value is NULL...

What I requested is an operator that doesn't require any
FALLBACK and automatically NULLIFY the ASSIGMENT

There are plenty of options, aside from the ones I already mentioned,
maybe even we can reuse the "old" ternary/elvis operator like this
$a = $b ?:; without requiring to have the last value either

Some examples...
$a = ?$b;   # like nullable types (but require to have at least one space in between...)
$a =? $b;   # preferred operator (so the parser can ignore all the spaces...)
$a = @$b;   # maybe supress the error and return null?
$a ?= $b;   # one sign to not interfere with ??=
$a = $b ?:; # elvis2.0? but why not shorter...
$a = $b ?;  # the parser can say "after ? if you find ; assign null"
$a |= $b;   # weird but...
There are so many other symbols to choose from...

Is not that hard to understand what I want
 [2020-06-03 14:37 UTC] valentiny510 at gmail dot com
ups, typo...
instead of
$a |= $b;
I meant...
$a \= $b;

(my pinky didn't reached that far)
 [2020-06-03 17:55 UTC] requinix@php.net
> $a = @$b; (btw this doesn't work either...)
Yes it does. https://3v4l.org/03cuu

For more complicated expressions you can promote the @ to the whole assignment:
> @$a = $b + $c;
 [2020-06-03 18:28 UTC] valentiny510 at gmail dot com
You don't get it either...
Your example "https://3v4l.org/03cuu" produce the same error for Either...
$a = @$b; or
@$a = $b;

"Notice: Undefined variable: b in /in/03cuu on line 3"

I want to get rid of the error message and have a short operator that assign the null to the variable $a automatically but ONLY IF $b doesn't exists...
like "self casting to null" or similar...
$a = (null?) $b;

I really don't know what to say to make myself understandable more than I already did...

Thank you for your time guys
 [2020-06-03 18:48 UTC] valentiny510 at gmail dot com
Just think what the coalence operator do (in +/- english...)
$a = $b ?? null;

1. create $a =
2. Evaluate the "expression $b" to null
3. go to the next "expression"
4. Evaluate the "expression null" to null
5. ask if there are more expressions and if there are not return the null from step 4

The step 2 was ALREADY EVALUATED to null, and I can I ASK the parser,
"If you find this operator, (placeholder)... give me whatever you
Evaluated on the step 2 no matter what it is, its value or null otherwise"

so it will skip all the next steps 3, 4, 5, etc...
and as you can see, there are Two expressions that evaluates to null,
and is why I said I think that is a bit redundant, and maybe...
just maybe, returning whatever it is in the step 2 can improve the speed in some cases.
 [2020-06-03 18:51 UTC] requinix@php.net
> You don't get it either...
Let me spell this out for you:

1 <?php
2
3 $a = $b;
4 $c = @$d;

Line 3 produces a warning. Of course it does.

Line 4 DOES NOT.
 [2020-06-03 19:21 UTC] valentiny510 at gmail dot com
I just checked and realized that the SDTERR handler doesn't have
if (!($code & error_reporting( )))
    return; # Error silenced "@"

Sorry, mea culpa... for the $a = @$b; example
(third party software...)

but still feels like I'm cheating somehow, because you know that the error happend, the parser triggered the error, but you just choose to silence it like you can silence
many other errors, is not exactly the same as coalescing
and I maintain the position with other symbols/operators
 [2020-06-03 19:36 UTC] valentiny510 at gmail dot com
You can see the @ operator as a general purpose "error messages supresser".
A "null assigner" or whatever you want to call it, have a different implementation and can be a bit faster, (negligeable but still...)
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sat Aug 15 18:01:26 2020 UTC