Hi Kosit,

Thank you for your reply.

> On Oct 20, 2019, at 3:54 AM, Kosit Supanyo <webdevxp....@gmail.com> wrote:
> 
> Hi Mike
> 
> Is there a strong reason to change to using fat arrows and colons?
> 
> 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:

<expression-designating-keyword> [(<selector-expression>)] { 
<brace-enclosed-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 
<brace-enclosed-expression>?  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? 

We can limit to single expressions, but that seems, well, limiting.  If we 
instead leave open the option for multiple statements — which a semi-colon 
would not conflict with — 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 — which as I said seems too limiting — 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?
> 
> 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 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. 

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 = 0; $i < 100; $i++) {
    $x = getX($i);
    $y =  switch ($x) {
            case 0  => 'ZERO',
            case 1  => 'ONE',
            case 2  => 'TWO',
            case 3  => 'THREE',
            default => 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/ 
<http://www.lighterra.com/papers/exceptionsharmful/>
[2] https://sidburn.github.io/blog/2016/03/25/exceptions-are-evil 
<https://sidburn.github.io/blog/2016/03/25/exceptions-are-evil>
[3] http://xahlee.info/comp/why_i_hate_exceptions.html 
<http://xahlee.info/comp/why_i_hate_exceptions.html>
[4] https://www.joelonsoftware.com/2003/10/13/13/ 
<https://www.joelonsoftware.com/2003/10/13/13/>
[5] https://mortoray.com/2012/04/02/everything-wrong-with-exceptions/ 
<https://mortoray.com/2012/04/02/everything-wrong-with-exceptions/>
[6] https://www.atlassian.com/blog/archives/exceptions_are_bad 
<https://www.atlassian.com/blog/archives/exceptions_are_bad>

Reply via email to