Conversation
Contributor
Just trying to initiate some movement for https://wiki.php.net/rfc/nullable-casting (including settype() as requested in https://externals.io/message/102997#102999) ๐
/cc @rentalhost (author of the RFC)
I made some choices open to discussion, for example not supporting (?unset) at all but allowing settype($x, '?null') with a notice (which I found simpler for a start).
The new tests are essentially minimally-modified copies of existing ones.
Questions:
- How to test the OPcache part?
- How to evaluate the impact on performance?
- Is defining a new
T_NULLABLE_<TYPE>_CASTtoken for eachT_<TYPE>_CAST(exceptT_UNSET_CAST) like I did, the "right" way? - Would adding a new "
ZEND_AST_NULLABLE_CAST" node and/or a new "ZEND_NULLABLE_CAST" opcode be better than extending the existingZEND_AST_CASTandZEND_CASTwith theZEND_TYPE_NULLABLEflag like I did?
Contributor
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Zend/tests/cast_to_array-nullable.phpt test is been considering as a new Binary file for some reason
Contributor Author
@carusogabriel This is expected.
Details It's because the file contains some NUL character (in the--EXPECTF-- section, output of a var_dump() of "\0"). GitHub does not show the contents in its diff view but you can click the "View file" button: at line 67 I see string(1) "" but there is actually an invisible NUL between the quotes (see e.g. https://3v4l.org/luX7q, and also https://3v4l.org/j1Q3D).
It was copied as-is from the existing Zend/tests/cast_to_array.phpt (diff between the two files: https://www.diffchecker.com/Zqoo2T6f). Same for the cast_to_object and cast_to_string tests.
(BTW there is a trailing space in ext/tokenizer/tests/token_get_all_variation8-nullable.phpt after <?php at line 21: it was copied as-is from the existing token_get_all_variation8.phpt and is even actually tested at line 43, and I didn't want to introduce extra changes in this PR. Which is why I also didn't change the existing in %s line %d to in %s on line %d in Zend/tests/cast_to_string[-nullable].phpt.)
Member
FWIW re-reading that internals thread, the reception is somewhat mixed, but I think it still makes sense to put the RFC to voting.
Contributor Author
@nikic: Thanks for your time. But now we have union types (which I consider much more important than nullable casting, by the way!), so people will probably want the RFC to include the (int|null) $x syntax, and then what about e.g. (int|string) $x or (int|string|null) $x?
Anyway I didn't (and won't) have the time to keep this PR up to date, so it wasn't really making sense to let it open...
@guilliamxavier casting with union types seems a bit confuses and restrict.
For instance, (Foo|Bar) $foobar should be instanceof Foo or instanceof Bar?
Same for your example (int|string|null) $x will returns what exactly? Since (bool) $x will returns a bool.
So I still thinks that nullable casting will works better and will match with an existing feature like typed properties and parameters.
Contributor Author
@rentalhost: Casting is only to primitive types, so (Foo|Bar) $foobar would not be a possible cast, just like (Foo) $foobar is not.
As for hypothetical (int|string|null) $x I suppose it could follow the same logic as https://wiki.php.net/rfc/union_types_v2#coercive_typing_mode but I don't want to think too much about it. As I said, "people will probably want" various things (that I personally wouldn't necessarily).
Member
Good point about the union types. There could indeed be a reasonable expectation that once (?T) is supported, it works with everything allowed in type declarations.
If we had generics (haha), we could do a C++ style cast that would automatically support all types and have the same semantics as weak type coercions:
declare(strict_types=0);
function cast<T>($val): T {
return $val;
}
$x = cast<?int>($y);
$foo = cast<int|float>($bar);
Contributor Author
@rentalhost: unlikely, given the lack of consensus (and the increasing divergence of type declarations [now with union types] vs casts [fixed tokens])... But actually I find nikic's idea more promising