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:57] – bp1222 | rfc:chaining_comparison [2016/12/22 16:22] – 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 allow this to be functionally the same | ||
+ | */ | ||
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 ===== | ||
+ | Proposals herein will contain a dump of relevant AST (php-ast) nodes and OPCodes (vld) to better visualize the compilation, | ||
==== Comparison Chaining ==== | ==== Comparison Chaining ==== | ||
- | The proposal creates a new AST operation type '' | + | The proposal creates a new AST operation type '' |
- | + | ||
- | The proposal also changes the precedence | + | |
<file php> | <file php> | ||
Line 67: | Line 66: | ||
| | ||
| | ||
- | | + | |
| | ||
- | | + | |
- | | + | |
| | ||
*/ | */ | ||
Line 112: | Line 111: | ||
* | * | ||
| | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
*/ | */ | ||
</ | </ | ||
- | ==== Combined Uses (Open Discussion Topic)==== | + | ===== Backward Incompatible Changes ===== |
- | One of the concerns raised in the implementation of this feature would be how to handle | + | BC Breaking changes expected depending on open-issue answers |
+ | |||
+ | ===== Proposed PHP Version(s) ===== | ||
+ | Next PHP (currently 7.2) | ||
+ | |||
+ | ===== RFC Impact ===== | ||
+ | ==== To Opcache ==== | ||
+ | I'm unsure; we're adding new op-codes and/or order of opcodes, but are not introducing any new codes | ||
+ | |||
+ | ===== Open Issues ===== | ||
+ | ====Should equality and comparison | ||
+ | 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. | ||
<file php> | <file php> | ||
<?php | <?php | ||
- | $a = 1; | ||
- | $b = 4; | ||
- | $c = 10; | ||
- | var_dump($a < 2 == 3 < $b < 5 == 20 > $c); // bool(true) | + | /* |
+ | * PHP <= 7.1 | ||
+ | */ | ||
+ | var_dump(1 < 2 == 3 < 4); // bool(true) | ||
+ | var_dump(1 < 2 == 3 < 4 == 5 < 6) // Syntax Error | ||
/* | /* | ||
- | | + | |
- | * | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
*/ | */ | ||
+ | var_dump(1 < 2 == 3 < 4); // bool(true) | ||
+ | var_dump(1 < 2 == 3 < 4 == 5 < 6) // bool(true) | ||
/* | /* | ||
- | | + | |
- | * | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
*/ | */ | ||
+ | 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) | ||
</ | </ | ||
- | ===== Backward Incompatible Changes ===== | + | ==== Right Recursion |
- | No BC Breaking changes expected | + | Another syntax difference that could be BC problematic is with right-recursion of the chained expression. |
- | ===== Proposed PHP Version(s) ===== | + | <file php> |
- | Next PHP (currently 7.2) | + | <?php |
+ | var_dump(1 < (2 < 3)); | ||
+ | var_dump(1 < 2 == 3); | ||
+ | var_dump(1 < 2 == 3 == 4); | ||
+ | var_dump(1 < 2 == (3 == 4)); | ||
+ | </ | ||
- | ===== RFC Impact ===== | + | We will go over how PHP 7.1 currently would evaluate each, and then how a right-recursive chain would pan out. |
- | ==== To Opcache ==== | + | <file php> |
- | Yes, we're adding new JMPZ_EX codes when chaining to ensure false values correctly jump over any pre/post inc/dev ops from eval. | + | <?php |
+ | var_dump(1 < (2 < 3)); | ||
+ | /* | ||
+ | * 1 < (2 < 3) := 1 < true := false | ||
+ | */ | ||
- | ===== Open Issues ===== | + | var_dump(1 < 2 == 3); |
- | ====Should equality and comparison expressions be treated as same precedence? | + | /* |
- | This is a tough question. | + | |
+ | */ | ||
- | Why is this even a question? | + | 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 | ||
+ | <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 | ||
===== 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 205: | Line 252: | ||
===== Patches and Tests ===== | ===== Patches and Tests ===== | ||
- | A Proposed Implementaiton: https:// | + | Implementation #1: comparisons evaluated before equality: https:// |
+ | |||
+ | Implementation #2: comparisons and equality evaluated together: https:// | ||
Will need eyes of those more familiar with AST/VM to review. | Will need eyes of those more familiar with AST/VM to review. | ||
Line 215: | Line 264: | ||
===== 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