Hi everybody!
Has this idea been discussed before?
I find myself writing switch statements in PHP quite rarely. This has a few reasons:
- It doesn’t have a "strict_types” version
- It is quite verbose (lots of breaks)
- It is a statement rather than an expression
Often, if / elseif statements turn out to be shorter, safer and easier to read than the switch statement.
What I’d really love is something like a match expression:
$r = match ($x) {
1: ‘Tiny’;
<= 10: ‘Small’;
<= 20: ‘Medium’;
<= 30: ‘Large’;
range(31, 100): ‘Enormous’; // Equivalent to `in_array($x, range(31, 100), true)`
instanceof Foo, instanceof Bar: ‘What?’;
default: ‘Unknown’;
};
These are the main differences compared to a traditional switch
statement:
- The whole
match
is an expression, the result of the executedcase
is implicitly returned - It allows pattern matching, not just
==
comparison,===
is the default - It does no implicit type conversion, thus no unexpected results when mixing strings and numbers
- Each case has an implicit
break
- Where you’d previously use twocase
s without a break, you now combine conditions using a comma
One downside, since PHP doesn’t implicitly return the last statement as some languages do there’s no obvious way to do multi-statement cases.
I assume that some people will not be so happy about having to switch-like constructs. IMO the implicit type conversion is the biggest issue here. Maybe we could offer a solution for this one at least.
Just some random thoughts.
Regards
Hi,
Something like:
function match($x) {
switch(true) {
case $x === 1:
return 'Tiny';
case is_numeric($x) && $x <= 10:
return 'Small';
case is_numeric($x) && $x <= 20:
return 'Medium';
case is_numeric($x) && $x <= 30:
return 'Large';
case is_numeric($x) && ($x >= 31 || $x <= 100):
return 'Enormous';
case $x instanceof Foo:
case $x instanceof Bar:
return 'What?';
default:
return 'Unknown';
}
}
the problem is you need is_numeric because no type safe version of <=
and >= exists.
Hi everybody!
Has this idea been discussed before?
..
Each case has an implicitbreak
This part has come up before, as the default behaviour of fall through
is a nasty gotcha for when you forget to put break. I can't find the
conversation right now, but the discussion was around a 'select'
keyword. I think the conversation didn't proceed as it seemed like
adding a new keyword just to fix the fall-through behaviour was a bad
tradeoff.
This RFC idea adds more capabilities, so is a better trade-off, and
more likely to be worth doing in my opinion.
One downside, since PHP doesn’t implicitly return the last statement
as some languages do there’s no obvious way to do multi-statement cases.
People are still working on and hoping for short-closures. That RFC
and any potential one for this, should attempt to use the same syntax.
Something like:
wall_of_hard_to_read_code
Yeah, that's a pretty good example of why I'd be in favour of this RFC.
cheers
Dan
Ack
for when you forget to put break.
Applying break statements is the first thing you should do if you intend
to break. That way it can't be forgotten.
--
Thomas Hruska
CubicleSoft President
I've got great, time saving software that you will find useful.
And once you find my software useful:
Applying break statements is the first thing you should do if you intend
to break. That way it can't be forgotten.
You should also immediately free the memory you’ve allocated but memory leaks still happen all the time.
Human error is inevitable.
The more the compiler can do for you automatically (especially if it’s without performance penalties) the better.
for when you forget to put break.
Applying break statements is the first thing you should do if you intend
to break. That way it can't be forgotten.--
Thomas Hruska
CubicleSoft PresidentI've got great, time saving software that you will find useful.
And once you find my software useful:
wrote in message news:eb28362c-4f8f-45df-bbf0-582e8ad2b8af@Spark...
Hi everybody!
Has this idea been discussed before?
I find myself writing switch statements in PHP quite rarely. This has a few
reasons:
- It doesn’t have a "strict_types” version
- It is quite verbose (lots of breaks)
- It is a statement rather than an expression
Often, if / elseif statements turn out to be shorter, safer and easier to
read than the switch statement.
What I’d really love is something like a match expression:
If there are circumstances where a series of if / elseif statements turn out
to be shorter, safer and easier to read than a switch statement, then the
intelligent thing to do would be to use if / elseif statements instead of
trying to make the switch statement more complicated. If your problem with
the switch statement is that you sometimes forget to insert a break
statement then that is your fault. Try to use the language features as they
were intended to be used and not how you would personally like to use them.
Millions of other programmers have no problem with the switch statement, and
they would not be pleased to have it changed just to deal with your
perceived problem with it.
--
Tony Marston
Hi Tony
… you sometimes forget to insert a break statement then that is your fault.
Any bug in your source code is ultimately your fault. But as mentioned before human error is inevitable. You can make it easier for your users to make less mistakes though. Other languages (e.g. Rust or Swift) have implicit breaks in their switch statements. This has been done for a reason, I wouldn’t call this a non-issue.
Millions of other programmers have no problem with the switch statement
It’s all they know. They don’t complain about null pointers even though it’s inventor calls it his billion-dollar mistake. The customer rarely knows what he truly needs.
they would not be pleased to have it changed just to deal with your perceived problem with it
I don’t suggest altering the behaviour of the switch statement but rather to introduce a new match statement.
Ilija
wrote in message news:eb28362c-4f8f-45df-bbf0-582e8ad2b8af@Spark...
Hi everybody!
Has this idea been discussed before?
I find myself writing switch statements in PHP quite rarely. This has a few
reasons:
- It doesn’t have a "strict_types” version
- It is quite verbose (lots of breaks)
- It is a statement rather than an expression
Often, if / elseif statements turn out to be shorter, safer and easier to
read than the switch statement.
What I’d really love is something like a match expression:If there are circumstances where a series of if / elseif statements turn out
to be shorter, safer and easier to read than a switch statement, then the
intelligent thing to do would be to use if / elseif statements instead of
trying to make the switch statement more complicated. If your problem with
the switch statement is that you sometimes forget to insert a break
statement then that is your fault. Try to use the language features as they
were intended to be used and not how you would personally like to use them.
Millions of other programmers have no problem with the switch statement, and
they would not be pleased to have it changed just to deal with your
perceived problem with it.--
Tony Marston
wrote in message news:7cd2884a-6606-4c3f-8f95-776fd277878b@Spark...
Hi Tony
… you sometimes forget to insert a break statement then that is your
fault.Any bug in your source code is ultimately your fault. But as mentioned
before human error is inevitable. You can make it easier for your users to
make less mistakes though. Other languages (e.g. Rust or Swift) have
implicit breaks in their switch statements. This has been done for a
reason, I wouldn’t call this a non-issue.
The problem with implicit breaks is that it makes it impossible to group
several conditions with a single break. My previous language use implicit
breaks, and this problem really annoyed me. With PHP I have more control,
and the fact that I have to insert explicit breaks I do not see as an
inconvenience.
Millions of other programmers have no problem with the switch statement
It’s all they know. They don’t complain about null pointers even though it’s
inventor calls it his billion-dollar mistake. The customer rarely knows
what he truly needs.
They know what they want to achieve, and they have to know which language
features are available to help them meet their objectives. The fact that
some language features have turned out to be a big mistake is purely the
fault of the people who introduced those features. Some programmers complain
about some languages features even though they are useful features which
work as advertised as are not deemed to be a mistake - take yourself for
example who is now complaining about issues with the switch statement.
If what you want to achieve can be done better with a series of if/elseif
statements than the switch statement, then why can't you use if/elseif
instead of making the language more complicated?
--
Tony Marston
it makes it impossible to group several conditions with a single break
In Swift you can group multiple conditions with a comma ,
and in Rust with a pipe |
. Here’s how that could look in PHP:
match ($x) {
1, 2: ‘One or two’;
}
The only thing you cannot do is this:
switch ($x) {
case 1:
echo “One\n”;
case 2:
echo “Two\n”;
break;
}
Meaning you cannot “bleed through” the first case into the second, executing both in case of $x
being 1
. This is acceptable IMO because this looks like a bug even if it’s intended.
then why can't you use if/elseif instead of making the language more complicated?
Because that’s usually the perfect use case for a switch statement.
wrote in message news:7cd2884a-6606-4c3f-8f95-776fd277878b@Spark...
Hi Tony
… you sometimes forget to insert a break statement then that is your
fault.Any bug in your source code is ultimately your fault. But as mentioned
before human error is inevitable. You can make it easier for your users to
make less mistakes though. Other languages (e.g. Rust or Swift) have
implicit breaks in their switch statements. This has been done for a
reason, I wouldn’t call this a non-issue.The problem with implicit breaks is that it makes it impossible to group
several conditions with a single break. My previous language use implicit
breaks, and this problem really annoyed me. With PHP I have more control,
and the fact that I have to insert explicit breaks I do not see as an
inconvenience.Millions of other programmers have no problem with the switch statement
It’s all they know. They don’t complain about null pointers even though it’s
inventor calls it his billion-dollar mistake. The customer rarely knows
what he truly needs.They know what they want to achieve, and they have to know which language
features are available to help them meet their objectives. The fact that
some language features have turned out to be a big mistake is purely the
fault of the people who introduced those features. Some programmers complain
about some languages features even though they are useful features which
work as advertised as are not deemed to be a mistake - take yourself for
example who is now complaining about issues with the switch statement.If what you want to achieve can be done better with a series of if/elseif
statements than the switch statement, then why can't you use if/elseif
instead of making the language more complicated?--
Tony Marston
wrote in message news:3b05768a-95b7-42de-8bb8-3d9ce0cce3a5@Spark...
it makes it impossible to group several conditions with a single break
In Swift you can group multiple conditions with a comma
,
and in Rust
with a pipe|
. Here’s how that could look in PHP:match ($x) { 1, 2: ‘One or two’; }
Just because other languages have different ways of implementing certain
features is no reason why PHP should include the same implementations. That
ius why there are so many different languages - because they do things
differently. If they were all the same there would be no need for different
languages.
The only thing you cannot do is this:
switch ($x) { case 1: echo “One\n”; case 2: echo “Two\n”; break; }
Meaning you cannot “bleed through” the first case into the second,
executing both in case of$x
being1
. This is acceptable IMO because
this looks like a bug even if it’s intended.
For people who RTFM and know how PHP works that code is perfectly acceptable
and not buggy in the least.
then why can't you use if/elseif instead of making the language more
complicated?Because that’s usually the perfect use case for a switch statement.
So why are you proposing a third alternative to the switch of if/elseif
statements?
--
Tony Marston
So why are you proposing a third alternative to the switch of if/elseif
statements?
Because they think it's a good idea.
Not everyone is going to agree, which is why we have voting for RFCs.
cheers
Dan
Ack
Hi everybody!
Has this idea been discussed before?
I find myself writing switch statements in PHP quite rarely. This has a few reasons:
- It doesn’t have a "strict_types” version
- It is quite verbose (lots of breaks)
- It is a statement rather than an expression
Often, if / elseif statements turn out to be shorter, safer and easier to read than the switch statement.
I've had the idea kicking around my head for some time of a "switch-use"
statement. I keep hoping to find the time to play around with the PHP
parser and see if I can write a proof of concept implementation, just as
an excuse to get deeper into the source, but since this has come up,
I'll outline the idea.
The general form would be "switch ( expression ) use ( op ) { ... }",
where "op" is any binary operator which gives a boolean result, and the
rest looks the same as a normal PHP switch statement.
The simplest example would be to do a strict comparison by using "===":
switch ( someFunction() ) use ( === ) {
case 42:
// ...
break;
case '42':
// ...
break;
}
Which would approximately de-sugar to:
$temp = someFunction();
switch ( true ) {
case $temp === 42:
// ...
break;
case $temp === '42':
// ...
break;
}
As you can see, the switch(true) version has to use an explicit variable
to avoid re-computing the expression, which switch does for you, and you
then have to repeat the "$temp ===", obscuring the fact that all cases
are checking the same thing. A normal switch, however, can't distinguish
42 from '42', because it uses the == comparison rules.
If this were the only useful operator, we might just call it "switch
strict" or something, but here are a couple of examples with other
operators:
// Generic exception handling function
// Also useful when accepting various incompatible implementations of
something and wrapping or converting them
switch ( $e ) use ( instanceof ) {
case FooException:
case BarException:
// ...
break;
case SomeOtherException:
// ...
break;
}
// Dividing a circle into arbitrary sectors, based on this Stack
Overflow question: https://stackoverflow.com/q/44183771/157957
// Note the ability to place "default" at the top, rather than
duplicating code in an else clause
switch ( $angle ) use ( <= ) {
case 30:
default:
return Direction::Right;
break;
case 60:
return Direction::UP_RIGHT;
break;
case 120:
return Direction::UP;
break;
case 150:
return Direction::UP_LEFT;
break;
case 210:
return Direction::LEFT;
break;
case 240:
return Direction::DOWN_LEFT;
break;
case 300:
return Direction::DOWN;
break;
case 330:
return Direction::DOWN_RIGHT;
break;
}
There are a couple of ways to expand this further, if we wanted:
- Allow operators whose result isn't strictly a boolean, such as bitwise &
- Allow any 2-parameter callable in place of an operator, to have more
complex comparisons. With Andrea's "operator functions" suggestion,
operators would technically just be a subset of this anyway.
The below would be quite useful, but unfortunately preg_match takes
($pattern, $subject) and this would need ($subject, $pattern), so you'd
need some extra transform:
switch ( $message ) use ( 'preg_match' ) {
case '/^Missing parameter:/':
case '/^Unexpected parameter:/':
return self::MALFORMED_REQUEST;
break;
case '/.*try again later.$/':
return self::TEMPORARY_ERROR;
break;
}
Any thoughts?
Regards,
--
Rowan Collins
[IMSoP]
I find myself writing switch statements in PHP quite rarely. This has a few reasons:
- It doesn’t have a "strict_types” version
...
I assume that some people will not be so happy about having to switch-like constructs. IMO the implicit type conversion is the biggest issue here. Maybe we could offer a solution for this one at least.
I also rarely use switch, primarily because of the lack of strict comparison.
Personally I would prefer having an option for strict comparison when using switch, similar to how in_array
has an optional $strict
parameter.
Would it be possible to add an optional $strict
parameter to switch? E.g.
switch ($i, true) {
case 1:
echo 'i is 1';
break;
case: 1.0:
echo 'i is 1.0';
break;
case '1':
echo 'i is "1"';
break;
case true:
echo 'i is true';
break;
}
-Theodore Brown
2017-09-10 18:05 GMT+02:00 Theodore Brown theodorejb@outlook.com:
I find myself writing switch statements in PHP quite rarely. This has a
few reasons:
- It doesn’t have a "strict_types” version
...
I assume that some people will not be so happy about having to
switch-like constructs. IMO the implicit type conversion is the biggest
issue here. Maybe we could offer a solution for this one at least.I also rarely use switch, primarily because of the lack of strict
comparison.
Personally I would prefer having an option for strict comparison when
using switch, similar to howin_array
has an optional$strict
parameter.Would it be possible to add an optional
$strict
parameter to switch? E.g.switch ($i, true) { case 1: echo 'i is 1'; break; case: 1.0: echo 'i is 1.0'; break; case '1': echo 'i is "1"'; break; case true: echo 'i is true'; break; }
I'd very much prefer a "strict switch ($i) { ... }" over a second parameter.
Regards, Niklas
2017-09-10 18:05 GMT+02:00 Theodore Brown theodorejb@outlook.com:
Would it be possible to add an optional
$strict
parameter to
switch? E.g.switch ($i, true) {
I'd very much prefer a "strict switch ($i) { ... }" over a second parameter.
What do either of you think of my "switch-use" proposal, which would
spell this as "switch ($i) use (===)"?
Regards,
--
Rowan Collins
[IMSoP]