Hi Mike

Is there a strong reason to change to using fat arrows and colons?


The reason is statement/expression semantic.

The reason for choosing comma over semicolon is because in PHP semicolons
are used only as statement separator while commas are used as expression
separator within brackets and item separator of some statements that can
take numbers of item such as `echo` or variable/property declarations.
Since switch-expression is a list of expression pairs, commas should be
used to separate its items.

And the reason for choosing fat arrow over colon is still the same as
above, expression semantic. In PHP fat arrows (double arrows) were used
only to separate key and value until 7.4 where their role has extended
(arrow functions), while colons are used in three places labels, ternary
operator and return types. Since cases in switch statements are labels,
colons are approprate. But as I stated above, switch-expression is a list
of expression pairs so it should use syntax like array rather than its
statement counterpart. If PHP was using colon as key/value separator then
colons should be used here.

And here are examples of languages that use arrow-like syntax:

[C#]

var result = bank.Status switch
{
    BankBranchStatus.Open => true,
    BankBranchStatus.Closed => false,
    BankBranchStatus.VIPCustomersOnly => isVip
};

[Rust]

let message = match x {
    0 | 1  => "not many",
    2 ..= 9 => "a few",
    _ => "lots"
};

[Kotlin]

var result = when (number) {
    0 -> "Invalid number"
    1, 2 -> "Number too low"
    3 -> "Number correct"
    4 -> "Number too high, but acceptable"
    else -> "Number too high"
}

What about break?
>

Let's see this example.

for ($i = 0; $i < 100; $i++) {
    $x = getX($i);
    doSomething(
        $i,
        $x,
        switch ($x) {
            case 0  => 'ZERO',
            case 1  => 'ONE',
            case 2  => 'TWO',
            case 3  => 'THREE',
            default => break,
        },
    );
}

This shoud break `switch` or `for`? And if it breaks `switch` NULL should
be returned but this will be the same as omitting `default`. And if it
breaks `for`, call to `doSomething()` will be incomplete because a call
frame was already pushed to VM stack. As I know ongoing function calls can
only be aborted by exceptions (and `return` should not be allowed either, I
need to fix that) so expressions must give something or throw.

Cheers

On Sun, Oct 20, 2019 at 6:52 AM Mike Schinkel <m...@newclarity.net> wrote:

>
> On Oct 19, 2019, at 12:40 PM, Kosit Supanyo <webdevxp....@gmail.com>
> wrote:
>
> Hi Internals
>
> I've just finished an implementation of 'switch-expression' that have been
> discussed recently. So I would like to present my ideas here.
>
>
> This is great to see that you proactively implemented this.
>
>
> The basic syntax of switch-expression in this implementation is:
>
> $result = switch ($expr) {
>    case $cond1 => $result1,
>    case $cond2 => $result2,
>    case $cond3 => $result3,
>    default => $default_result,
> };
>
>
> However, why the need to deviate with the existing syntax, making
> refactoring between switch statements and switch expressions more work that
> it needs to be.  Is there some reason why keeping colons and semlicolons
> would not work?
>
> Given your syntax manually refactoring existing switches to use
> expressions, or refactoring back from expressions to statements will
> require more and tedious keystrokes than if you just kept colons and
> semicolons.  Is there a strong reason to change to using fat arrows and
> colons?
>
>
>
> You can omit parenthesized expression which is shortcut to `switch (true)`.
> This change applies to switch statement as well.
>
> $v = switch {
>    case $x >= 0 && $x <= 100 => 1,
>    case $x >= 100 && $x <= 200 => 2,
>    default => 3,
> };
>
> switch {
>    case $x >= 0 && $x <= 100:
>        doSomething1();
>        break;
>    case $x >= 100 && $x <= 200:
>        doSomething2();
>        break;
>    default:
>        doNothing();
>        break;
> }
>
>
> I do very much like this innovation.
>
> Would love to see this work for switch statements too.
>
>
> You can also use `return` and `throw` in result expression. I recalled some
> languages have this feature (but I've forgotten what language). This
> feature can be very handy and useful in many use cases.
>
> $x = 'd';
> $v = switch ($x) {
>    case 'a' => 1,
>    case 'b' => 2,
>    case 'c' => return true,
>    default => throw new Exception("'$x' is not supported"),
> };
>
>
> What about break?
>
>
> Additional feature in the demo patch is the 'type guard' unary operator
> which is an operator that will perform type check on given value and throw
> `TypeError` when type mismatch occurred, otherwise return the value as is.
> It has the same precedence  as `new`.
>
> $a = 'This is a string';
> $v = <int>$a; // TypeError: Value is expected to be int, string given
>
> Just like type hints, can accept nullable types.
>
> $v = <?int>switch ($x) {
>    case 'a' => $result1,
>    case 'b' => $result2,
> };
>
>
> Nice!
>
>
> -Mike
>
>

Reply via email to