Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:107590 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 10293 invoked from network); 20 Oct 2019 23:29:08 -0000 Received: from unknown (HELO php-smtp3.php.net) (208.43.231.12) by 76.75.200.58 with SMTP; 20 Oct 2019 23:29:08 -0000 Received: from php-smtp3.php.net (localhost [127.0.0.1]) by php-smtp3.php.net (Postfix) with ESMTP id E80B32C84C2 for ; Sun, 20 Oct 2019 14:12:38 -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=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,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-yb1-xb41.google.com (mail-yb1-xb41.google.com [IPv6:2607:f8b0:4864:20::b41]) (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 14:12:38 -0700 (PDT) Received: by mail-yb1-xb41.google.com with SMTP id q143so3435948ybg.12 for ; Sun, 20 Oct 2019 14:12:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20150623.gappssmtp.com; s=20150623; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=8l1nPc18vK4sdkNtX1CAnm6DCrqNlGjOFHBqPcRwSRA=; b=1a4rFadcSQPsDSaNuY4t34XVrSEpwpM14P7KnKudhfwdNzdxRuz6nCv3B0KcpzTpVi Eg76FCjvlfFfeDhTvqdcmpUMt3Uru0gWDpyClNM1bruEGntgQQLX5PmHVx8tjEeEJhB1 ccF+i56wDzXdd5UKbdq76hujz92jxBFhNKYje1wE5/jjGVxMw2jASMduQTf1Dp3zBR3A yX1dZ5NYUJUf0QNnM7jwPiy/9EAkydIMEIOnVQqO37SPZOdbUN9UpgIefgh/Cqcjv91F KiXlojKj7htawpFp6OlrKnN/wAlTPKOMgs6qscD6Q8QOaGmuck2n9KaTsGgtHE6pLmqX BjNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=8l1nPc18vK4sdkNtX1CAnm6DCrqNlGjOFHBqPcRwSRA=; b=d4rmAWYJfZjtHlOzAPkWA+tbvIWNTGN+t8iL0H9iKH6g5ve0SPUfKBfwVSwfg4W/nB rUKSVslDwZJZ5/evjWz6Bva1XzBaDDWgCCuEBDC6Dn/VHOL2NTHrIXJZnTiUcl+4z6qM +MuRdVgfVtQwS1Vtalvf3h5908QkfI/8OhtYiWlm2zih7n6n2IyR3Z40rNA7VKTPrmVd sIJqTpZzMDNGbBKY4b/erbIwAlux7oYM5ijvi/5RDonf9FxNfzhThl+yCo5a20S/85r9 qBPJ8/rr4Aeok4Nsi24d1W3eQekt5+fIfR7AhHmadEbUhSYoqJ78hJAyb8HvYNPr6Qji 9LNQ== X-Gm-Message-State: APjAAAWQHxxWlFkJLzZpolzJoIGCg0eXj9EAwUgZCrlcnqZZqhc0NYKL UV/5uC7hrR7G4Vmu3JPBs33IqQ== X-Google-Smtp-Source: APXvYqwI5TQTB6oufnadpL0wrLD2KWKa/5qjXX5pRfdeFVkK2mpQucsChvt6zZH9kZE2UQxS8l727w== X-Received: by 2002:a25:afd1:: with SMTP id d17mr13392671ybj.470.1571605957328; Sun, 20 Oct 2019 14:12:37 -0700 (PDT) Received: from ?IPv6:2601:c0:c67f:e34e:dc33:30b5:913d:fcb2? ([2601:c0:c67f:e34e:dc33:30b5:913d:fcb2]) by smtp.gmail.com with ESMTPSA id d123sm3166788ywb.11.2019.10.20.14.12.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 20 Oct 2019 14:12:36 -0700 (PDT) Message-ID: <3D85D31D-5DDD-42AA-B465-6ADBE72D952A@newclarity.net> Content-Type: multipart/alternative; boundary="Apple-Mail=_1AB13499-2939-4E5E-B9F7-30FE3671E77D" Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Date: Sun, 20 Oct 2019 17:12:35 -0400 In-Reply-To: Cc: PHP internals To: Kosit Supanyo References: X-Mailer: Apple Mail (2.3445.104.11) X-Envelope-From: Subject: Re: [PHP-DEV] 'switch-expression' and the 'type guard' unary operator demo From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_1AB13499-2939-4E5E-B9F7-30FE3671E77D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hi Kosit, Thank you for your reply. > On Oct 20, 2019, at 3:54 AM, Kosit Supanyo = wrote: >=20 > Hi Mike >=20 > Is there a strong reason to change to using fat arrows and colons? >=20 > The reason is statement/expression semantic. Okay, so you chose commas and fat arrows because of perceived = consistency. I can buy that. However, I think by being consistent with one set of PHP syntax you = ended up being inconsistent with another set; the brace-enclosed block. = In a brace-enclosed block statements are separated by semi-colons, not = commas. And given your use of `case` we could argue that the `case`s = are sub-statements of the switch. So I think both of our arguments as suspect here you are actually = introducing a new syntactical structure with this switch expression that = has no current analogue in PHP. It is unlike anything else that comes = before it, and so I think it would be a mistake to be consistent in some = ways but not in others. Better to introduce rules that are specific to = this structure that to justify the rules based on only partial = consistency. Basically you are introducing the following syntax where the entirety is = an expression: [()] { = } And we should explicitly consider what are the best rules to use for = this rather than allow the rules to be defined based on consistency with = something that is not like this new structure and thus potentially paint = us into a corner in the future simple because we did not evaluate it = fully. The question I think we should consider here is, what makes for a valid = ? Is it a single expression, or can be be = multiple expressions with a delimiter where the last expression produces = the resultant value? Or can it even be multiple statements, the last of = which produces the resultant value?=20 We can limit to single expressions, but that seems, well, limiting. If = we instead leave open the option for multiple statements =E2=80=94 which = a semi-colon would not conflict with =E2=80=94 then we leave open the = future option to support multiple statements in a block-enclosed = expression. But if we choose a comma we can never go down that path. = Given this, I think using comma paints us into a corner that using = semi-colon would not. As for fat arrows vs. colons, that too feels like misapplication of = consistency. A `case` is more like a ternary operator than an array = initializer, and is much more like a switch statement. I fear that use = of a fat arrow will also paint us into a corner, but I cannot think of a = specific example yet, it is just a fear based on my gut feeling. Using a = colon would likely not paint us into a corner because it has already = been used in effectively exactly the same context, e.g. the `case` = statement for a `switch`. So the question is, do we want to be consistent with an expression but = inconsistent with brace-enclosed blocks, or do we want to recognize that = this is a new type of element and design the best rules we can for this = new type of element? We can either limit a brace-enclosed expression to containing only = simple expressions =E2=80=94 which as I said seems too limiting =E2=80=94 = or we can enable the future potential for multi-line statements in a = block-enclosed expression. And that is my 200 cents on the matter. :-) >> What about break? >=20 > Let's see this example. >=20 > for ($i =3D 0; $i < 100; $i++) { > $x =3D getX($i); > doSomething( > $i, > $x, > switch ($x) { > case 0 =3D> 'ZERO', > case 1 =3D> 'ONE', > case 2 =3D> 'TWO', > case 3 =3D> 'THREE', > default =3D> break, > }, > ); > } >=20 > This should 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. As I envision, it should break `for`. And since the fact the call frame = is already pushed does not stop a `throw` from working I do not see why = it should stop a `break` from working.=20 And if for some reason that is too complicated, I do not see any reason = why it could not throw an error in that context, because the refactored = solution is trivial, and I would say, preferred for its readability = anyway: for ($i =3D 0; $i < 100; $i++) { $x =3D getX($i); $y =3D switch ($x) { case 0 =3D> 'ZERO', case 1 =3D> 'ONE', case 2 =3D> 'TWO', case 3 =3D> 'THREE', default =3D> break, }, doSomething( $I, $x, $y ); } BTW, when I code I use `break` wherever possible instead of = `throw`[1-6], and only ever use `throw` and `try...catch` when I am = forced to. So supporting throw but not break here would require an = additional comparison after the `switch` expression for people who like = me avoid `throw`, which is not ideal. -Mike [1] http://www.lighterra.com/papers/exceptionsharmful/ = [2] https://sidburn.github.io/blog/2016/03/25/exceptions-are-evil = [3] http://xahlee.info/comp/why_i_hate_exceptions.html = [4] https://www.joelonsoftware.com/2003/10/13/13/ = [5] https://mortoray.com/2012/04/02/everything-wrong-with-exceptions/ = [6] https://www.atlassian.com/blog/archives/exceptions_are_bad = --Apple-Mail=_1AB13499-2939-4E5E-B9F7-30FE3671E77D--