Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] Strict switch statements

Posted by Sara Golemon 
Sara Golemon
[PHP-DEV] Strict switch statements
June 14, 2018 07:00AM
Just for casual discussion at this point:
https://github.com/php/php-src/pull/3297

switch ($a) {
case FOO:
// Works exactly as current behavior.
break;
case == FOO:
// Nearly identical, though not using the ZEND_CASE optimization.
// Can probably make this equivalent to `case FOO`, but it felt
like an interesting direction.
break;
case === FOO:
// Only triggers if `$a === FOO`, no type juggling
break;
}

Love it? Hate it? See obvious flaws? The implementation is just a
rushed proof of concept, not something I've labored over, it may well
have bugs. Certainly wouldn't target anything earlier than 7.4, if at
all.

-Sara

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Andrey Andreev
Re: [PHP-DEV] Strict switch statements
June 14, 2018 07:30AM
Hi,

On Thu, Jun 14, 2018 at 7:53 AM, Sara Golemon <[email protected]> wrote:
> Just for casual discussion at this point:
> https://github.com/php/php-src/pull/3297
>
> switch ($a) {
> case FOO:
> // Works exactly as current behavior.
> break;
> case == FOO:
> // Nearly identical, though not using the ZEND_CASE optimization.
> // Can probably make this equivalent to `case FOO`, but it felt
> like an interesting direction.
> break;
> case === FOO:
> // Only triggers if `$a === FOO`, no type juggling
> break;
> }
>
> Love it? Hate it? See obvious flaws? The implementation is just a
> rushed proof of concept, not something I've labored over, it may well
> have bugs. Certainly wouldn't target anything earlier than 7.4, if at
> all.
>

I love it for the === part. Countless times I've had to avoid switch
statements because they can't do strict comparisons.

Cheers,
Andrey.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Nikita Popov
Re: [PHP-DEV] Strict switch statements
June 14, 2018 10:40AM
On Thu, Jun 14, 2018 at 6:53 AM, Sara Golemon <[email protected]> wrote:

> Just for casual discussion at this point:
> https://github.com/php/php-src/pull/3297
>
> switch ($a) {
> case FOO:
> // Works exactly as current behavior.
> break;
> case == FOO:
> // Nearly identical, though not using the ZEND_CASE optimization.
> // Can probably make this equivalent to `case FOO`, but it felt
> like an interesting direction.
> break;
> case === FOO:
> // Only triggers if `$a === FOO`, no type juggling
> break;
> }
>
> Love it? Hate it? See obvious flaws? The implementation is just a
> rushed proof of concept, not something I've labored over, it may well
> have bugs. Certainly wouldn't target anything earlier than 7.4, if at
> all.
>

I like the general idea here (switch with strict type comparison), but not
super fond of the particular syntax and implementation.

I think if people want to use strict matching, they'll quite likely want to
have it on all cases. Something like "strict switch ($expr) {}" or "switch
strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
{}" or "switch ($expr) { strict; }" or whatever would be preferable in that
case.

Additionally, switch has the issue of fall-through behavior, which is
somewhat unexpected and error prone to many people. It might make sense to
introduce an entirely new "match" statement that conforms a bit more with
how switch-like strictures are implemented nowadays. That is, something like

match ($expr) {
"foo" => {...},
"bar" | "baz" => {...},
}

or similar. This might need some more design work to ensure forward
compatibility with potential future algebraic datatypes etc.

Nikita
Rowan Collins
Re: [PHP-DEV] Strict switch statements
June 14, 2018 11:30AM
On 14 June 2018 at 09:35, Nikita Popov <[email protected]> wrote:

> On Thu, Jun 14, 2018 at 6:53 AM, Sara Golemon <[email protected]> wrote:
>
> > Just for casual discussion at this point:
> > https://github.com/php/php-src/pull/3297
> >
> > switch ($a) {
> > case FOO:
> > // Works exactly as current behavior.
> > break;
> > case == FOO:
> > // Nearly identical, though not using the ZEND_CASE optimization.
> > // Can probably make this equivalent to `case FOO`, but it felt
> > like an interesting direction.
> > break;
> > case === FOO:
> > // Only triggers if `$a === FOO`, no type juggling
> > break;
> > }
> >
> > Love it? Hate it? See obvious flaws? The implementation is just a
> > rushed proof of concept, not something I've labored over, it may well
> > have bugs. Certainly wouldn't target anything earlier than 7.4, if at
> > all.
> >
>
> I like the general idea here (switch with strict type comparison), but not
> super fond of the particular syntax and implementation.
>
> I think if people want to use strict matching, they'll quite likely want to
> have it on all cases. Something like "strict switch ($expr) {}" or "switch
> strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
> {}" or "switch ($expr) { strict; }" or whatever would be preferable in that
> case.
>


For ages, I've had an idea along these lines kicking around. Like Nikita,
I was assuming that all branches would want strict comparison or none, so
was thinking of putting the operator at the top, something like "switch
($expr) use (===)". I figured it could then be extended so the "===" could
be substituted for any binary operator; for instance, you could match
values into ranges with "switch ($score) use (>=)".

That said, I can see an attraction in a form with the operator on the
branch, if operators other than "==" and "===" are supported; for the range
example, it might be handy to have cases for ">= 50", "> 0", and "=== 0".

I prefer reusing "===" in some way over the word "strict", even if no other
operators are supported, because "strict" could mean a number of things -
"strictly no fall-throughs", for instance - and I think that could cause
confusion (people already expect "strict types" to mean more than it does).

Regards,
--
Rowan Collins
[IMSoP]
Stephen Reay
Re: [PHP-DEV] Strict switch statements
June 14, 2018 12:00PM
Apologies - sending again from on-list address.

I’m not overly fond of the `case ===`

Could it be simply `case` for current behaviour and `strict case` for the new behaviour?

I’d argue that while fall through can cause problems it also has legitimate uses.



Sent from my iPhone



Sent from my iPhone
>> On 14 Jun 2018, at 15:35, Nikita Popov <[email protected]> wrote:
>>
>> On Thu, Jun 14, 2018 at 6:53 AM, Sara Golemon <[email protected]> wrote:
>>
>> Just for casual discussion at this point:
>> https://github.com/php/php-src/pull/3297
>>
>> switch ($a) {
>> case FOO:
>> // Works exactly as current behavior.
>> break;
>> case == FOO:
>> // Nearly identical, though not using the ZEND_CASE optimization.
>> // Can probably make this equivalent to `case FOO`, but it felt
>> like an interesting direction.
>> break;
>> case === FOO:
>> // Only triggers if `$a === FOO`, no type juggling
>> break;
>> }
>>
>> Love it? Hate it? See obvious flaws? The implementation is just a
>> rushed proof of concept, not something I've labored over, it may well
>> have bugs. Certainly wouldn't target anything earlier than 7.4, if at
>> all.
>
> I like the general idea here (switch with strict type comparison), but not
> super fond of the particular syntax and implementation.
>
> I think if people want to use strict matching, they'll quite likely want to
> have it on all cases. Something like "strict switch ($expr) {}" or "switch
> strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
> {}" or "switch ($expr) { strict; }" or whatever would be preferable in that
> case.
>
> Additionally, switch has the issue of fall-through behavior, which is
> somewhat unexpected and error prone to many people. It might make sense to
> introduce an entirely new "match" statement that conforms a bit more with
> how switch-like strictures are implemented nowadays. That is, something like
>
> match ($expr) {
> "foo" => {...},
> "bar" | "baz" => {...},
> }
>
> or similar. This might need some more design work to ensure forward
> compatibility with potential future algebraic datatypes etc.
>
> Nikita


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Christoph M. Becker
Re: [PHP-DEV] Strict switch statements
June 14, 2018 01:40PM
On 14.06.2018 at 10:35, Nikita Popov wrote:

> On Thu, Jun 14, 2018 at 6:53 AM, Sara Golemon <[email protected]> wrote:
>
>> Just for casual discussion at this point:
>> https://github.com/php/php-src/pull/3297
>>
>> switch ($a) {
>> case FOO:
>> // Works exactly as current behavior.
>> break;
>> case == FOO:
>> // Nearly identical, though not using the ZEND_CASE optimization.
>> // Can probably make this equivalent to `case FOO`, but it felt
>> like an interesting direction.
>> break;
>> case === FOO:
>> // Only triggers if `$a === FOO`, no type juggling
>> break;
>> }
>
> I like the general idea here (switch with strict type comparison), but not
> super fond of the particular syntax and implementation.
>
> I think if people want to use strict matching, they'll quite likely want to
> have it on all cases. […]

ACK. Even the example shows the gotchas with this kind of mix: the
final case would never match, or would it (which I would find even more
confusing)?

Furthermore, I personally don't like switch statements in a higher level
programming language, since they feel so low level (optional fall
through, and whatever). And there is already the “switch (true)” hack,
to make the proposed behavior possible (without optimizations, though, I
presume), see https://3v4l.org/qPauK and https://3v4l.org/iSLkW.

> Additionally, switch has the issue of fall-through behavior, which is
> somewhat unexpected and error prone to many people. It might make sense to
> introduce an entirely new "match" statement that conforms a bit more with
> how switch-like strictures are implemented nowadays. That is, something like
>
> match ($expr) {
> "foo" => {...},
> "bar" | "baz" => {...},
> }

On a quick thought, I like this!

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Sara Golemon
Re: [PHP-DEV] Strict switch statements
June 14, 2018 05:00PM
On Thu, Jun 14, 2018 at 4:35 AM, Nikita Popov <[email protected]> wrote:
> I like the general idea here (switch with strict type comparison), but not
> super fond of the particular syntax and implementation.
>
No arguments there. What's presented is "best I could come up in the bath".. :)

> I think if people want to use strict matching, they'll quite likely want to
> have it on all cases. Something like "strict switch ($expr) {}" or "switch
> strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
> {}" or "switch ($expr) { strict; }" or whatever would be preferable in that
> case.
>
Agree that it's more likely to be all-or-not within a switch block.
If I could step through my thinking in putting it on the case
statement however, I applied two starting rules:
1. Avoid adding new reserved symbols/keywords.
2. Try to make it read naturally.

I actually did consider Rowan's suggestion `switch (expr) use (===)
{}`, but I didn't feel like it satisfied #2 well.
Instead, I chose to think of the T_CASE as a placeholder for the
switch expression. If you visually substitute the expression where
the 'case' is at, then this:

switch ($x) {
case === 1:
case === 2:
}

Could be read as:

switch (...) {
$x === 1:
$x === 2:
}

Not saying that's the only route, just walking through how I would
imaging it reading to new eyes.

> Additionally, switch has the issue of fall-through behavior, which is
> somewhat unexpected and error prone to many people. It might make sense to
> introduce an entirely new "match" statement that conforms a bit more with
> how switch-like strictures are implemented nowadays. That is, something like
>
> match ($expr) {
> "foo" => {...},
> "bar" | "baz" => {...},
> }
>
> or similar. This might need some more design work to ensure forward
> compatibility with potential future algebraic datatypes etc.
>
That's certainly more ambitious, but since we're just casually
talking, then let's explore it.

I like the idea of a richer syntax for matching that goes beyond
simple equality/identicality, but we'll need to think very carefully
about interactions (for example, in your example, is `"bar" | "baz"` a
bitwise binary OR?) What might default look like here? I guess we
still reuse the default keyword. My nit-pick about the "match" keyword
is that I (personally, and this is probably minority) think of this
like regex related.

I'll be honest, I didn't realize the fall-through behavior was a
learning curve issue. This block scoping would address that, but I
wonder if we could make use of break/continue. The former's meaning
being obvious enough, the latter allowing us to either fall through to
the next case or possibly continuing evaluating conditionals.

Rowan Collins
Re: [PHP-DEV] Strict switch statements
June 14, 2018 06:00PM
On 14 June 2018 at 15:48, Sara Golemon <[email protected]> wrote:

> Agree that it's more likely to be all-or-not within a switch block.
> If I could step through my thinking in putting it on the case
> statement however, I applied two starting rules:
> 1. Avoid adding new reserved symbols/keywords.
> 2. Try to make it read naturally.
>
> I actually did consider Rowan's suggestion `switch (expr) use (===)
> {}`, but I didn't feel like it satisfied #2 well.
>


I always read it in my head as "switch on expression using the ===
operator". There is a bit of a punctuation pileup, though.




> I'll be honest, I didn't realize the fall-through behavior was a
> learning curve issue. This block scoping would address that, but I
> wonder if we could make use of break/continue. The former's meaning
> being obvious enough, the latter allowing us to either fall through to
> the next case or possibly continuing evaluating conditionals.


Yeah, annoyingly "continue" is actually valid in switch statements, as a
confusing synonym of "break", because I always thought it would be nice if
you had to balance every non-empty case with either "break" or "continue".
It's not just the learning curve that's a problem, it's really easy to
write subtly broken code with an accidental fall-through.

I was just telling a colleague that I've made this mistake before:

//Before: no break needed because there's a return
switch ( $foo ) {
case 1:
return true;
default:
bar();
}

//After: should have added a break, but didn't notice until something went
wrong
switch ( $foo ) {
case 1:
if ( $something ) {
return true;
}
default:
bar();
}

I think a lot of people would find a syntax with { ... } blocks much more
familiar.

One thing to consider is what actually is the "mission statement" of the
switch/match/whatever - what makes it "better" than a chain of if-elseif
blocks?


Meanwhile, someone just posted this on Stack Overflow
https://stackoverflow.com/q/50860319/157957 where someone was trying to use
<= in a switch statement!


Regards,
--
Rowan Collins
[IMSoP]
Thomas Bley
Re: [PHP-DEV] Strict switch statements
June 14, 2018 06:00PM
Nikita Popov wrote on 14.06.2018 10:35:

> On Thu, Jun 14, 2018 at 6:53 AM, Sara Golemon <[email protected]> wrote:
>
>> Just for casual discussion at this point:
>> https://github.com/php/php-src/pull/3297
>>
>> switch ($a) {
>> case FOO:
>> // Works exactly as current behavior.
>> break;
>> case == FOO:
>> // Nearly identical, though not using the ZEND_CASE optimization.
>> // Can probably make this equivalent to `case FOO`, but it felt
>> like an interesting direction.
>> break;
>> case === FOO:
>> // Only triggers if `$a === FOO`, no type juggling
>> break;
>> }
>>
>> Love it? Hate it? See obvious flaws? The implementation is just a
>> rushed proof of concept, not something I've labored over, it may well
>> have bugs. Certainly wouldn't target anything earlier than 7.4, if at
>> all.
>>
>
> I like the general idea here (switch with strict type comparison), but not
> super fond of the particular syntax and implementation.
>
> I think if people want to use strict matching, they'll quite likely want to
> have it on all cases. Something like "strict switch ($expr) {}" or "switch
> strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
> {}" or "switch ($expr) { strict; }" or whatever would be preferable in that
> case.
>
> Additionally, switch has the issue of fall-through behavior, which is
> somewhat unexpected and error prone to many people. It might make sense to
> introduce an entirely new "match" statement that conforms a bit more with
> how switch-like strictures are implemented nowadays. That is, something like
>
> match ($expr) {
> "foo" => {...},
> "bar" | "baz" => {...},
> }
>
> or similar. This might need some more design work to ensure forward
> compatibility with potential future algebraic datatypes etc.
>
> Nikita
>

for simplicity I would use an extra parameter to have a strict comparison (similar to the extra parameter in in_array()):

switch ($a, true) { // strict comparison
switch ($a) { // loose comparison

Regards
Thomas

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Mathieu Rochette
Re: [PHP-DEV] Strict switch statements
June 14, 2018 06:10PM
Sara Golemon – Thu, 14. June 2018 16:50
> On Thu, Jun 14, 2018 at 4:35 AM, Nikita Popov <[email protected]> wrote:
> > I like the general idea here (switch with strict type comparison), but not
> > super fond of the particular syntax and implementation.
> >
> No arguments there. What's presented is "best I could come up in the bath". :)
>
> > I think if people want to use strict matching, they'll quite likely want to
> > have it on all cases. Something like "strict switch ($expr) {}" or "switch
> > strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
> > {}" or "switch ($expr) { strict; }" or whatever would be preferable in that
> > case.
> >
> Agree that it's more likely to be all-or-not within a switch block.
> If I could step through my thinking in putting it on the case
> statement however, I applied two starting rules:
> 1. Avoid adding new reserved symbols/keywords.
> 2. Try to make it read naturally.
>
> I actually did consider Rowan's suggestion `switch (expr) use (===)
> {}`, but I didn't feel like it satisfied #2 well.
> Instead, I chose to think of the T_CASE as a placeholder for the
> switch expression. If you visually substitute the expression where
> the 'case' is at, then this:
>
> switch ($x) {
> case === 1:
> case === 2:
> }
>
> Could be read as:
>
> switch (...) {
> $x === 1:
> $x === 2:
> }
>
> Not saying that's the only route, just walking through how I would
> imaging it reading to new eyes.
>
> > Additionally, switch has the issue of fall-through behavior, which is
> > somewhat unexpected and error prone to many people. It might make sense to
> > introduce an entirely new "match" statement that conforms a bit more with
> > how switch-like strictures are implemented nowadays. That is, something like
> >
> > match ($expr) {
> > "foo" => {...},
> > "bar" | "baz" => {...},
> > }
> >
> > or similar. This might need some more design work to ensure forward
> > compatibility with potential future algebraic datatypes etc.
> >
> That's certainly more ambitious, but since we're just casually
> talking, then let's explore it.
>
> I like the idea of a richer syntax for matching that goes beyond
> simple equality/identicality, but we'll need to think very carefully
> about interactions (for example, in your example, is `"bar" | "baz"` a
> bitwise binary OR?) What might default look like here? I guess we
> still reuse the default keyword. My nit-pick about the "match" keyword
> is that I (personally, and this is probably minority) think of this
> like regex related.

match is also used to destructure things in other language (at least in Rust). I d'like to to that:

$a = [1, 2];
match ($a) {
[2, $n] => { ... }
[$m, $n] => { ... }
[$m, $n, $o] => { ... }
[$m, $n, $o, ...$next] => { ... }
[] => {...}
[$m] => {...}
$l =>{...}
}

and I'm probably dreaming but if I could destructure objects it would be awesome:

class User {
public $id;
public $banned;
}

$user = $repository->getById($id);

// with https://github.com/hoaproject/Option
// eg: $user = Some(new User($id, $banned));
// or: $user = None()

match ($user) {
Some:$user=User:{banned => true} => { assert($user instanceof User); /* user is banned */ }
Some:User:{name=$name, banned => $banned, role='admin'} => { assert(!$banned) }
Some:$user => { assert($user instanceof User); assert(!$user->banned) }
None => { /* user not found */ }
}

It could also be used to match http Request, Json API input, etc.

>
> I'll be honest, I didn't realize the fall-through behavior was a
> learning curve issue. This block scoping would address that, but I
> wonder if we could make use of break/continue. The former's meaning
> being obvious enough, the latter allowing us to either fall through to
> the next case or possibly continuing evaluating conditionals.
>
>
Sara Golemon
Re: [PHP-DEV] Strict switch statements
June 14, 2018 06:20PM
On Thu, Jun 14, 2018 at 11:57 AM, Thomas Bley <[email protected]> wrote:
> for simplicity I would use an extra parameter to have a strict comparison (similar to the extra parameter in in_array()):
>
> switch ($a, true) { // strict comparison
> switch ($a) { // loose comparison
>
I instinctively recoil from boolean arguments as they tend to be
opaque at a glance, but perhaps:

switch ($a, ===) {...}

Would both be more apparent as to its meaning and leave the door open
for other uses. Though at that point, tbqh, I think `switch ($a) use
(===) {...}` gives better visual isolation.

-Sara

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Alice Wonder
Re: [PHP-DEV] Strict switch statements
June 14, 2018 06:20PM
On 06/14/2018 08:57 AM, Thomas Bley wrote:
> Nikita Popov wrote on 14.06.2018 10:35:
>
>> On Thu, Jun 14, 2018 at 6:53 AM, Sara Golemon <[email protected]> wrote:
>>
>>> Just for casual discussion at this point:
>>> https://github.com/php/php-src/pull/3297
>>>
>>> switch ($a) {
>>> case FOO:
>>> // Works exactly as current behavior.
>>> break;
>>> case == FOO:
>>> // Nearly identical, though not using the ZEND_CASE optimization.
>>> // Can probably make this equivalent to `case FOO`, but it felt
>>> like an interesting direction.
>>> break;
>>> case === FOO:
>>> // Only triggers if `$a === FOO`, no type juggling
>>> break;
>>> }
>>>
>>> Love it? Hate it? See obvious flaws? The implementation is just a
>>> rushed proof of concept, not something I've labored over, it may well
>>> have bugs. Certainly wouldn't target anything earlier than 7.4, if at
>>> all.
>>>
>>
>> I like the general idea here (switch with strict type comparison), but not
>> super fond of the particular syntax and implementation.
>>
>> I think if people want to use strict matching, they'll quite likely want to
>> have it on all cases. Something like "strict switch ($expr) {}" or "switch
>> strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
>> {}" or "switch ($expr) { strict; }" or whatever would be preferable in that
>> case.
>>
>> Additionally, switch has the issue of fall-through behavior, which is
>> somewhat unexpected and error prone to many people. It might make sense to
>> introduce an entirely new "match" statement that conforms a bit more with
>> how switch-like strictures are implemented nowadays. That is, something like
>>
>> match ($expr) {
>> "foo" => {...},
>> "bar" | "baz" => {...},
>> }
>>
>> or similar. This might need some more design work to ensure forward
>> compatibility with potential future algebraic datatypes etc.
>>
>> Nikita
>>
>
> for simplicity I would use an extra parameter to have a strict comparison (similar to the extra parameter in in_array()):
>
> switch ($a, true) { // strict comparison
> switch ($a) { // loose comparison
>
> Regards
> Thomas
>

Should declare(strict_types = 1) do that?

I haven't tried, but I would think it should.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Rowan Collins
Re: [PHP-DEV] Strict switch statements
June 14, 2018 06:50PM
On 14 June 2018 at 17:16, Alice Wonder <[email protected]> wrote:

>
> Should declare(strict_types = 1) do that?
>
> I haven't tried, but I would think it should.



No, it doesn't, and shouldn't. "strict_types" actually means
"non_coercive_scalar_type_hints"; it's a very specific feature, controlling
a specific set of situations, not a catch-all "strict mode" for anything
type-related.

I suppose we could have a new directive that magically changed the default
for the "strict" parameter of array_search, et al. But if that converted
switch, would it also convert == itself? And then would we need a new
syntax for "opting out" and using the loose comparison? Would the resulting
confusion of people not seeing which mode a file was in be worth it?

This is exactly why I think the word "strict" should be avoided at all
costs; it's just far too ambiguous.

Regards,
--
Rowan Collins
[IMSoP]
Chase Peeler
Re: [PHP-DEV] Strict switch statements
June 15, 2018 12:00AM
On Thu, Jun 14, 2018 at 12:45 PM Rowan Collins <[email protected]>
wrote:

> On 14 June 2018 at 17:16, Alice Wonder <[email protected]> wrote:
>
> >
> > Should declare(strict_types = 1) do that?
> >
> > I haven't tried, but I would think it should.
>
>
>
> No, it doesn't, and shouldn't. "strict_types" actually means
> "non_coercive_scalar_type_hints"; it's a very specific feature, controlling
> a specific set of situations, not a catch-all "strict mode" for anything
> type-related.
>
> I suppose we could have a new directive that magically changed the default
> for the "strict" parameter of array_search, et al. But if that converted
> switch, would it also convert == itself? And then would we need a new
> syntax for "opting out" and using the loose comparison? Would the resulting
> confusion of people not seeing which mode a file was in be worth it?
>
> This is exactly why I think the word "strict" should be avoided at all
> costs; it's just far too ambiguous.
>
> Regards,
> --
> Rowan Collins
> [IMSoP]
>

Here's an idea, that leaves the flexibility to use strict comparisons on a
per case basis, but doesn't use the === syntax, which I don't like either.

switch($a){
case true:
//will match true, 1, etc...
break;
strict case false:
//will not match anything except boolean FALSE
//other stuff
break;
case false:
//will match 0, null, etc....
break;
}

You could expand this further with a second parameter to the switch, as
someone proposed above, that would put it in "strict" mode, and, allow a
keyword to change things back to non-strict as needed:

switch($a,true){
loose case true:
//will match true, 1, etc...
break;
case false:
//will not match anything except boolean FALSE
//other stuff
break;
loose case false:
//will match 0, null, etc....
break;
}

And, if it's in strict mode, you can still specify the strict keyword, and
if it's in non-strict mode, you can still specify the loose keyword.

Shouldn't even have to make them reserved words either, since they only
have meaning inside a switch statement, when immediately before the word
"case"


--
-- Chase
chasepeeler@gmail.com
Stanislav Malyshev
Re: [PHP-DEV] Strict switch statements
June 15, 2018 12:20AM
Hi!

> switch ($a) {
> case FOO:
> // Works exactly as current behavior.
> break;
> case == FOO:
> // Nearly identical, though not using the ZEND_CASE optimization.
> // Can probably make this equivalent to `case FOO`, but it felt
> like an interesting direction.
> break;
> case === FOO:
> // Only triggers if `$a === FOO`, no type juggling
> break;
> }

With current tendency to move to more strict interpretation and a bit
away from type juggling, I think it has its place. But I am not a big
fan to putting === there, it looks weird. Maybe go a bit further and
make the whole switch strict?

strict switch ($a) {
case FOO:
case BAR:
// both are strict ===
}

I imagine people that like strict style would want to use strict
everywhere, so for them using === every time might be annoying. This way
it makes for easier read for both strict and weak typers.
--
Stas Malyshev
smalyshev@gmail.com

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Stanislav Malyshev
Re: [PHP-DEV] Strict switch statements
June 15, 2018 12:20AM
Hi!

> Would both be more apparent as to its meaning and leave the door open
> for other uses. Though at that point, tbqh, I think `switch ($a) use
> (===) {...}` gives better visual isolation.

I don't think we should reuse the use() thing for third purpose when
we're already using it for two. I imagine with new parser logic we
should not be as restricted in syntax choices as we've been before? So
being a bit more explicit than "use(===)", which would be a bit of a
head-scratcher for a casual PHP user. Something like "strict switch" at
least gives a person something to ask about - what is "strict switch"
exactly? But "use(===)" would be harder to read and harder to look up
online.

--
Stas Malyshev
smalyshev@gmail.com

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Pedro Magalhães
Re: [PHP-DEV] Strict switch statements
June 15, 2018 02:50AM
>
> switch($a){
> case true:
> //will match true, 1, etc...
> break;
> strict case false:
> //will not match anything except boolean FALSE
> //other stuff
> break;
> case false:
> //will match 0, null, etc....
> break;
> }
>

I like this syntax, but I think I'd prefer the other way around. `case
strict false:` describes better what the condition is.

Regards,
Pedro
Sebastian Bergmann
Re: [PHP-DEV] Strict switch statements
June 15, 2018 08:40AM
Am 14.06.2018 um 10:35 schrieb Nikita Popov:
> It might make sense to introduce an entirely new "match" statement
> that conforms a bit more with how switch-like strictures are
> implemented nowadays. That is, something like
>
> match ($expr) {
> "foo" => {...},
> "bar" | "baz" => {...},
> }
>
> or similar.

Interesting. Can you provide a pointer to a language that has a match
statement like that?

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Rowan Collins
Re: [PHP-DEV] Strict switch statements
June 15, 2018 10:50AM
On 14 June 2018 at 23:15, Stanislav Malyshev <[email protected]> wrote:

> Hi!
>
> > Would both be more apparent as to its meaning and leave the door open
> > for other uses. Though at that point, tbqh, I think `switch ($a) use
> > (===) {...}` gives better visual isolation.
>
> I don't think we should reuse the use() thing for third purpose when
> we're already using it for two. I imagine with new parser logic we
> should not be as restricted in syntax choices as we've been before? So
> being a bit more explicit than "use(===)", which would be a bit of a
> head-scratcher for a casual PHP user. Something like "strict switch" at
> least gives a person something to ask about - what is "strict switch"
> exactly? But "use(===)" would be harder to read and harder to look up
> online.
>


As I've said before, I think precisely the opposite: === immediately means
"strict comparison" to anyone who knows PHP, but "strict switch" could mean
any number of restrictions: strict comparisons, no implicit fall-through of
cases, no duplicate cases, etc, etc

If it's the keyword reuse and punctuation that are an issue, what about
just picking a different word, and leaving out the parens:

switch ($foo) with === {
case 42:
blah();
break;
case '42':
blerg();
break;
}


Regards,
--
Rowan Collins
[IMSoP]
Christoph M. Becker
Re: [PHP-DEV] Strict switch statements
June 15, 2018 11:50AM
On 15.06.2018 at 08:36, Sebastian Bergmann wrote:

> Am 14.06.2018 um 10:35 schrieb Nikita Popov:
>
>> It might make sense to introduce an entirely new "match" statement
>> that conforms a bit more with how switch-like strictures are
>> implemented nowadays. That is, something like
>>
>> match ($expr) {
>> "foo" => {...},
>> "bar" | "baz" => {...},
>> }
>>
>> or similar.
>
> Interesting. Can you provide a pointer to a language that has a match
> statement like that?

This match statement (or would it be an expression?) could be regarded
as an extremly simplified syntactic variant of the case-of expression of
Standard ML[1].

Instead of the pipe operator we could use a comma to separate multiple
“patterns”. Using “case” instead of “match” appears to be something to
consider as well.

[1]
https://www.cs.cornell.edu/courses/cs312/2004fa/lectures/lecture3.htm,
section “Pattern Matching”

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Michał Brzuchalski
Re: [PHP-DEV] Strict switch statements
June 15, 2018 02:30PM
2018-06-15 11:44 GMT+02:00 Christoph M. Becker <[email protected]>:

> On 15.06.2018 at 08:36, Sebastian Bergmann wrote:
>
> > Am 14.06.2018 um 10:35 schrieb Nikita Popov:
> >
> >> It might make sense to introduce an entirely new "match" statement
> >> that conforms a bit more with how switch-like strictures are
> >> implemented nowadays. That is, something like
> >>
> >> match ($expr) {
> >> "foo" => {...},
> >> "bar" | "baz" => {...},
> >> }
> >>
> >> or similar.
> >
> > Interesting. Can you provide a pointer to a language that has a match
> > statement like that?
>
> This match statement (or would it be an expression?) could be regarded
> as an extremly simplified syntactic variant of the case-of expression of
> Standard ML[1].
>
> Instead of the pipe operator we could use a comma to separate multiple
> “patterns”. Using “case” instead of “match” appears to be something to
> consider as well.
>
> [1]
> https://www.cs.cornell.edu/courses/cs312/2004fa/lectures/lecture3.htm,
> section “Pattern Matching”
>
> --
> Christoph M. Becker
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
It's just a thought but maybe providing a new declare directive
like `declare(strict_comparison=1);` be easier for those who prefer strict
everywhere?
We have `declare(strict_types=1);` so we may have stricter declares also.
Maybe someday it turns into a standard way of working with PHP and can get
rid of declares without any code changes.
This may result in all comparisons strict without type juggling and won't
need any syntax changes at all.
And it'll apply for switch,if,else,ifselse,for,while etc. in all
comparisons.

Or maybe `declare(no_type_juggling=1)` or smth like that.

--
regards / pozdrawiam,
--
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com
Jordi Boggiano
Re: [PHP-DEV] Strict switch statements
June 15, 2018 03:50PM
On 15/06/2018 00:10, Stanislav Malyshev wrote:
> With current tendency to move to more strict interpretation and a bit
> away from type juggling, I think it has its place. But I am not a big
> fan to putting === there, it looks weird. Maybe go a bit further and
> make the whole switch strict?
>
> strict switch ($a) {
> case FOO:
> case BAR:
> // both are strict ===
> }

Might I suggest a new strictwich ($a) { ... } keyword? It's much more
appetizing.

Apologies,
Jordi

--
Jordi Boggiano
@seldaek - https://seld.be


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Rowan Collins
Re: [PHP-DEV] Strict switch statements
June 15, 2018 04:10PM
On 15 June 2018 at 14:48, Jordi Boggiano <[email protected]> wrote:

> Might I suggest a new strictwich ($a) { ... } keyword? It's much more
> appetizing.
>


Or maybe we should follow the pattern of == vs === and double up the "s":
"sswitch ($a) { ... }"

;)

--
Rowan Collins
[IMSoP]
Theodore Brown
Re: [PHP-DEV] Strict switch statements
June 15, 2018 05:00PM
On Thu, Jun 14, 2018 at 4:35 AM, Nikita Popov <[email protected]> wrote:

> I think if people want to use strict matching, they'll quite likely want to
> have it on all cases. Something like "strict switch ($expr) {}" or "switch
> strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
> {}" or "switch ($expr) { strict; }" or whatever would be preferable in that
> case.
>
> Additionally, switch has the issue of fall-through behavior, which is
> somewhat unexpected and error prone to many people. It might make sense to
> introduce an entirely new "match" statement that conforms a bit more with
> how switch-like strictures are implemented nowadays. That is, something like
>
> match ($expr) {
>     "foo" => {...},
>     "bar" | "baz" => {...},
> }
>
> or similar. This might need some more design work to ensure forward
> compatibility with potential future algebraic datatypes etc.

I really like this idea. It's similar to the `match` control flow operator
in Rust: https://doc.rust-lang.org/book/second-edition/ch06-02-match.html.

One reason I almost never use the `switch` statement in PHP (besides the
lack of strict matching) is that it's so verbose. Having to put a `break`
keyword after every case to avoid fallthrough means that it almost always
requires less code to use `if` statements instead.

To avoid confusion with union types, I think I would prefer commas between
or conditions instead of a pipe character. Example:

```
match ($expr) {
"foo", "bar" => {echo 'expr is "foo" or "bar"';},
true => {echo 'expr is true';},
1 => {echo 'expr is 1';},
null => {echo 'expr is null';},
false => {echo 'expr is false';},
default => {echo 'expr is something else';},
}
```
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Larry Garfield
Re: [PHP-DEV] Strict switch statements
June 15, 2018 05:40PM
On Friday, June 15, 2018 9:54:48 AM CDT Theodore Brown wrote:
> On Thu, Jun 14, 2018 at 4:35 AM, Nikita Popov <[email protected]> wrote:
> > I think if people want to use strict matching, they'll quite likely want
> > to
> > have it on all cases. Something like "strict switch ($expr) {}" or "switch
> > strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
> > {}" or "switch ($expr) { strict; }" or whatever would be preferable in
> > that
> > case.
> >
> > Additionally, switch has the issue of fall-through behavior, which is
> > somewhat unexpected and error prone to many people. It might make sense to
> > introduce an entirely new "match" statement that conforms a bit more with
> > how switch-like strictures are implemented nowadays. That is, something
> > like
> >
> > match ($expr) {
> >
> > "foo" => {...},
> > "bar" | "baz" => {...},
> >
> > }
> >
> > or similar. This might need some more design work to ensure forward
> > compatibility with potential future algebraic datatypes etc.
>
> I really like this idea. It's similar to the `match` control flow operator
> in Rust: https://doc.rust-lang.org/book/second-edition/ch06-02-match.html.
>
> One reason I almost never use the `switch` statement in PHP (besides the
> lack of strict matching) is that it's so verbose. Having to put a `break`
> keyword after every case to avoid fallthrough means that it almost always
> requires less code to use `if` statements instead.
>
> To avoid confusion with union types, I think I would prefer commas between
> or conditions instead of a pipe character. Example:
>
> ```
> match ($expr) {
> "foo", "bar" => {echo 'expr is "foo" or "bar"';},
> true => {echo 'expr is true';},
> 1 => {echo 'expr is 1';},
> null => {echo 'expr is null';},
> false => {echo 'expr is false';},
> default => {echo 'expr is something else';},
> }
> ```

I'm not fully sold that anything is needed here, but if something is I would
also very much favor a substantially more robust match statement a la Rust,
Go, et al over some form of "pickiness flag" on the existing switch. Syntax
details TBD, but the benefit of a flag on switch seems minimal while the
benefit of more robust type/pattern matching is potentially large.

That said, however, also bear in mind that "PHP is not $language": One of the
big uses of match in Rust, as I understand it, is to force fully exploring the
keyspace of an enum. We of course don't have enums so that use case goes
away. Given the emphasis on polymorphism in OOP PHP over RTTI, are there
enough non-enum, non-RTTI use cases for a robust match statement to justify
its inclusion?

If so, then I'm down. :-)

--Larry Garfield
Björn Larsson
Re: [PHP-DEV] Strict switch statements
June 16, 2018 04:50PM
Den 2018-06-14 kl. 11:21, skrev Rowan Collins:

> On 14 June 2018 at 09:35, Nikita Popov <[email protected]> wrote:
>
>> On Thu, Jun 14, 2018 at 6:53 AM, Sara Golemon <[email protected]> wrote:
>>
>>> Just for casual discussion at this point:
>>> https://github.com/php/php-src/pull/3297
>>>
>>> switch ($a) {
>>> case FOO:
>>> // Works exactly as current behavior.
>>> break;
>>> case == FOO:
>>> // Nearly identical, though not using the ZEND_CASE optimization.
>>> // Can probably make this equivalent to `case FOO`, but it felt
>>> like an interesting direction.
>>> break;
>>> case === FOO:
>>> // Only triggers if `$a === FOO`, no type juggling
>>> break;
>>> }
>>>
>>> Love it? Hate it? See obvious flaws? The implementation is just a
>>> rushed proof of concept, not something I've labored over, it may well
>>> have bugs. Certainly wouldn't target anything earlier than 7.4, if at
>>> all.
>>>
>> I like the general idea here (switch with strict type comparison), but not
>> super fond of the particular syntax and implementation.
>>
>> I think if people want to use strict matching, they'll quite likely want to
>> have it on all cases. Something like "strict switch ($expr) {}" or "switch
>> strict ($expr) {}" or "switch (strict $expr) {}" or "switch ($expr) strict
>> {}" or "switch ($expr) { strict; }" or whatever would be preferable in that
>> case.
>>
>
> For ages, I've had an idea along these lines kicking around. Like Nikita,
> I was assuming that all branches would want strict comparison or none, so
> was thinking of putting the operator at the top, something like "switch
> ($expr) use (===)". I figured it could then be extended so the "===" could
> be substituted for any binary operator; for instance, you could match
> values into ranges with "switch ($score) use (>=)".
>
> That said, I can see an attraction in a form with the operator on the
> branch, if operators other than "==" and "===" are supported; for the range
> example, it might be handy to have cases for ">= 50", "> 0", and "=== 0".
>
> I prefer reusing "===" in some way over the word "strict", even if no other
> operators are supported, because "strict" could mean a number of things -
> "strictly no fall-throughs", for instance - and I think that could cause
> confusion (people already expect "strict types" to mean more than it does).
>
> Regards,

Yup, I also like this idea very much. Using the === syntax is a clear
message on what's it all about. Having the ability to extend it to
other operators is also interesting, e.g. !== & !=.

Another point is that by keeping switch keyword it would be relatively
easy to upgrade legacy code, making it more robust.

Of course there is a use for a new keyword like match extending the
functionality even more. Maybe we can have both?

I'm thinking if one should be able to have like:
switch ($a)  {
    case === FOO:
        break;
    case !== BAR:
        break;
}
or:
switch ($a) with !== {
    case FOO:
        break;
    case BAR:
        break;
    default:
        break;
}
or:
switch ($a, ===)  {
    case FOO:
        break;
    case BAR:
        break;
}

r//Björn Larsson

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Sorry, only registered users may post in this forum.

Click here to login