[PHP-BUG] Req #79079 [NEW]: Opt-in strict [and/or custom] comparison for switch/case

[email protected] ("phpuser at yopmail dot com") Wed, 08 Jan 2020 11:09:20 +0000
Newsgroups php.standards
Message-ID <[email protected]>
From:             phpuser at yopmail dot com
Operating system: 
PHP version:      Next Minor Version
Package:          PHP Language Specification
Bug Type:         Feature/Change Request
Bug description:Opt-in strict [and/or custom] comparison for switch/case

Description:
------------
First, switch/case compares values using *loose* equality (==) which
causes issues with null, 0, "" etc. and requires ugly hacks, for
instance:
https://github.com/doctrine/orm/commit/a9bca86d4d06557b8159b82b2de0b6f678c9dffd

I almost always want *strict* equality (===).

Idea of syntax (related to the second idea below):

    switch ( EXPR ) using strict_equality { CASES }

(note: that syntax is open to debate, but in any case I would *not* want
a declare()).


Second (but far less important), sometimes I would like to use a
switch/case with a custom comparison (instead of equality).

Idea of syntax (related to the first idea above):

    switch ( EXPR ) using ( BINARY_PREDICATE ) { CASES }

Examples:

    switch (getSomeString()) using ('str_starts_with') {
        case 'foo_':
        case 'bar_':
            /* starts with "foo_" or "bar_" */
            break;
        case 'qux_2_':
            /* starts with "qux_2_" */
            // no break
        case 'qux_':
            /* starts with "qux_" */
            break;
        default:
            /* doesn't start with any of the above */
    }

    switch (getSomeString()) using (fn($value, $case) => (bool)
preg_match($case, $value)) {
        case '/^(0|-?[1-9]\d*)$/D':
            /* ... */
            break;
        case '/^[[:xdigit:]]{2}$/D':
            /* ... */
            break;
        // ...
    }

    switch (getSomeInt()) using (fn($value, $case) => $value >= $case)
{
        case 50:
            /* >= 50 (i.e. in range(50, \PHP_INT_MAX)) */
            break;
        case 10:
            /* in range(10, 49) */
            break;
        case 0:
            /* in range(0, 9) */
            break;
        default:
            /* < 0 (i.e. in range(\PHP_INT_MIN, -1)) */
    }

And as a bonus, it would be even nicer if it could handle specifying
built-in comparison operators directly like e.g. "using (>=)" (or maybe
"using >="), in which case maybe "using strict_equality" wouldn't be
needed.

But again, let's not let extra wishes hinder the most wanted: strict
switch.


Thoughts?


-- 
Edit bug report at https://bugs.php.net/bug.php?id=79079&edit=1
-- 
Fix committed:                    https://bugs.php.net/fix.php?id=79079&r=fixed
Fixed in release:                 https://bugs.php.net/fix.php?id=79079&r=alreadyfixed
Need backtrace:                   https://bugs.php.net/fix.php?id=79079&r=needtrace
Need Reproduce Script:            https://bugs.php.net/fix.php?id=79079&r=needscript
Try newer version:                https://bugs.php.net/fix.php?id=79079&r=oldversion
Not developer issue:              https://bugs.php.net/fix.php?id=79079&r=support
Expected behavior:                https://bugs.php.net/fix.php?id=79079&r=notwrong
Not enough info:                  https://bugs.php.net/fix.php?id=79079&r=notenoughinfo
Submitted twice:                  https://bugs.php.net/fix.php?id=79079&r=submittedtwice
register_globals:                 https://bugs.php.net/fix.php?id=79079&r=globals
PHP version support discontinued: https://bugs.php.net/fix.php?id=79079&r=phptooold
Daylight Savings:                 https://bugs.php.net/fix.php?id=79079&r=dst
IIS Stability:                    https://bugs.php.net/fix.php?id=79079&r=isapi
Install GNU Sed:                  https://bugs.php.net/fix.php?id=79079&r=gnused
Floating point limitations:       https://bugs.php.net/fix.php?id=79079&r=float
No Zend Extensions:               https://bugs.php.net/fix.php?id=79079&r=nozend
MySQL Configuration Error:        https://bugs.php.net/fix.php?id=79079&r=mysqlcfg