rfc:chaining_comparison
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:chaining_comparison [2016/12/12 17:40] – bp1222 | rfc:chaining_comparison [2017/02/12 18:59] – bp1222 | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: Chaining Comparison ====== | ====== PHP RFC: Chaining Comparison ====== | ||
- | * Version: 0.1 | + | * Version: 0.2 |
- | * Date: 2016-12-08 | + | * Date: 2016-12-13 |
- | * Author: David Walker (dave@mudsite.com), Richard Fussenegger (php@fleshgrinder.com) | + | * Author: David Walker (dave@mudsite.com) |
+ | * Author: | ||
* Status: Draft | * Status: Draft | ||
* First Published at: http:// | * First Published at: http:// | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | The point of this RFC is to allow the chaining together of comparison and equality operations | + | This RFC proposes a syntax change |
- | Today such comparisons must be written as such: | ||
<file php> | <file php> | ||
<?php | <?php | ||
$a = 10; | $a = 10; | ||
+ | /* | ||
+ | * The initial request of this proposal was to change the following syntax | ||
+ | */ | ||
if (0 < $a && $a < 100) { | if (0 < $a && $a < 100) { | ||
echo "Value is between 0 and 100\n"; | echo "Value is between 0 and 100\n"; | ||
} | } | ||
- | </ | ||
- | |||
- | The proposal of this RFC is to allow new syntax as follows: | ||
- | <file php> | ||
- | <?php | ||
- | $a = 10; | ||
+ | /* | ||
+ | * To be functionally equivalent to this syntax | ||
+ | */ | ||
if (0 < $a < 100) { | if (0 < $a < 100) { | ||
echo "Value is between 0 and 100\n"; | echo "Value is between 0 and 100\n"; | ||
Line 30: | Line 30: | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | The proposal creates a new AST operation type '' | + | Proposals herein |
- | The proposal | + | ==== Comparison Chaining ==== |
+ | The proposal | ||
<file php> | <file php> | ||
Line 39: | Line 40: | ||
$b = 10; | $b = 10; | ||
- | var_dump($a < 5 < $b++); | + | var_dump($a < 5 < $b++); |
/* | /* | ||
* AST Dump | * AST Dump | ||
- | | + | * |
- | | + | * 2: |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
+ | | ||
*/ | */ | ||
Line 65: | Line 67: | ||
| | ||
| | ||
- | | + | |
| | ||
- | | + | |
- | | + | |
| | ||
*/ | */ | ||
</ | </ | ||
- | So we can see what this feature will do internally. | + | So we can see what this feature will do internally. |
+ | |||
+ | ==== Equality Chaining ==== | ||
+ | The proposal is also extended to allow chaining of equality operators. | ||
+ | |||
+ | <file php> | ||
+ | <?php | ||
+ | $a = 1; | ||
+ | $b = 10; | ||
+ | |||
+ | var_dump($a == 1 === true); // bool(true) | ||
+ | |||
+ | /* | ||
+ | * AST Dump | ||
+ | * | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | */ | ||
+ | |||
+ | /* | ||
+ | * OPCodes | ||
+ | * | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | */ | ||
+ | </ | ||
+ | |||
+ | ==== False Short Circuiting ==== | ||
+ | In doing this compilation we can ensure short cutting of righter operations if the left sides have evaluated to false. | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | No BC Breaking changes expected | + | BC Breaking changes expected |
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
Line 83: | Line 130: | ||
===== RFC Impact ===== | ===== RFC Impact ===== | ||
==== To Opcache ==== | ==== To Opcache ==== | ||
- | Yes, we're adding new JMPZ_EX | + | I'm unsure; |
===== Open Issues ===== | ===== Open Issues ===== | ||
+ | ====Should equality and comparison expressions be treated as same precedence? | ||
+ | This is harder of a question that it seems. | ||
+ | '' | ||
+ | |||
+ | Why is this even a question, much less a challenging one? Well, a seemingly majority of languages '' | ||
+ | |||
+ | It is important to point out that the example syntax is currently valid in PHP 7.1. PHP 7.1 currently has a C-like precedence where '' | ||
+ | |||
+ | <file php> | ||
+ | <?php | ||
+ | |||
+ | /* | ||
+ | * PHP <= 7.1 | ||
+ | */ | ||
+ | var_dump(1 < 2 == 3 < 4); // bool(true) | ||
+ | var_dump(1 < 2 == 3 < 4 == 5 < 6) // Syntax Error | ||
+ | |||
+ | /* | ||
+ | * Proposed Chaining, comparators evaluated first; equality second [See: Implementation #1] | ||
+ | */ | ||
+ | var_dump(1 < 2 == 3 < 4); // bool(true) | ||
+ | var_dump(1 < 2 == 3 < 4 == 5 < 6) // bool(true) | ||
+ | |||
+ | /* | ||
+ | * Proposed Strict Chaining [See: Implementation #2] | ||
+ | */ | ||
+ | var_dump(1 < 2 == 3 < 4); // bool(false) | ||
+ | var_dump(1 < 2 == 3 < 4 == 5 < 6) // bool(false) | ||
+ | var_dump((1 < 2) == (3 < 4) == (5 < 6)) // bool(true) | ||
+ | </ | ||
+ | |||
+ | ==== Right Recursion ==== | ||
+ | Another syntax difference that could be BC problematic is with right-recursion of the chained expression. | ||
+ | |||
+ | <file php> | ||
+ | <?php | ||
+ | var_dump(1 < (2 < 3)); | ||
+ | var_dump(1 < 2 == 3); | ||
+ | var_dump(1 < 2 == 3 == 4); | ||
+ | var_dump(1 < 2 == (3 == 4)); | ||
+ | </ | ||
+ | |||
+ | We will go over how PHP 7.1 currently would evaluate each, and then how a right-recursive chain would pan out. | ||
+ | <file php> | ||
+ | <?php | ||
+ | var_dump(1 < (2 < 3)); | ||
+ | /* | ||
+ | * 1 < (2 < 3) := 1 < true := false | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == 3); | ||
+ | /* | ||
+ | * (1 < 2) == 3 := true == 3 := true | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == 3 == 4); | ||
+ | /* | ||
+ | * Parse Error, unexpected == | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == (3 == 4)); | ||
+ | /* | ||
+ | * (1 < 2) == (3 == 4) := true == false := false | ||
+ | */ | ||
+ | </ | ||
+ | |||
+ | The current proposal (implemented) evaluation method. | ||
+ | <file php> | ||
+ | <?php | ||
+ | var_dump(1 < (2 < 3)); | ||
+ | /* | ||
+ | * Parse Error: No right recursion | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == 3); | ||
+ | /* | ||
+ | * (1 < 2) == 3 := true == 3 := true | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == 3 == 4); | ||
+ | /* | ||
+ | * ((1 < 2) == 3) == 4 := (true == 3) == 4 := true == 4 := true | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == (3 == 4)); | ||
+ | /* | ||
+ | * (1 < 2) == (3 == 4) := true == false := false | ||
+ | */ | ||
+ | </ | ||
+ | |||
+ | If however we permitted right recursive comparison operations we would evaluate as such: | ||
+ | <file php> | ||
+ | <?php | ||
+ | var_dump(1 < (2 < 3)); | ||
+ | /* | ||
+ | * 1 < (2 < 3) := 1 && (2 < 3) && (1 < 2) := true && true && true := true | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == 3); | ||
+ | /* | ||
+ | * (1 < 2) == 3 := true == 3 := true | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == 3 == 4); | ||
+ | /* | ||
+ | * ((1 < 2) == 3) == 4 := (true == 3) == 4 := true == 4 := true | ||
+ | */ | ||
+ | |||
+ | var_dump(1 < 2 == (3 == 4)); | ||
+ | /* | ||
+ | * (1 < 2) == (3 == 4) := true == false := false | ||
+ | */ | ||
+ | </ | ||
+ | |||
+ | If the first example in this last one looks a little odd, it's because it is. We do design for short-cutting of a long expression when a fault is found to prevent further execution much like you have in '' | ||
+ | |||
+ | Although allow right-recursion of equality operations does itself introduce some slightly odd syntax like: | ||
+ | <file php> | ||
+ | <?php | ||
+ | /* | ||
+ | * Right chained comparison syntax | ||
+ | */ | ||
+ | var_dump(1 < (2 == 2)); // bool(false) | ||
+ | |||
+ | /* | ||
+ | * Is Functionally identical to PHP 7.1's allowed syntax | ||
+ | */ | ||
+ | var_dump(1 < (2 <= 2)); // bool(false) | ||
+ | </ | ||
+ | Since we don't chain together the right/left node of an equality operator, this is functionally identical to PHP 7.1's allowed syntax. | ||
+ | |||
+ | |||
+ | As we can see right-recursive comparison operations do have numerous caveats and oddities. | ||
===== Unaffected PHP Functionality ===== | ===== Unaffected PHP Functionality ===== | ||
Does not alter the operation of the comparison Spaceship [<=>] operator. | Does not alter the operation of the comparison Spaceship [<=>] operator. | ||
- | |||
- | ===== Future Scope ===== | ||
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== | ||
Line 96: | Line 274: | ||
===== Patches and Tests ===== | ===== Patches and Tests ===== | ||
- | A Proposed Implementaiton: https:// | + | Working Implementation: |
Will need eyes of those more familiar with AST/VM to review. | Will need eyes of those more familiar with AST/VM to review. | ||
- | |||
- | For changes affecting the core language, you should also provide a patch for the language specification. | ||
===== Implementation ===== | ===== Implementation ===== | ||
Line 106: | Line 282: | ||
===== References ===== | ===== References ===== | ||
- | Initial idea on Internals: | + | * [1] - [[http:// |
+ | * [2] - [[https:// | ||
+ | * [3] - [[https:// | ||
+ | * [4] - [[http:// | ||
+ | * [5] - [[https:// | ||
+ | * [6] - [[http:// | ||
+ | * [7] - [[https:// | ||
+ | * [8] - [[http:// | ||
===== Rejected Features ===== | ===== Rejected Features ===== | ||
Keep this updated with features that were discussed on the mail lists. | Keep this updated with features that were discussed on the mail lists. |
rfc/chaining_comparison.txt · Last modified: 2021/03/27 14:58 by ilutov