Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:107586 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 96812 invoked from network); 20 Oct 2019 10:09:49 -0000 Received: from unknown (HELO php-smtp3.php.net) (208.43.231.12) by pb1.pair.com with SMTP; 20 Oct 2019 10:09:49 -0000 Received: from php-smtp3.php.net (localhost [127.0.0.1]) by php-smtp3.php.net (Postfix) with ESMTP id 3FC062C2B7E for ; Sun, 20 Oct 2019 00:55:10 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp3.php.net X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS3215 2.6.0.0/16 X-Spam-Virus: No Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp3.php.net (Postfix) with ESMTPS for ; Sun, 20 Oct 2019 00:55:09 -0700 (PDT) Received: by mail-oi1-x230.google.com with SMTP id o205so8576257oib.12 for ; Sun, 20 Oct 2019 00:55:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=fCuTzYzQIRPi07apMI6OaXjyliz/oGTwM8yM9lRZKbI=; b=fZhLCWy2lZZr0qrQdR4tNPwdca5CO5crXIEMPpneAGSkXR0zwVrrs/U0zbVmbmHf/h dFHFaey34MTZE5jjUhiJsXfichqgh68qoQkUPqPlduDP9jI2W22eiwgde162K36AzCwb HQC8eyT1dyGd0FQoVYIX+QjjbGd5/qc5rnnol6/8QCz6uGLfnj/zAWwqMpFh7Dx0wfI5 wmpVnGynXJX0nt5Ok5fVRgGfnZjCvmm6uBxDS1Zw8XA12620i3elr6jxpHMCioiU/WWz Z2eWHJtYvl295ayXaz5Ye6lrkmRrYtElqFJjO4G0zvblzfUwpglZcezLmbnB7Rzu0YG6 bYsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=fCuTzYzQIRPi07apMI6OaXjyliz/oGTwM8yM9lRZKbI=; b=DcgwggKLoy8VCzpnNri9h+xfpN5pYRC4zaUuhdCDlZFTGZTHwxt8LoeouWwMRBj8xP VgG+oJRv2hBUy74uu4wC6AIlEdKo23Q2cjAl3Lug2KxKQwlQeYSB5/Oezu92YI0jox4p bxa6+esmm/tLi8lZHwhEQTrawafKm9NSfWKbwCryK8Q1vcSS3Ke9j6G/uTAhPG3QTy4j UeUoUqZObVYnAixKp7R9de0mBZlHNr2z+36qKDFSeea2jQzdD7Nbz5cKso/eo2MgqXlC uEgFl1zQPsba1Bl/JXInoqpt7Azp2r5OXxaVXfgGwtHM7RdEuCaTHi3e3sBV7B2E43X3 RwEw== X-Gm-Message-State: APjAAAXtla2ykngJg2OYa39+RBLZPUce32o95wvMkfMGu7g9Fh5qD0Jh ekUBdvYNWltCij0ipr4weyIWLH6aYCS4uHAiIoi9pA== X-Google-Smtp-Source: APXvYqwkfMLPK4tt0eazE2aQP/c7kU2jVZyVFaDTBEZVuYeC/ZpoebFsCGhF/9Cfnc+vLG0bpFxLFnSkfNBT3KQwKmU= X-Received: by 2002:aca:ef85:: with SMTP id n127mr14726650oih.42.1571558108959; Sun, 20 Oct 2019 00:55:08 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Sun, 20 Oct 2019 14:54:58 +0700 Message-ID: To: Mike Schinkel Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000d418cc059552e236" X-Envelope-From: Subject: Re: [PHP-DEV] 'switch-expression' and the 'type guard' unary operator demo From: webdevxp.com@gmail.com (Kosit Supanyo) --000000000000d418cc059552e236 Content-Type: text/plain; charset="UTF-8" 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 wrote: > > On Oct 19, 2019, at 12:40 PM, Kosit Supanyo > 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 = $a; // TypeError: Value is expected to be int, string given > > Just like type hints, can accept nullable types. > > $v = switch ($x) { > case 'a' => $result1, > case 'b' => $result2, > }; > > > Nice! > > > -Mike > > --000000000000d418cc059552e236--