rfc:nullable-casting
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:nullable-casting [2018/08/07 16:12] – created david.proweb | rfc:nullable-casting [2019/03/17 15:17] – Revamp draft 0.2, add settype and example guilliamxavier | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: Nullable Casting ====== | ====== PHP RFC: Nullable Casting ====== | ||
- | * Version: 0.9 | + | * Version: 0.2-draft |
- | * Date: 2018-08-07 | + | * Date: 2019-03-17 |
- | * Author: David Rodrigues, david.proweb@gmail.com | + | * Author: David Rodrigues |
* Status: Draft | * Status: Draft | ||
- | * Discussion | + | * First Published |
===== Introduction ===== | ===== Introduction ===== | ||
- | PHP supports expression casting by using '' | + | PHP supports expression casting |
+ | |||
+ | Due to the lack of support for nullable casting, | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | The proposal is to add support | + | The proposal is to add support |
- | The difference | + | The only difference |
- | ^ Input ^ (cast) - default | + | ^ // |
- | | int (123) | int (123) | int (123) | Yes | | + | ^ '' |
- | | null | int (0) | + | ^ '' |
- | | bool (true) | + | |
- | | bool (false) | + | |
- | | null | bool (false) | + | |
- | | float (1.23) | + | |
- | | null | float (0.0) | + | |
- | | string ("test") | string (" | + | |
- | | null | string | + | |
- | | array ([1, 2, 3]) | array ([1, 2, 3]) | array ([1, 2, 3]) | Yes | | + | |
- | | null | array ([]) | null | No | | + | |
- | | object ({ a => 1 }) | object ({ a => 1 }) | + | |
- | | null | object ({}) | null | No | + | |
+ | **Notes:** | ||
+ | * The '' | ||
+ | * The PHP parser is not sensitive to spaces in e.g. "'' | ||
+ | * The PHP parser does not distinguish between '' | ||
- | **Note: | + | If the expression value is not '' |
- | ====== Example ====== | + | ==== Additional proposal for settype() |
+ | |||
+ | Additionally, | ||
+ | |||
+ | In short, for a currently valid < | ||
+ | |||
+ | === "? | ||
+ | |||
+ | In < | ||
+ | |||
+ | Possible options: | ||
+ | - Allow it as equivalent to plain < | ||
+ | - Allow it as equivalent to plain < | ||
+ | - Disallow it and emit a specific Warning (like the existing " | ||
+ | - Disallow it and emit the existing generic Warning " | ||
+ | |||
+ | For demonstration, | ||
+ | |||
+ | ===== Motivating | ||
+ | |||
+ | In strict type-checking mode (< | ||
+ | |||
+ | < | ||
+ | function getInt(): int | ||
+ | { | ||
+ | return mt_rand(); | ||
+ | } | ||
+ | |||
+ | function processString(string $s): void | ||
+ | { | ||
+ | printf(" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | then the following call: | ||
+ | |||
+ | < | ||
+ | processString(getInt()); | ||
+ | </ | ||
+ | |||
+ | will throw a '' | ||
+ | |||
+ | < | ||
+ | processString((string) getInt()); | ||
+ | </ | ||
+ | |||
+ | (which will print something like " | ||
+ | |||
+ | Now given two functions like the following (with // | ||
+ | |||
+ | < | ||
+ | function getIntOrNull(): | ||
+ | { | ||
+ | $r = mt_rand(); | ||
+ | return $r % 2 === 0 ? $r : null; | ||
+ | } | ||
+ | |||
+ | function processStringOrNull(? | ||
+ | { | ||
+ | if ($s === null) { | ||
+ | printf(" | ||
+ | } else { | ||
+ | printf(" | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | then the following call: | ||
+ | |||
+ | < | ||
+ | processStringOrNull(getIntOrNull()); | ||
+ | </ | ||
+ | |||
+ | will sometimes work (print " | ||
+ | |||
+ | < | ||
+ | processStringOrNull((? | ||
+ | </ | ||
+ | |||
+ | but currently this syntax is not supported (" | ||
+ | |||
+ | < | ||
+ | processStringOrNull(($tmp = getIntOrNull()) === null ? null : (string) $tmp); | ||
+ | unset($tmp); | ||
+ | </ | ||
+ | |||
+ | or writing custom casting functions. | ||
+ | |||
+ | (Note that in //weak// type-checking mode, there is never a '' | ||
+ | |||
+ | ==== settype() ==== | ||
+ | |||
+ | When the desired type is not known before runtime, we cannot use a cast operator, but we can use the '' | ||
+ | |||
+ | < | ||
+ | function getIntOrNullAs(string $type) | ||
+ | { | ||
+ | $x = getIntOrNull(); | ||
+ | settype($x, $type); | ||
+ | return $x; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | but currently < | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
Line 43: | Line 141: | ||
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
- | PHP 7.NEXT, possibly | + | Next PHP 7.x (7.4 now). |
===== RFC Impact ===== | ===== RFC Impact ===== | ||
+ | |||
==== To SAPIs ==== | ==== To SAPIs ==== | ||
- | I need help here. | + | :?: //Help needed// |
==== To Existing Extensions ==== | ==== To Existing Extensions ==== | ||
- | I need help here, but I do not think so. | + | :?: //Help needed// |
==== To Opcache ==== | ==== To Opcache ==== | ||
- | I need help here. | + | :?: //Help needed// |
+ | |||
+ | ===== Unaffected PHP Functionality ===== | ||
+ | |||
+ | * The '' | ||
+ | * The < | ||
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== | ||
- | Voting process should requires '' | + | * **Accept nullable casting**: Simple vote (Yes / No), requiring a 2/3 majority to pass. |
+ | * **Additionally accept nullable settype()**: | ||
+ | * **How to handle settype($x, "? | ||
+ | |||
+ | (Each secondary vote result will be considered only if its parent vote passes.) | ||
===== Patches and Tests ===== | ===== Patches and Tests ===== | ||
- | I need help here. | + | * Working prototype: https:// |
+ | |||
+ | ===== References ===== | ||
+ | |||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[rfc: | ||
+ | * [[rfc: | ||
+ | * Initial discussion: https:// |
rfc/nullable-casting.txt · Last modified: 2019/04/21 09:03 by guilliamxavier