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
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.
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
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
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.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
throughif ()
, for these rare cases.Marco Pivetta
--
Doug Nelson
Senior Software Engineer
Hey Doug,
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 NelsonHey 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.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
throughif ()
, for these rare cases.Marco Pivetta
--
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.
Another situation in which _ might be useful. match (_) { ... }
Hey Doug,
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 NelsonHey 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.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
throughif ()
, for these rare cases.Marco Pivetta
--
Doug Nelson
Senior Software EngineerIt'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 usingif
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.
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 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.
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. /shrugI 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
Den 2020-12-14 kl. 22:23, skrev Sara Golemon:
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. /shrugI 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
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. /shrugI 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.
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 acceptingmatch
RFC itself
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
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
Le 17 déc. 2020 à 17:23, Sara Golemon pollita@php.net a écrit :
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
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
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
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
--
To unsubscribe, visit: https://www.php.net/unsub.php
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
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-matchingThat'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
--
To unsubscribe, visit: https://www.php.net/unsub.php
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.
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.
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:
$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:
$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:
$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").
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:$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:
$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:
$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").--
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
).
Hi internals
With match this becomes much more concise:
$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.
$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
With match this becomes much more concise:
$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:
$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
Or even better with existing syntax:
$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:
$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.
$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
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
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.comJust 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 thatmatch { preg_match(...) => ... }
is going to do something sensible, like it would if placed inside an
"if()". But it does not, aspreg_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
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.comJust 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 thatmatch {
preg_match(...) => ...
}is going to do something sensible, like it would if placed inside an
"if()". But it does not, aspreg_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,
NikitaHm.
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.
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
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 valuetrue
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