Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:107588 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 55026 invoked from network); 20 Oct 2019 14:15:13 -0000 Received: from unknown (HELO php-smtp3.php.net) (208.43.231.12) by 76.75.200.58 with SMTP; 20 Oct 2019 14:15:13 -0000 Received: from php-smtp3.php.net (localhost [127.0.0.1]) by php-smtp3.php.net (Postfix) with ESMTP id BDC1C2C0526 for ; Sun, 20 Oct 2019 04:59:37 -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,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: X-Spam-Virus: No Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) (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 04:59:37 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id c2so5507022wrr.10 for ; Sun, 20 Oct 2019 04:59:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding:content-language; bh=8p29uvH0bPWkdcbvNoGEmnTT+MvjqaXtnKrMASDLx48=; b=VvfbRFMZF+vfiCOXcf+edYepO1pSX67tIfikfn7ZtKdszRMfmxUJk53IQ+i5C8v6wj VR9NWvcnmdIEMOO0eJVrdcDzBq3eNlsT5mNWlHUOy0C/rAXjM1o/VRa221gxuUmla/0+ Po6DuM9xIPdx0P4hT/XVULQ1jN9if8czdruMVrJdKwTPCAk9ybvG7bBHQKSLnvedcyKH qIaWQebhWumRYDeCkq4J+7RTIxo5/9zVi0Yim3QaHpyibwmMwnRiRT7cZrcPDpnFPwGl KRAQda5yu7AxGTEjeJ/GVKbCvPgmMlQuRxX8iRFu/KfIw+9eFxBSmtwNo1nlcxmBqumg Dypg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=8p29uvH0bPWkdcbvNoGEmnTT+MvjqaXtnKrMASDLx48=; b=Ad+DgP7xY5Cf1mzl4p5uHcf7sYpTS3RY2EqdD7mDAlPRDNr2NUOZWpndQW/lmke6yd igsK5GKAqsINooMkWE36tdBB/HKC6rm7i+fWffx3oUeEckcyJgYPYs4SA25tjorpMaQt AYOdCiQpvNUjoM1NxHGwnnEox7c8D2v7W38hODQrihzZ6VsAKTuwbeQ7qWwkbGZ2aSHY bdiNX1ChtyCRZVvwk79Vc8I5vDnYpyCgriwGkk9ahBFIQW2E3EkscPY3yKbgs8gHCQsz QGqtYQxSeD7SGrkgBN0pFjOjDeUuj8/pUfzcc+rrdxDoH+JsqMq0Br4IUCrPrY/lsEn9 wRSQ== X-Gm-Message-State: APjAAAU4858V/DMC1srtET0aCOUrNN3MuED4H8TezG02E+r6pSwJXry0 4aSh4sFBHXNVGIRLyaTejVLWJKB4w8g= X-Google-Smtp-Source: APXvYqyVEZdmbuTODwnaUfU1rqlqRM4h2DDpiM2lMnWKw5tuf2n8ieDvmGQQnNV91rG75zJB8jY8WQ== X-Received: by 2002:adf:8465:: with SMTP id 92mr14798569wrf.376.1571572775783; Sun, 20 Oct 2019 04:59:35 -0700 (PDT) Received: from [192.168.0.16] (cpc84253-brig22-2-0-cust114.3-3.cable.virginm.net. [81.108.141.115]) by smtp.googlemail.com with ESMTPSA id c6sm10547358wrm.71.2019.10.20.04.59.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Oct 2019 04:59:35 -0700 (PDT) To: internals@lists.php.net References: Message-ID: Date: Sun, 20 Oct 2019 12:59:32 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-GB X-Envelope-From: Subject: Re: [PHP-DEV] 'switch-expression' and the 'type guard' unary operator demo From: rowan.collins@gmail.com (Rowan Tommins) Hi Kosit, There's some really interesting ideas in here, thanks for sharing them. On 19/10/2019 17:40, Kosit Supanyo wrote: > Like function declaration and function expression in JavaScript, if > `switch` appears as first token at statement level it will be recognized as > statement but if `switch` is in expression context it will be > switch-expression. > > switch ($expr) { > case $cond1 => $result1, > case $cond2 => $result2, > case $cond3 => $result3, > default => $default_result, > }; > // Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW) > > But this is OK. > > !switch ($expr) { > case $cond1 => $result1, > case $cond2 => $result2, > case $cond3 => $result3, > default => $default_result, > }; // semicolon is still required because it is an expression This feels like an odd restriction to me, and one that as far as I'm aware PHP doesn't have anywhere else. For instance, it might be considered bad style, but it's possible to use a ternary operator as an abbreviated if statement: isset($_GET['logout']) ? $session->logout() : $session->extend(); Was this restriction added to make the implementation easier, or because you thought it was a useful feature? > 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; > } This is an interesting idea, given that switch(true) is the documented way to do this right now. However, I've always felt switch(true) was rather limited in its advantage over if-elseif. I would prefer a syntax that reduced the boilerplate for: * Different comparisons applied to the same variable/expression, e.g. match($user->getScore()) { case <0 => foo(), case >100 => bar(), default => baz() } * Different values compared against the same expression using the same operator, e.g. match( $exception instanceOf ) { case FooException => handleFoo(), case BarException => handleBar() } > 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"), > }; This seems confusing to me, because it mixes statements and expressions in a rather unusual way. The "return" case in particular seems ambiguous - if $v is visible outside the function, will it have a value assigned to it by the "return" branch, and if so what would that value be? I can imagine more use cases for the "throw" version, and it's reasonably obvious how it would behave, so it might be reasonable to have that one special case. > 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 This is a very interesting feature, although I think what would be even more useful would be syntax to check if something _can_ be cast, i.e. the same check you have here, but as an operator evaluating to boolean. That way, you could write code like this: if ( $_GET['id'] ) {    $user = getUser($_GET['id']): } else {    echo "Invalid ID provided"; } Which would be equivalent (given a type hint on getUser() and no strict_types declaration) to this, but without needing to use exceptions as flow control: try {    getUser($_GET['id']); } catch ( TypeError $e ) {    echo "Invalid ID provided"; } Regards, -- Rowan Tommins (né Collins) [IMSoP]