rfc:short-functions
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:short-functions [2020/10/23 21:48] – crell | rfc:short-functions [2021/06/15 22:29] (current) – Fix RFC status ilutov | ||
---|---|---|---|
Line 3: | Line 3: | ||
* Date: 2020-10-20 | * Date: 2020-10-20 | ||
* Author: Larry Garfield (larry@garfieldtech.com) | * Author: Larry Garfield (larry@garfieldtech.com) | ||
- | * Status: | + | * Status: |
- | * First Published at: http:// | + | * First Published at: http:// |
===== Introduction ===== | ===== Introduction ===== | ||
Line 19: | Line 19: | ||
function add(int $a, int $b): int | function add(int $a, int $b): int | ||
{ | { | ||
- | return $a + b; | + | return $a + $b; |
} | } | ||
</ | </ | ||
Line 48: | Line 48: | ||
Functions are simpler than lambdas, as there is no need for closing over variables contextually. | Functions are simpler than lambdas, as there is no need for closing over variables contextually. | ||
+ | ==== Consistency with closure syntax ==== | ||
+ | |||
+ | This RFC is designed to complement the [[rfc: | ||
+ | |||
+ | * The '' | ||
+ | * '' | ||
+ | * The '' | ||
+ | * The '' | ||
+ | * A function with a name is declared globally at compile time. A function without a name is declared locally as a closure at runtime. | ||
+ | |||
+ | These rules are easily recognizable and learnable by developers. | ||
+ | |||
+ | (Further discussion of the possible permutations, | ||
==== Reasoning ==== | ==== Reasoning ==== | ||
- | Many functions and methods are, in practice, simple expressions. | + | Many functions and methods are, in practice, simple expressions. |
- | Expressions are becoming increasingly capable, too. match() expressions and throw expressions in PHP 8.0, plus proposals such as [[rfc: | + | Expressions are becoming increasingly capable, too. match() expressions and throw expressions in PHP 8.0, plus proposals such as [[rfc: |
- | Expression functions are also more likely to avoid mutable state. | + | The trend in PHP in recent years has been toward |
- | ==== Examples ==== | + | ==== Pure functions ==== |
+ | |||
+ | Expression functions are also more likely to be pure, and thus avoid mutable state. | ||
+ | |||
+ | <code php> | ||
+ | |||
+ | $called = 0; | ||
+ | |||
+ | function fullName(string $first, string $last): string | ||
+ | => sprintf(' | ||
+ | </ | ||
+ | |||
+ | However, such code would be readily apparent as using global mutable state, and is easily avoided. | ||
+ | |||
+ | ===== Examples | ||
Below are some examples of "long form" current code and what the short function equivalent would be. This RFC asserts that the shorter version is more concise and readable. | Below are some examples of "long form" current code and what the short function equivalent would be. This RFC asserts that the shorter version is more concise and readable. | ||
- | === Match functions === | + | ==== Match functions |
A function that encapsulates a match() expression. | A function that encapsulates a match() expression. | ||
Line 90: | Line 117: | ||
</ | </ | ||
- | === Getter methods === | + | ==== Enum methods ==== |
+ | |||
+ | In practice, most enum methods are likely to contain only a match expression, the evaluated value of which should be returned. | ||
+ | |||
+ | <code php> | ||
+ | enum Suit | ||
+ | { | ||
+ | |||
+ | case Hearts; | ||
+ | case Diamonds; | ||
+ | case Clubs; | ||
+ | case Spades; | ||
+ | |||
+ | public function color(): string => match($this) { | ||
+ | static:: | ||
+ | static:: | ||
+ | }; | ||
+ | |||
+ | vs: | ||
+ | |||
+ | public function color(): string | ||
+ | { | ||
+ | return match($this) { | ||
+ | static:: | ||
+ | static:: | ||
+ | }; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Getter methods | ||
- | Many classes consist primarily or almost entirely | + | Many classes consist primarily or almost entirely of methods that either return a property, or some computation off of a property. |
<code php> | <code php> | ||
Line 137: | Line 195: | ||
</ | </ | ||
- | === Functional code === | + | ==== Functional code ==== |
<code php> | <code php> | ||
Line 161: | Line 219: | ||
</ | </ | ||
- | === Piped functions === | + | ==== Conditional methods |
- | + | ||
- | The pipe operator |> is still pending in an RFC, but the feedback on it before was generally positive. | + | |
- | + | ||
- | <code php> | + | |
- | function doAThing(User $u) | + | |
- | { | + | |
- | return $u |> ' | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | vs. | + | |
- | + | ||
- | <code php> | + | |
- | function doAThing(User $u) => $u | + | |
- | |> ' | + | |
- | |> ' | + | |
- | |> ' | + | |
- | |> ' | + | |
- | ; | + | |
- | </ | + | |
- | + | ||
- | Which is a really nice way to build up a pipeline through composition. | + | |
- | + | ||
- | === Conditional methods === | + | |
A common refactoring technique is to take a complex conditional in an if statement and move it to its own method, so it can be given a self-descriptive name. Such methods are naturally single-expression. | A common refactoring technique is to take a complex conditional in an if statement and move it to its own method, so it can be given a self-descriptive name. Such methods are naturally single-expression. | ||
Line 210: | Line 244: | ||
Which is more simple and compact than a full function body. | Which is more simple and compact than a full function body. | ||
- | === Decorating functions in live code === | + | ==== Decorating functions in live code ==== |
Often times, methods exist that are just delegating to some other method, either in the same object or a composed object. | Often times, methods exist that are just delegating to some other method, either in the same object or a composed object. | ||
Line 318: | Line 352: | ||
That can collapse to this (a bit reordered): | That can collapse to this (a bit reordered): | ||
- | |||
<code php> | <code php> | ||
Line 379: | Line 412: | ||
The => operator has de facto become the "maps to this expression" | The => operator has de facto become the "maps to this expression" | ||
- | The author favors using " | + | The use of the '' |
- | As of this time, this RFC is to use "function" | + | ===== Related RFCs ===== |
+ | |||
+ | A number | ||
+ | |||
+ | ==== Piped functions ==== | ||
+ | |||
+ | The [[rfc: | ||
+ | |||
+ | <code php> | ||
+ | function doAThing(User $u) | ||
+ | { | ||
+ | return $u |> ' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | vs. | ||
+ | |||
+ | <code php> | ||
+ | function doAThing(User $u) => $u | ||
+ | |> ' | ||
+ | |> ' | ||
+ | |> ' | ||
+ | |> ' | ||
+ | ; | ||
+ | </ | ||
+ | |||
+ | Which is a really nice way to build up a pipeline through composition. | ||
+ | |||
+ | <code php> | ||
+ | function | ||
+ | |> step1(?) | ||
+ | |> step2(?) | ||
+ | |> step3($val, ?) | ||
+ | |> step4(?, $var) | ||
+ | ; | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== clone-with ==== | ||
+ | |||
+ | Although no formal RFC has been proposed, Máté had discussed a '' | ||
+ | |||
+ | <code php> | ||
+ | class Point | ||
+ | { | ||
+ | public function __construct(private int $x, private int $y) {} | ||
+ | |||
+ | public function getX(): int => $this-> | ||
+ | public function getY(): int => $this-> | ||
+ | |||
+ | public function withX($x): static => clone($this) with {x: $x}; | ||
+ | public function withY($y): static => clone($this) with {y: $y}; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Thus making many cases of wither methods just as trivial to write as getter methods. | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
Line 390: | Line 478: | ||
PHP 8.1. | PHP 8.1. | ||
- | |||
===== Open Issues ===== | ===== Open Issues ===== | ||
Line 400: | Line 487: | ||
This is a simple up-or-down vote, requiring 2/3 approval to pass. | This is a simple up-or-down vote, requiring 2/3 approval to pass. | ||
- | ===== Patches | + | Voting started 2021-05-31 |
- | [[https:// | + | <doodle title=" |
+ | * Yes | ||
+ | * No | ||
+ | </doodle> | ||
- | [[https:// | + | ===== Patches and Tests ===== |
- | Pull request | + | [[https:// |
- | + | ||
- | ===== Implementation ===== | + | |
- | After the project is implemented, | + | |
- | - the version(s) it was merged into | + | |
- | - a link to the git commit(s) | + | |
- | - a link to the PHP manual entry for the feature | + | |
- | - a link to the language specification section (if any) | + | |
- | + | ||
- | ===== References ===== | + | |
- | Links to external references, discussions or RFCs | + | |
- | ===== Rejected Features ===== | ||
- | Keep this updated with features that were discussed on the mail lists. |
rfc/short-functions.1603489722.txt.gz · Last modified: 2020/10/23 21:48 by crell