[RFC] Short-match

php.internals

Larry Garfield

5 years ago
I present to Internals this tiny RFC to follow up on the match() expression RFC from earlier in the year. There was solidly positive support for this shortcut previously but it was removed for simplicity at the time, with the intent to bring it back later. It's now later. https://wiki.php.net/rfc/short-match
-- Larry Garfield larry@garfieldtech.com

Marco Pivetta

5 years ago
Hey Larry, On Mon, Dec 14, 2020 at 6:34 PM Larry Garfield <larry@garfieldtech.com> wrote:
> I present to Internals this tiny RFC to follow up on the match() > expression RFC from earlier in the year. There was solidly positive > support for this shortcut previously but it was removed for simplicity at > the time, with the intent to bring it back later. It's now later. > > https://wiki.php.net/rfc/short-match >
Overall back to the `switch (true)` case, which IMO is not a good idea in first place :| Nothing wrong with using a set of conditional that are put in a sequence through `if ()`, for these rare cases. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/

Doug Nelson

5 years ago
Hi Marco, Is there any chance you can elaborate on why you feel it's a bad idea? Both you and Sara at different points have talked about thinking was bad practice, but I've not read anything compelling about why it should be considered as such. Kind regards, Doug Nelson On Mon, 14 Dec 2020 at 18:14, Marco Pivetta <ocramius@gmail.com> wrote:
> Hey Larry, > > On Mon, Dec 14, 2020 at 6:34 PM Larry Garfield <larry@garfieldtech.com> > wrote: > > > I present to Internals this tiny RFC to follow up on the match() > > expression RFC from earlier in the year. There was solidly positive > > support for this shortcut previously but it was removed for simplicity at > > the time, with the intent to bring it back later. It's now later. > > > > https://wiki.php.net/rfc/short-match > > > > Overall back to the `switch (true)` case, which IMO is not a good idea in > first place :| > > Nothing wrong with using a set of conditional that are put in a sequence > through `if ()`, for these rare cases. > > Marco Pivetta > > http://twitter.com/Ocramius > > http://ocramius.github.com/ >
-- Doug Nelson Senior Software Engineer

Marco Pivetta

5 years ago
Hey Doug, On Mon, Dec 14, 2020, 21:24 Doug Nelson <dougnelson@silktide.com> wrote:
> Hi Marco, > > Is there any chance you can elaborate on why you feel it's a bad idea? > > Both you and Sara at different points have talked about thinking was bad > practice, but I've not read anything compelling about why it should be > considered as such. > > Kind regards, > Doug Nelson > > On Mon, 14 Dec 2020 at 18:14, Marco Pivetta <ocramius@gmail.com> wrote: > >> Hey Larry, >> >> On Mon, Dec 14, 2020 at 6:34 PM Larry Garfield <larry@garfieldtech.com> >> wrote: >> >> > I present to Internals this tiny RFC to follow up on the match() >> > expression RFC from earlier in the year. There was solidly positive >> > support for this shortcut previously but it was removed for simplicity >> at >> > the time, with the intent to bring it back later. It's now later. >> > >> > https://wiki.php.net/rfc/short-match >> > >> >> Overall back to the `switch (true)` case, which IMO is not a good idea in >> first place :| >> >> Nothing wrong with using a set of conditional that are put in a sequence >> through `if ()`, for these rare cases. >> >> Marco Pivetta >> >> http://twitter.com/Ocramius >> >> http://ocramius.github.com/ >> > > > -- > Doug Nelson > Senior Software Engineer >
It's effectively yet another way to write something that already exists, which means more syntax to learn, more syntax to deal with (in downstream tooling), and that for an edge case being a fall-through list of boolean expressions, which is what already happens by using `if` with early return statements. Let me rephrase it then: * It brings little to no advantage to the table for something seen very rarely (`match` already being super-rare, since adoption didn't even start yet) * It increases language complexity Every time new AST is to be added, that complexity needs to be weighed against the benefits, and I don't see any compelling ones here.

Olle Härstedt

5 years ago
Another situation in which _ might be useful. match (_) { ... } On Mon, 14 Dec 2020, 21:43 Marco Pivetta, <ocramius@gmail.com> wrote:

Sara Golemon

5 years ago
On Mon, Dec 14, 2020 at 2:24 PM Doug Nelson <dougnelson@silktide.com> wrote:
> Both you and Sara at different points have talked about thinking was bad > practice, but I've not read anything compelling about why it should be > considered as such. > >
I'm not a full -1 on the concept (especially as match(true) has the convenience of returning a value), but it's very square peg in a round hole to me. At the end of the day though, that's a style choice and not one I have any business imposing on anyone, and certainly within the context of this diff, the actual change is trivial. It's sugar for match(true) that looks like match. /shrug I might suggest broadening the scope to include `switch` as well though. If we're going to codify match(true) as a pattern, we should at least be consistent about it. -Sara

Kamil Tekiela

5 years ago
I don't understand what's the advantage of the short match? Why would I ever want to use it? If I ever saw this kind of code in my codebase then I would immediately refactor it to use if statements. That is just abuse of match statement in my opinion. If someone wants to abuse match syntax like this then I think they should put (true) after it to make it clear what they are doing. Allowing match without the match subject will be lead to confusing problems for a lot of beginners who will forget the match subject or mis-copy it and then wonder why their application does not behave as it should. IMHO I see no benefit of adding this feature to PHP, and I actually see disadvantages. On Mon, 14 Dec 2020 at 21:23, Sara Golemon <pollita@php.net> wrote:

Björn Larsson

5 years ago
Den 2020-12-14 kl. 22:23, skrev Sara Golemon:
> On Mon, Dec 14, 2020 at 2:24 PM Doug Nelson <dougnelson@silktide.com> wrote: > >> Both you and Sara at different points have talked about thinking was bad >> practice, but I've not read anything compelling about why it should be >> considered as such. >> >> > I'm not a full -1 on the concept (especially as match(true) has the > convenience of returning a value), but it's very square peg in a round hole > to me. > > At the end of the day though, that's a style choice and not one I have any > business imposing on anyone, and certainly within the context of this diff, > the actual change is trivial. It's sugar for match(true) that looks like > match. /shrug > > I might suggest broadening the scope to include `switch` as well though. > If we're going to codify match(true) as a pattern, we should at least be > consistent about it. > > -Sara >
I think it's a good point to keep it consistent with switch, i.e. if moving forward make the same change in switch. Then when mixing and matching on at least don't need to remember where true is needed... r//Björn L

Paul

5 years ago
On Mon, Dec 14, 2020 at 1:23 PM Sara Golemon <pollita@php.net> wrote:
> > On Mon, Dec 14, 2020 at 2:24 PM Doug Nelson <dougnelson@silktide.com> wrote: > > > Both you and Sara at different points have talked about thinking was bad > > practice, but I've not read anything compelling about why it should be > > considered as such. > > > > > I'm not a full -1 on the concept (especially as match(true) has the > convenience of returning a value), but it's very square peg in a round hole > to me. > > At the end of the day though, that's a style choice and not one I have any > business imposing on anyone, and certainly within the context of this diff, > the actual change is trivial. It's sugar for match(true) that looks like > match. /shrug > > I might suggest broadening the scope to include `switch` as well though. > If we're going to codify match(true) as a pattern, we should at least be > consistent about it. > > -Sara
I lean more on the side of +1 but otherwise agree with Sara here. I'm apathetic on including switch but it's worth considering. If this (slightly) better aligns someone's code with how they're thinking about the problem then yay.

Илья Сомов

5 years ago
`match` is an expression, where as if-else construction is not. This allows for combining it with a potential future feature of single line functions and methods. For example (hypothetical syntax is used): ``` function getNumberKind(int $number) => match { $number > 0 => NumberKind::POSITIVE, $number == 0 => NumberKind::ZERO, $number < 0 => NumberKind::NEGATIVE, } ``` See how natural it looks and reads. Another improvement is that it reduces the amount of visual clutter (`if` and `return` keywords). Yet another distinction between “if” and “match” is their intent. `If` is more appropriate for the procedural flow. However, when we operate with pure functions, `match` is a good sign of such function. It shows that different input values turn into different output values, instead of different branches of procedural code being executed. Therefore, if code is intended to be more FP-ish, IMO, `match` is preferred. For the procedural code patterns, including early returns / throws, `if` is clearly a better choice. So, `match` is better suited for functional-ish parts of code, which do not pose behavior, but only convert one value to another ones. In the FP world, pattern matching is a widely used feature, allowing to split computations of output value for different kinds of input value. The closest thing available in PHP these days is `match (true)`. The `(true)` part looks ugly and artificial, and removing it is a matter of a cosmetic change. Of course, it is possible to use `match` instead of `switch` or `if`s for procedural code, and vice versa, which is still syntaxically correct, but bad from an intent expression perspective. This is a downside of `match` expression as a whole and, IMO, is irrelevant for this small improvement. So, - `match` allows writing clearer code when used with FP-ish intent; it is also an expression, therefore irreplaceable with if/switch in some cases. - pattern matching is a widely used feature in FP, and `match (true)` is the current way to achieve the most similar thing in PHP. - improving `match` will not hurt the language allowing to write the same thing two ways – because it is already done by accepting `match` RFC itself

Larry Garfield

5 years ago
On Wed, Dec 16, 2020, at 6:49 PM, someniatko wrote:
> `match` is an expression, where as if-else construction is not. This > allows for combining it with a potential future feature of single line > functions and methods. For example (hypothetical syntax is used): > > ``` > function getNumberKind(int $number) => match { > $number > 0 => NumberKind::POSITIVE, > $number == 0 => NumberKind::ZERO, > $number < 0 => NumberKind::NEGATIVE, > } > ``` > > See how natural it looks and reads.
Ah, someone gets what I'm driving toward overall. :-) --Larry Garfield

Sara Golemon

5 years ago
On Wed, Dec 16, 2020 at 6:50 PM someniatko <someniatko@gmail.com> wrote:
> > `match` is an expression, where as if-else construction is not. This > allows for combining it with a potential future feature of single line > functions and methods. For example (hypothetical syntax is used): > > ``` > $getNumber = fn(int $number) => match { > $number < 0 => NumberKind::NEGATIVE, > $number == 0 => NumberKind::ZERO, > $number > 0 => NumberKind::POSITIVE, > }; > ``` >
That does read attractively, yes. This is the example that should have been offered first as it shows the expression nature shining. To contrast that with what would be possible now in an expressive functional form: $getNumber = fn(int $number) => [ -1 => NumberKind::NEGATIVE, 0 => NumberKind::ZERO, 1 => NumberKind::POSITIVE, ][$number <=> 0]; The match form *certainly* reads more naturally than the spaceship indexing form even though both take up equal space. -Sara

Claude Pache

5 years ago
> Le 17 déc. 2020 à 17:23, Sara Golemon <pollita@php.net> a écrit : > > On Wed, Dec 16, 2020 at 6:50 PM someniatko <someniatko@gmail.com> wrote: >> >> `match` is an expression, where as if-else construction is not. This >> allows for combining it with a potential future feature of single line >> functions and methods. For example (hypothetical syntax is used): >> >> ``` >> $getNumber = fn(int $number) => match { >> $number < 0 => NumberKind::NEGATIVE, >> $number == 0 => NumberKind::ZERO, >> $number > 0 => NumberKind::POSITIVE, >> }; >> ``` >> > > That does read attractively, yes. This is the example that should have > been offered first as it shows the expression nature shining. > > To contrast that with what would be possible now in an expressive > functional form: > > $getNumber = fn(int $number) => [ > -1 => NumberKind::NEGATIVE, > 0 => NumberKind::ZERO, > 1 => NumberKind::POSITIVE, > ][$number <=> 0]; > > The match form *certainly* reads more naturally than the spaceship indexing > form even though both take up equal space. > > -Sara
If you mean a version of `if` that works in expressions, there already exists a standard operator for that. Once its historical associativity goof is definitely fixed, you will be able to write: ``` $getNumberKind = fn(int $number) => $number > 0 ? NumberKind::POSITIVE : $number == 0 ? NumberKind::ZERO : $number < 0 ? NumberKind::NEGATIVE : throw new \TypeError; ``` There is a semantic advantage of `match` over `? : `, though, namely its exhaustivity: You don’t need to add a “panic” default case in order to catch logic errors. —Claude

Larry Garfield

5 years ago
On Thu, Dec 17, 2020, at 10:23 AM, Sara Golemon wrote:
> On Wed, Dec 16, 2020 at 6:50 PM someniatko <someniatko@gmail.com> wrote: > > > > `match` is an expression, where as if-else construction is not. This > > allows for combining it with a potential future feature of single line > > functions and methods. For example (hypothetical syntax is used): > > > > ``` > > $getNumber = fn(int $number) => match { > > $number < 0 => NumberKind::NEGATIVE, > > $number == 0 => NumberKind::ZERO, > > $number > 0 => NumberKind::POSITIVE, > > }; > > ``` > > > > That does read attractively, yes. This is the example that should have > been offered first as it shows the expression nature shining. > > To contrast that with what would be possible now in an expressive > functional form: > > $getNumber = fn(int $number) => [ > -1 => NumberKind::NEGATIVE, > 0 => NumberKind::ZERO, > 1 => NumberKind::POSITIVE, > ][$number <=> 0]; > > The match form *certainly* reads more naturally than the spaceship indexing > form even though both take up equal space. > > -Sara
It looks like the quoted part from someniatko changed from a named function to an anon function? Not sure what happened there. I've included both a named and lambda version of his example in the RFC, however, and linked to the short-functions RFC as that would allow the form he originally listed. They complement each other nicely. --Larry Garfield

Olle Härstedt

5 years ago
What about matching on a variable's type? ``` match { $var: string => "is a string" $var: array => "something else" } ``` This could be used with flow-sensitive typing, e.g. assume the type of $var being string in the string block. Psalm works like this for if-statements. Also consider the case with generics. Compare with generalised algebraic data types in FP (GADT). Olle On Thu, 17 Dec 2020, 22:01 Larry Garfield, <larry@garfieldtech.com> wrote:

Larry Garfield

5 years ago
On Fri, Dec 18, 2020, at 1:40 PM, Olle Härstedt wrote:
> What about matching on a variable's type? > > ``` > match { > $var: string => "is a string" > $var: array => "something else" > } > ``` > > This could be used with flow-sensitive typing, e.g. assume the type of $var > being string in the string block. Psalm works like this for if-statements. > Also consider the case with generics. > > Compare with generalised algebraic data types in FP (GADT). > > Olle
That would be more along the lines of the pattern matching RFC that Ilija and I have been kicking around for post-enums: https://wiki.php.net/rfc/pattern-matching That's still in the "it would be cool if" stage only, and is IMO off topic from the abbreviation effort in this RFC. --Larry Garfield

Olle Härstedt

5 years ago
On Sat, 19 Dec 2020, 02:48 Larry Garfield, <larry@garfieldtech.com> wrote:
> On Fri, Dec 18, 2020, at 1:40 PM, Olle Härstedt wrote: > > What about matching on a variable's type? > > > > ``` > > match { > > $var: string => "is a string" > > $var: array => "something else" > > } > > ``` > > > > This could be used with flow-sensitive typing, e.g. assume the type of > $var > > being string in the string block. Psalm works like this for > if-statements. > > Also consider the case with generics. > > > > Compare with generalised algebraic data types in FP (GADT). > > > > Olle > > That would be more along the lines of the pattern matching RFC that Ilija > and I have been kicking around for post-enums: > https://wiki.php.net/rfc/pattern-matching > > That's still in the "it would be cool if" stage only, and is IMO off topic > from the abbreviation effort in this RFC. > > --Larry Garfield >
Very cool. Thanks for the link. Looking forward to further implementations! Olle
--

Andreas Leathley

5 years ago
On 14.12.20 18:33, Larry Garfield wrote:
> I present to Internals this tiny RFC to follow up on the match() expression RFC from earlier in the year. There was solidly positive support for this shortcut previously but it was removed for simplicity at the time, with the intent to bring it back later. It's now later. > > https://wiki.php.net/rfc/short-match
I think it is a good addition that will make code clearer. If the main counter-argument is that "if - elseif - else" does the same thing, comparing the syntax to that and showing some real-world examples might even convince some more people who think it is unnecessary, as the code mostly speaks for itself, but the example currently in the RFC might be a bit too simplistic to be convincing for the sceptics. It would also be interesting how much switch(true) is used in open source code currently, as it is the currently used "equivalent" to match(true) - I know it is in some parts of the Symfony code, probably because it is often easier to scan over when compared to huge if / elseif blocks. match(true) is clearly an improvement to switch(true), so while match has almost no use so far in PHP code, switch(true) definitely has.

Andreas Leathley

5 years ago
I checked in my vendor directory for currently used switch(true) usages, there were 96 matches. It is often used when handling an unknown value and needing to display or convert it, as there the structure of a switch is easier to scan compared to other comparisons like ifs (at least it is for me). Compared to match these switch statements are a lot uglier, which shows that there are use cases for it even when you are forced to use switch. This is a good example in my estimation, from the Symfony Console Dumper class (taken from Symfony 5.2), when a value is converted into a string representation: ```php $this->handler = function ($var): string {     switch (true) {         case null === $var:             return 'null';         case true === $var:             return 'true';         case false === $var:             return 'false';         case \is_string($var):             return '"'.$var.'"';         default:             return rtrim(print_r($var, true));     } }; ``` With match this becomes much more concise: ```php $this->handler = function ($var): string {     return match {         null === $var => 'null',         true === $var => 'true',         false === $var => 'false',         \is_string($var) => '"'.$var.'"',         default => rtrim(print_r($var, true)),     }; }; ``` The same with ifs: ```php $this->handler = function ($var): string {     if (null === $var) {         return 'null';     }     if (true === $var) {         return 'true';     }     if (false === $var) {         return 'false';     }     if (\is_string($var)) {         return '"'.$var.'"';     }     return rtrim(print_r($var, true)); }; ``` The implied return type for match and the reduced amount of code to scan makes match {} much better in my opinion, with ifs you always have to make sure there isn't additional logic somewhere, and it makes it easy to add more complex code "by accident" compared to match. match (true) would be possible now, but the true makes the code a bit confusing, while without the (true) it reads more like natural language ("match the first possible expression in this list and return a corresponding value").

Olle Härstedt

5 years ago
On Tue, 15 Dec 2020, 00:30 Andreas Leathley, <a.leathley@gmx.net> wrote:
> I checked in my vendor directory for currently used switch(true) usages, > there were 96 matches. It is often used when handling an unknown value > and needing to display or convert it, as there the structure of a switch > is easier to scan compared to other comparisons like ifs (at least it is > for me). Compared to match these switch statements are a lot uglier, > which shows that there are use cases for it even when you are forced to > use switch. > > This is a good example in my estimation, from the Symfony Console Dumper > class (taken from Symfony 5.2), when a value is converted into a string > representation: > > ```php > $this->handler = function ($var): string { > switch (true) { > case null === $var: > return 'null'; > case true === $var: > return 'true'; > case false === $var: > return 'false'; > case \is_string($var): > return '"'.$var.'"'; > default: > return rtrim(print_r($var, true)); > } > }; > ``` > > With match this becomes much more concise: > > ```php > $this->handler = function ($var): string { > return match { > null === $var => 'null', > true === $var => 'true', > false === $var => 'false', > \is_string($var) => '"'.$var.'"', > default => rtrim(print_r($var, true)), > }; > }; > ``` > > The same with ifs: > > ```php > $this->handler = function ($var): string { > if (null === $var) { > return 'null'; > } > if (true === $var) { > return 'true'; > } > if (false === $var) { > return 'false'; > } > if (\is_string($var)) { > return '"'.$var.'"'; > } > > return rtrim(print_r($var, true)); > }; > ``` > > The implied return type for match and the reduced amount of code to scan > makes match {} much better in my opinion, with ifs you always have to > make sure there isn't additional logic somewhere, and it makes it easy > to add more complex code "by accident" compared to match. match (true) > would be possible now, but the true makes the code a bit confusing, > while without the (true) it reads more like natural language ("match the > first possible expression in this list and return a corresponding value"). > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php
In OCaml they actually use `function` as a shorthand for lambda + match (on the implied first argument). `fun` is the lambda keyword (and also `let`).

Ilija Tovilo

5 years ago
Hi internals
> With match this becomes much more concise: > > ```php > $this->handler = function ($var): string { > return match { > null === $var => 'null', > true === $var => 'true', > false === $var => 'false', > \is_string($var) => '"'.$var.'"', > default => rtrim(print_r($var, true)), > }; > }; > ```
I suspect most use cases of `match (true)` are exactly for things like this where you're always comparing the same value but not against fixed values but "shapes". I think some simple and limited pattern matching would be useful here. ```php $this->handler = function ($var): string { return match ($var) { null => 'null', true => 'true', false => 'false', is string => '"'.$var.'"', default => rtrim(print_r($var, true)), }; }; ``` This would have some significant overlap with the short match proposed here. Combined with the unclear semantics (strict comparison? loose comparison? type error on non-bool values?) makes me unsure if we really need the short match. Ilija

Sara Golemon

5 years ago
On Mon, Dec 14, 2020 at 5:30 PM Andreas Leathley <a.leathley@gmx.net> wrote:
> With match this becomes much more concise: > > ```php > $this->handler = function ($var): string { > return match { > null === $var => 'null', > true === $var => 'true', > false === $var => 'false', > \is_string($var) => '"'.$var.'"', > default => rtrim(print_r($var, true)), > }; > }; > ``` >
Or even better with existing syntax: ```php $this->handler = match($var) { null, true, false => json_encode($var), default => \is_string($var) ? "\"$var\"" : \rtrim(\print_r($var, true)), }; I appreciate that this is a specific counter-example to your example, but you picked the bad example. :p -Sara

Andreas Leathley

5 years ago
On 15.12.20 20:08, Sara Golemon wrote:
> Or even better with existing syntax: > ```php > $this->handler = match($var) { > null, true, false => json_encode($var), > default => \is_string($var) ? "\"$var\"" : \rtrim(\print_r($var, true)), > }; > > I appreciate that this is a specific counter-example to your example, but > you picked the bad example. :p
Sure, for this specific example - there are of course longer real-life examples (sometimes even nested ones), often using instanceof, is_array, is_callable and similar constructs, but they seem a bit too much for a discussion. If you add slightly more logic then it might be better: ```php $this->handler = function ($var): string {      return match {          null === $var => 'null',          true === $var => 'true',          false === $var => 'false',          is_string($var) => '"'.$var.'"',          is_callable($var) => 'callable',          is_object($var) => get_class($var),          default => rtrim(print_r($var, true)),      }; }; ``` I guess that would be an advantage of these current switch(true) (and possibly future match {}) statements: it is easy to add additional matches that do not impact the others. I do like Nikitas idea to make it a TypeError for non-bool matches.

Sara Golemon

5 years ago
On Tue, Dec 15, 2020 at 1:37 PM Andreas Leathley <a.leathley@gmx.net> wrote:
> ```php >
$this->handler = match {
> null === $var => 'null', > true === $var => 'true', > false === $var => 'false', > is_string($var) => '"'.$var.'"', > is_callable($var) => 'callable', > is_object($var) => get_class($var), > default => rtrim(print_r($var, true)), > }; > ``` > >
I saw a proposal connected to match about a year ago that included type based matching, something like: match ($var) { true => 'true', false => 'false', instanceof int => "int($var)", instanceof string => "\"$var\"", instanceof object => get_class($var), instanceof DateTimeInterface => $var->getTimestamp(), default => rtrim(print_r($var, true)), }; That might satisfy at least one of the use cases in a general way.
> I do like Nikitas idea to make it a TypeError for non-bool matches. > >
Yeah. Within the context of this featurette, that's something we should include in the proposal. If you're doing a match(true/false/other-literal) (explicitly or implicitly) then your cases should be commensurately more well constrainted. -Sara

Nikita Popov

5 years ago
On Mon, Dec 14, 2020 at 6:34 PM Larry Garfield <larry@garfieldtech.com> wrote:
> I present to Internals this tiny RFC to follow up on the match() > expression RFC from earlier in the year. There was solidly positive > support for this shortcut previously but it was removed for simplicity at > the time, with the intent to bring it back later. It's now later. > > https://wiki.php.net/rfc/short-match > > -- > Larry Garfield > larry@garfieldtech.com >
Just like Sara, I'm not strongly opposed to this, but I'm also not sure this is worthwhile. Writing "match (true) {" instead of "match {" is not particularly tedious when compared to the size of the remaining structure. Writing "match (true) {" has the advantage of being more explicit about what this actually does, namely a "true ===" comparison. If it is omitted, a reasonable person might think that match { preg_match(...) => ... } is going to do something sensible, like it would if placed inside an "if()". But it does not, as preg_match() returns 1, not true, and as such the match arm will never be taken. This is more obvious when the value that is being compared against is explicitly given. Of course, with "match {" being a dedicated syntax, we could make it a TypeError to use a non-bool match arm... Regards, Nikita

Larry Garfield

5 years ago
On Tue, Dec 15, 2020, at 3:00 AM, Nikita Popov wrote:
> On Mon, Dec 14, 2020 at 6:34 PM Larry Garfield <larry@garfieldtech.com> > wrote: > > > I present to Internals this tiny RFC to follow up on the match() > > expression RFC from earlier in the year. There was solidly positive > > support for this shortcut previously but it was removed for simplicity at > > the time, with the intent to bring it back later. It's now later. > > > > https://wiki.php.net/rfc/short-match > > > > -- > > Larry Garfield > > larry@garfieldtech.com > > > > Just like Sara, I'm not strongly opposed to this, but I'm also not sure > this is worthwhile. Writing "match (true) {" instead of "match {" is not > particularly tedious when compared to the size of the remaining structure. > Writing "match (true) {" has the advantage of being more explicit about > what this actually does, namely a "true ===" comparison. If it is omitted, > a reasonable person might think that > > match { > preg_match(...) => ... > } > > is going to do something sensible, like it would if placed inside an > "if()". But it does not, as preg_match() returns 1, not true, and as such > the match arm will never be taken. This is more obvious when the value that > is being compared against is explicitly given. > > Of course, with "match {" being a dedicated syntax, we could make it a > TypeError to use a non-bool match arm... > > Regards, > Nikita
Hm. preg_match() is the first example I've seen that makes me think the weak comparison may have value in this case. I will have to consider that and discuss with Ilija a bit. (Since match was his addition and relates to the ongoing enum work.) I'd also have to figure out how best to handle that, too, since it's a deeper change. Whee! Several people have mentioned also short-circuiting switch the same way. I am not opposed, and honestly don't feel too strongly about it either way. On Twitter, someone suggested also short circuiting while (true) the same way; I don't know how useful that is, but I acknowledge the consistency argument. I'm happy with whatever the consensus is on both points. --Larry Garfield

Mike Schinkel

5 years ago
> On Dec 15, 2020, at 12:18 PM, Larry Garfield <larry@garfieldtech.com> wrote: > > On Tue, Dec 15, 2020, at 3:00 AM, Nikita Popov wrote: >> On Mon, Dec 14, 2020 at 6:34 PM Larry Garfield <larry@garfieldtech.com> >> wrote: >> >>> I present to Internals this tiny RFC to follow up on the match() >>> expression RFC from earlier in the year. There was solidly positive >>> support for this shortcut previously but it was removed for simplicity at >>> the time, with the intent to bring it back later. It's now later. >>> >>> https://wiki.php.net/rfc/short-match >>> >>> -- >>> Larry Garfield >>> larry@garfieldtech.com >>> >> >> Just like Sara, I'm not strongly opposed to this, but I'm also not sure >> this is worthwhile. Writing "match (true) {" instead of "match {" is not >> particularly tedious when compared to the size of the remaining structure. >> Writing "match (true) {" has the advantage of being more explicit about >> what this actually does, namely a "true ===" comparison. If it is omitted, >> a reasonable person might think that >> >> match { >> preg_match(...) => ... >> } >> >> is going to do something sensible, like it would if placed inside an >> "if()". But it does not, as preg_match() returns 1, not true, and as such >> the match arm will never be taken. This is more obvious when the value that >> is being compared against is explicitly given. >> >> Of course, with "match {" being a dedicated syntax, we could make it a >> TypeError to use a non-bool match arm... >> >> Regards, >> Nikita > > Hm. preg_match() is the first example I've seen that makes me think the weak comparison may have value in this case. I will have to consider that and discuss with Ilija a bit. (Since match was his addition and relates to the ongoing enum work.) I'd also have to figure out how best to handle that, too, since it's a deeper change. Whee! > > Several people have mentioned also short-circuiting switch the same way. I am not opposed, and honestly don't feel too strongly about it either way. On Twitter, someone suggested also short circuiting while (true) the same way; I don't know how useful that is, but I acknowledge the consistency argument. I'm happy with whatever the consensus is on both points.
Allowing "switch {...}" to represent "switch (true){...}" might not actually be consistent. Since switch/case does a loose equality check some people get confused when using it with booleans: https://stackoverflow.com/questions/8829229/why-switchtrue-in-php-with-a-strange-logic <https://stackoverflow.com/questions/8829229/why-switchtrue-in-php-with-a-strange-logic> If we allow "switch {...}" to represent "switch (true){...}" then the value switch compares will be hidden and less obvious to a developer if they are forgetting to consider switch's evaluation behavior. For some people this would increase the WTF factor. #fwiw -Mike P.S. OTOH allowing "while(true){...}" to be represented as "while{...}" would be great since AFAIK "while{...}" would not violate the principle of least surprise.

Ben Ramsey

5 years ago
> On Dec 16, 2020, at 10:54, Mike Schinkel <mike@newclarity.net> wrote: > > If we allow "switch {...}" to represent "switch (true){...}" then the value switch compares will be hidden and less obvious to a developer if they are forgetting to consider switch's evaluation behavior. For some people this would increase the WTF factor.
How does `"switch (true){...}"` cause less surprise than `"switch {...}”` for loose comparisons? IMO, seeing the boolean value `true` causes more confusion, since it matches any truthy value but the constant value in the expression is a bool. Cheers, Ben

Mike Schinkel

5 years ago
> On Dec 16, 2020, at 12:49 PM, Ben Ramsey <ben@benramsey.com> wrote: > >> On Dec 16, 2020, at 10:54, Mike Schinkel <mike@newclarity.net> wrote: >> >> If we allow "switch {...}" to represent "switch (true){...}" then the value switch compares will be hidden and less obvious to a developer if they are forgetting to consider switch's evaluation behavior. For some people this would increase the WTF factor. > > How does `"switch (true){...}"` cause less surprise than `"switch {...}”` for loose comparisons? IMO, seeing the boolean value `true` causes more confusion, since it matches any truthy value but the constant value in the expression is a bool.
I believe I must have worded it such that you misunderstood what I was writing. In fact, what you wrote is the point I was trying to get across. Sorry for my poor phrasing. -Mike