rfc:operator_functions

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:operator_functions [2017/09/08 23:00] ajfrfc:operator_functions [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== PHP RFC: Operator functions ====== ====== PHP RFC: Operator functions ======
-  * Version: 1.0.1+  * Version: 1.0.2
   * Date: 2017-09-08   * Date: 2017-09-08
   * Author: Andrea Faulds, ajf@ajf.me   * Author: Andrea Faulds, ajf@ajf.me
Line 62: Line 62:
 <code php> <code php>
 // Select only the positive numbers // Select only the positive numbers
-$positiveSubset = array_filters($numbers, partialApply('>', 0));+$positiveSubset = array_filter($numbers, partialApply('<', 0));
 </code> </code>
 +
 +An example working partial application implementation would be:
 +
 +<file php partialApply.php>
 +function partialApply(callable $c, ...$args) {
 +    return function (...$args2) use ($c, $args) {
 +        return $c(...$args, ...$args2);
 +    };
 +}
 +</file>
  
 ==== Detail ==== ==== Detail ====
Line 78: Line 88:
 The table below lists the new functions that would be added to the root namespace (''\''). Each is named the same as its corresponding operator, including any aliases (for the sake of consistency). The table below lists the new functions that would be added to the root namespace (''\''). Each is named the same as its corresponding operator, including any aliases (for the sake of consistency).
  
-^ Function signature        ^ Corresponding operation             ^ +^ Function signature        ^ Corresponding operation             Notes                       ^ 
-^ <php>'+'($a[, $b])</php>  <php>+$a</php>, <php>$a + $b</php>  ^ +<php>'+'($a[, $b])</php>  <php>+$a</php>, <php>$a + $b</php>  |                             | 
-<php>'-'($a[, $b])</php>  <php>-$a</php>, <php>$a - $b</php>  ^ +<php>'-'($a[, $b])</php>  <php>-$a</php>, <php>$a - $b</php>  |                             | 
-<php>'*'($a, $b)</php>    <php>$a * $b</php>                  ^ +<php>'*'($a, $b)</php>    <php>$a * $b</php>                  |                             | 
-<php>'/'($a, $b)</php>    <php>$a / $b</php>                  ^ +<php>'/'($a, $b)</php>    <php>$a / $b</php>                  |                             | 
-<php>'%'($a, $b)</php>    <php>$a % $b</php>                  ^ +<php>'%'($a, $b)</php>    <php>$a % $b</php>                  |                             | 
-<php>'**'($a, $b)</php>   <php>$a ** $b</php>                 ^ +<php>'**'($a, $b)</php>   <php>$a ** $b</php>                 |                             | 
-<php>'&'($a, $b)</php>    <php>$a & $b</php>                  ^ +<php>'&'($a, $b)</php>    <php>$a & $b</php>                  |                             | 
-<php>'|'($a, $b)</php>    <php>$a | $b</php>                  ^ +<php>'|'($a, $b)</php>    <php>$a | $b</php>                  |                             | 
-<php>'^'($a, $b)</php>    <php>$a ^ $b</php>                  ^ +<php>'^'($a, $b)</php>    <php>$a ^ $b</php>                  |                             | 
-<php>'~'($a)</php>        <php>~$a</php>                      ^ +<php>'~'($a)</php>        <php>~$a</php>                      |                             | 
-<php>'<<'($a, $b)</php>   <php>$a << $b</php>                 ^ +<php>'<<'($a, $b)</php>   <php>$a << $b</php>                 |                             | 
-<php>'>>'($a, $b)</php>   <php>$a >> $b</php>                 ^ +<php>'>>'($a, $b)</php>   <php>$a >> $b</php>                 |                             | 
-<php>'=='($a, $b)</php>   <php>$a == $b</php>                 ^ +<php>'=='($a, $b)</php>   <php>$a == $b</php>                 |                             | 
-<php>'==='($a, $b)</php>  <php>$a === $b</php>                ^ +<php>'==='($a, $b)</php>  <php>$a === $b</php>                |                             | 
-<php>'!='($a, $b)</php>   <php>$a != $b</php>                 ^ +<php>'!='($a, $b)</php>   <php>$a != $b</php>                 |                             | 
-<php>'<>'($a, $b)</php>   <php>$a <> $b</php>                 ^ +<php>'<>'($a, $b)</php>   <php>$a <> $b</php>                 |                             | 
-<php>'!=='($a, $b)</php>  <php>$a !== $b</php>                ^ +<php>'!=='($a, $b)</php>  <php>$a !== $b</php>                |                             | 
-<php>'<'($a, $b)</php>    <php>$a < $b</php>                  ^ +<php>'<'($a, $b)</php>    <php>$a < $b</php>                  |                             | 
-<php>'>'($a, $b)</php>    <php>$a > $b</php>                  ^ +<php>'>'($a, $b)</php>    <php>$a > $b</php>                  |                             | 
-<php>'<='($a, $b)</php>   <php>$a <= $b</php>                 ^ +<php>'<='($a, $b)</php>   <php>$a <= $b</php>                 |                             | 
-<php>'>='($a, $b)</php>   <php>$a >= $b</php>                 ^ +<php>'>='($a, $b)</php>   <php>$a >= $b</php>                 |                             | 
-<php>'<=>'($a, $b)</php>  <php>$a <=> $b</php>                ^ +<php>'<=>'($a, $b)</php>  <php>$a <=> $b</php>                |                             | 
-<php>'&&'($a, $b)</php>   <php>$a <=> $b</php>                ^ +<php>'&&'($a, $b)</php>   <php>$a && $b</php>                 | Can't fully short-circuit.  | 
-<php>'and'($a, $b)</php>  <php>$a and $b</php>                ^ +<php>'and'($a, $b)</php>  <php>$a and $b</php>                | Can't fully short-circuit.  | 
-<php>'||'($a, $b)</php>   <php>$a || $b</php>                 ^ +<php>'||'($a, $b)</php>   <php>$a || $b</php>                 | Can't fully short-circuit.  | 
-<php>'or'($a, $b)</php>   <php>$a or $b</php>                 ^ +<php>'or'($a, $b)</php>   <php>$a or $b</php>                 | Can't fully short-circuit.  | 
-<php>'xor'($a, $b)</php>  <php>$a xor $b</php>                ^ +<php>'xor'($a, $b)</php>  <php>$a xor $b</php>                |                             | 
-<php>'!'($a)</php>        <php>!$a</php>                      ^ +<php>'!'($a)</php>        <php>!$a</php>                      |                             | 
-<php>'.'($a, $b)</php>    <php>$a . $b</php>                  ^+<php>'.'($a, $b)</php>    <php>$a . $b</php>                  |                             |
  
 Since <php>pow()</php> already exists and behaves identically to how <php>'**'()</php> would, <php>'**'()</php> is simply an alias of it. Since <php>pow()</php> already exists and behaves identically to how <php>'**'()</php> would, <php>'**'()</php> is simply an alias of it.
- 
-This table notably lacks <php>$a instanceof $b</php>, <php>$a[$b]</php> and <php>$a->$b</php>, these latter two being “operators” that the PHP manual does not categorise as such. There may be an argument for adding these latter two. There might be an argument for adding the assignment operators (<php>=</php>, <php>+=</php> etc.) as well, though they don't provide much useful functionality on top of this existing set and since they would use references, are not usable in some common high-order function scenarios. 
  
 These functions do not perform any extra type checking on their arguments beyond that normally performed by the operators they correspond to. These functions do not perform any extra type checking on their arguments beyond that normally performed by the operators they correspond to.
 +
 +==== Missing operators ====
 +
 +The table above (like the patch) currently contains all the operators in the [[http://php.net/manual/en/language.operators.php|Operators section of the PHP Manual]], minus <php>instanceof</php>, <php>`backticks`</php> and the assignment operators. Whether these should have functions too is a matter to debate; <php>instanceof</php> doesn't take arbitrary expressions and already has a functional counterpart (<php>is_a</php>). As for the assignment operators, references mean they could be done, but from a functional programming perspective they have limited utility.
 +
 +PHP also has some other constructs that could be classed as operators but aren't considered such by the manual. A (possibly non-exhaustive) list is:
 +
 +  * <php>??</php> (Can't <php>isset()</php>. Can't short-circuit.)
 +  * <php>?:</php> (Could be <php>'?:'($a, $b[, $c])</php> and map to <php>$a ?: $b</php> or <php>$a ? $b : $c</php> depending on parameter count. Can't short-circuit.)
 +  * <php>@</php> (Could not be made a function without changing it to act on a callable.)
 +  * <php>(int)</php>, <php>(string)</php> etc. (Note <php>intval()</php> etc already exist.)
 +  * <php>clone</php>
 +  * <php>print</php> (This always returns 1, so we might as well make <php>echo</php> a function too even though it's a statement.)
 +  * <php>-></php> (How do you distinguish between property lookup and method calls? Are identifiers replaced with strings?)
 +  * <php>[]</php> (Array indexing.)
 +  * <php>()</php> (Function invocation. <php>call_user_func</php> exists already.)
 +  * <php>eval</php> (Probably not a good rabbit hole to go down, this requires frowned-upon stack gymnastics due to affecting the current scope.)
 +  * <php>include</php>, <php>require</php>, <php>include_once</php>, <php>require_once</php>
 +  * <php>yield</php> (Like <php>eval</php>, would require dubious stack gymnastics. It is a control-flow expression, not merely manipulating values.)
 +
 +Of these, <php>-></php>, <php>()</php>, <php>@</php> and <php>eval</php> are the most dubious.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
-All of these operator functions create no backwards-compatibility break, since they have names that cannot be used for userland functions, and thus they cannot possibly conflict with existing code (except that using exotic extensions like runkit). +All of these operator functions create no backwards-compatibility break, since they have names that cannot be used for userland functions, and thus they cannot conflict with function names in existing code (hypothetically this may not be true if using exotic extensions like runkit). 
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
Line 129: Line 158:
  
 ===== Open Issues ===== ===== Open Issues =====
-None.+See “Missing operators” section.
  
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
 The existing operators themselves behave the same as ever. The existing operators themselves behave the same as ever.
  
-Quoting function names in function calls is not new, it is a consequence of [[rfc:uniform_variable_syntax|Uniform Variable Syntax]].+Being able to quote function names in function calls (e.g. <php>'+'(1, 1)</php>is not new idea introduced by this RFC, it has been possible since [[rfc:uniform_variable_syntax|Uniform Variable Syntax]] in PHP 7.0.
  
 ===== Future Scope ===== ===== Future Scope =====
Line 158: Line 187:
  
 ===== References ===== ===== References =====
 +  * PHP manual operators section: http://php.net/manual/en/language.operators.php
   * Haskell's infix functions (any normal operator is a function and vice-versa) were an inspiration.   * Haskell's infix functions (any normal operator is a function and vice-versa) were an inspiration.
  
Line 165: Line 195:
 ===== Changelog ===== ===== Changelog =====
  
 +  * v1.0.2 - add subsection discussing omissions
   * v1.0.1 - acknowledge why certain operators are excluded   * v1.0.1 - acknowledge why certain operators are excluded
   * v1.0 - first public non-draft version   * v1.0 - first public non-draft version
rfc/operator_functions.1504911600.txt.gz · Last modified: 2017/09/22 13:28 (external edit)