Re: Expression switch - an alternate proposal

2018-04-10 Thread forax
- Mail original -
> De: "Brian Goetz" 
> À: "Remi Forax" , "Stephen Colebourne" 
> 
> Cc: "amber-spec-experts" 
> Envoyé: Lundi 9 Avril 2018 17:03:12
> Objet: Re: Expression switch - an alternate proposal

>> I think i agree with you about the fact that the expression switch does need 
>> to
>> support fallthrough,
>> more on that in a folowing email.
> 
> I've been leaving this topic until we have ironed out the higher-order
> bits, but this seems a good enough time to start this discussion.
> 
>> I also agree with you that mixing arrows and colons is confusing.
> I agree this is confusing, but I think it is also not likely to be
> something people do naturally -- because the -> form, where it is
> applicable, is so much more attractive -- so the risk of confusion is
> low.   Just as style guides say to users "if you're going to use fall
> through, label it clearly", and most code does, style guides will guide
> users away from this confusion.
> 
>> Basically, your proposal is to use -> eveywhere, i think i prefer the 
>> opposite,
>> do not use arrow at all.
>> Using arrow in this context is disturbing because it doesn't mean the same
>> things if it's the arrow of the lambda or the arrow inside an expression
>> switch.
> 
> This is a reasonable alternative, but I don't think it would be very
> popular.  I think people will really love being able to write:
> 
>     case MONDAY -> 1;
>     case TUESDAY -> 2;
> 
> and will be sad if we make them write
> 
>     case MONDAY: break 1;
>     case TUESDAY: break 2;
> 
> Not only will they be said, but they will point out that the "obvious"
> answer was in front of our noses, and we did something different just to
> be different.  (You can easily imagine the "There those Java guys go
> again, verbosity for its own sake" rants, but this time they might
> actually be right, rather than the folks who can't spell "migration
> compatibility" complaining about erasure.)

Apart from the semantics difference between -> inside a lambda and -> inside a 
case,
the fact that you can use -> but not -> { } let me think that if we need a 
shorter syntax,
a one that use -> is not the best one.

> 
>> the problem is that currently -> means create a new function scope and not
>> creates a new code scope.
> 
> I think the scopes issue is a red herring.
> 
>> So if do not mixing arrows and colons is an important goal and i think it 
>> is, i
>> think it's better to not use arrow.
> 
> Or just: avoid mixing arrows and colons.

That's may be hard, if you take ASM code as an example, we have two kind of 
switchs, low level ones to parse method descriptor, generics signature, etc 
that will continue to use the statement descriptor and "association" switch, 
that associate a value to another value, when ASM transforms the high level 
Visitor API to low level bytecodes or when ASM does abstract analysis like 
computing the stack frames, those can be transformed to expression switch but 
if you take a look to these switch, usually there is do computation/allocations 
so written as an expression switch, there will be case with one single 
expression (most of them) but also one or two cases by switch that will assign 
a local variable, so with the current proposed syntax, it means mixing arrows 
and colons. 

I'm sure there are other shorter syntax possible that does not use ->, 
technically we do even need the symbol ->, so why not just use ':' as a shorter 
syntax.
You may think that it means that the grammar as to be smarter to distinguish 
between a single expression and a statement that may be followed by other 
statements but you can parse everything as statements and in a later phase if 
there is only one expression consider it as a break expression.

The main drawback i see by not having to use '->' in the grammar is that you 
can not allow fallthrough but i think we should disable fallthrough in an 
expression switch anyway.
So in term of design, i see it in the opposite way, the fact that we do not 
allow fallthrough allow us more degree of freedom in term of syntax so let us 
use a more regular syntax by avoiding to introduce '->'.

I think not introducing -> as also the nice effect of making the expression 
switch less alien compared to the statement switch because it remove one of the 
syntactic difference between them.

> 
>> Moreover, do we really need a shorter syntax given that we can use break and 
>> a
>> value ?
> 
> I suggest you do this poll at Devoxx.  Make sure to wear flame-proof pants!

I have a 3 hours session with José Paumard at Devoxx France (only 3000 
attendees, so a little smaller than the real Devoxx in Belgium) next week on 
amber and valhalla.
So i will run the poll, we will see. For the pants, i've a plan :)

> 
>> and now we can discuss about adding a shorter syntax by making break 
>> optional if
>> there is one expression.
> 
> ... which we expect to be true almost all the time.

Rémi


Re: Expression switch - an alternate proposal

2018-04-09 Thread Brian Goetz



I think i agree with you about the fact that the expression switch does need to 
support fallthrough,
more on that in a folowing email.


I've been leaving this topic until we have ironed out the higher-order 
bits, but this seems a good enough time to start this discussion.



I also agree with you that mixing arrows and colons is confusing.
I agree this is confusing, but I think it is also not likely to be 
something people do naturally -- because the -> form, where it is 
applicable, is so much more attractive -- so the risk of confusion is 
low.   Just as style guides say to users "if you're going to use fall 
through, label it clearly", and most code does, style guides will guide 
users away from this confusion.



Basically, your proposal is to use -> eveywhere, i think i prefer the opposite, 
do not use arrow at all.
Using arrow in this context is disturbing because it doesn't mean the same 
things if it's the arrow of the lambda or the arrow inside an expression switch.


This is a reasonable alternative, but I don't think it would be very 
popular.  I think people will really love being able to write:


    case MONDAY -> 1;
    case TUESDAY -> 2;

and will be sad if we make them write

    case MONDAY: break 1;
    case TUESDAY: break 2;

Not only will they be said, but they will point out that the "obvious" 
answer was in front of our noses, and we did something different just to 
be different.  (You can easily imagine the "There those Java guys go 
again, verbosity for its own sake" rants, but this time they might 
actually be right, rather than the folks who can't spell "migration 
compatibility" complaining about erasure.)



the problem is that currently -> means create a new function scope and not 
creates a new code scope.


I think the scopes issue is a red herring.


So if do not mixing arrows and colons is an important goal and i think it is, i 
think it's better to not use arrow.


Or just: avoid mixing arrows and colons.


Moreover, do we really need a shorter syntax given that we can use break and a 
value ?


I suggest you do this poll at Devoxx.  Make sure to wear flame-proof pants!


and now we can discuss about adding a shorter syntax by making break optional 
if there is one expression.


... which we expect to be true almost all the time.




Re: Expression switch - an alternate proposal

2018-04-09 Thread Remi Forax
Do we need fallthrough in an expression switch, i believe like Stephen that we 
don't.

First, as Stephen point in it's example, if we have comma separated cases, we 
need less fallthrough and even if we have a code like this

  var value = switch(x) {
case 0:
  foo();
case 1:
  bar();
  break 42;
  };

one can always rewrite it with comma separated cases and an if
  var value = switch(x) {
case 0, 1:
  if (x == 0) {
foo();
  }
  bar();
  break 42;
  };

There is another reason to not allow fallthrough,
we have rule out all goto-related syntax like break label/continue label from 
the expression switch, but we should still allow a fallthrough which is a goto 
to the next basic block.

I think we should be coherent here and do not allow the fallthrough in the 
expression switch.

Rémi

- Mail original -
> De: "Stephen Colebourne" 
> À: "amber-dev" 
> Envoyé: Lundi 9 Avril 2018 01:58:03
> Objet: Expression switch - an alternate proposal

> What follows is a set of changes to the current expression switch
> proposal that I believe result in a better outcome.
> 
> The goal is to tackle four specific things (in order):
> 1) The context as to whether it is a statement or expression switch
> (and thus what is or is not allowed) is too remote/subtle
> 2) Mixing arrows and colons is confusing to read
> 3) Blocks that do not have a separate scope
> 4) Fall through by default
> while still keeping the design as a unified switch language feature.
> 
> To tackle #1 and #2, all cases in an expression switch must start with
> arrow -> (and all in statement switch must start with colon :)
> To tackle #3, all blocks in an expression switch must have braces
> To tackle #4, disallow fall through in expression switch (or add a
> fallthrough keyword)
> 
> Here is the impact on some code:
> 
> Current:
> 
> var action = switch (light) {
>   case RED:
> log("Red found");
> break "Stop";
>   case YELLOW:
>   case GREEN -> "Go go go";
>   default:
> log("WTF: " + light);
> throw new WtfException("Unexpected color: " + light);
> }
> 
> Alternate proposal:
> 
> var action = switch (light) {
>   case RED -> {
> log("Red found");
> break "Stop";
>   }
>   case YELLOW, GREEN -> "Go go go";
>   default: -> {
> log("WTF: " + light);
> throw new WtfException("Unexpected color: " + light);
>   }
> }
> 
> How is this still a unified switch? By observing that switch can be
> broken down into two distinct phases:
> - matching
> - action
> What makes it unified is that the matching phase is shared. Where
> statement and expression switch differ is in the action phase.
> 
> The unified matching phase includes:
> - target expression to switch on
> - case null
> - constant case clauses
> - pattern matching case clauses
> - default clause
> 
> The action phase of a statement switch is:
> - followed by a colon
> - have non-scoped blocks
> - fall through by default
> - can use return/continue/break
> 
> The action phase of an expression switch is:
> - followed by an arrow
> - have an expression or a block (aka block-expression)
> - cannot fall through
> - cannot use return/continue/break
> 
> By having a unified matching phase and a separate (but consistent)
> action phase in each form, I believe that the overall language feature
> would be much simpler to learn. And importantly, it achieves the goal
> of not deprecating or threatening the existence of the classic
> statement switch.
> 
> All the key differences are in the action phase, which is clearly
> identified by arrow or colon (no remote context). Developers will come
> to associate the rule differences between the two forms with the arrow
> or colon, while the pattern matching knowledge is shared.
> 
> Of course, the matching phase is not completely unified - expression
> switches must be exhaustive, and they may have auto default case
> clauses. (Perhaps the unified matching phase mental model suggests
> that auto default would be better written explicitly, eg. "default
> throw;", which could then apply to both statement and expression. Not
> sure.)
> 
> I hope this alternate proposal is clear. To me, the split between a
> unified matching phase and a consistent but different action phase
> clearly identified in syntax results in much better readability,
> learning and understandability.
> 
> Stephen
> PS. I think there are alternate block expression syntaxes, including
> ones that avoid "break expression", but I've chosen to avoid that
> bikeshed and use the closest one to the current proposal for the
> purpose of this mail


Re: Expression switch - an alternate proposal

2018-04-09 Thread Remi Forax
moving to spec-experts as it can interest others.

Hi Stephen,
First, thanks to do a detailed analysis of the rational of your proposal.

I think i agree with you about the fact that the expression switch does need to 
support fallthrough,
more on that in a folowing email.

I also agree with you that mixing arrows and colons is confusing.

I am not sure it's that important to make a string distinction between the 
statement switch and the expression switch.
You do not give any element or why you think it's important and in my opinion, 
it's the kind of things that you think is important when you introduce the 
feature and tend to be less important if the feature was not new.

Basically, your proposal is to use -> eveywhere, i think i prefer the opposite, 
do not use arrow at all.
Using arrow in this context is disturbing because it doesn't mean the same 
things if it's the arrow of the lambda or the arrow inside an expression 
switch. 

As i know that you love puzzlers, how about ?

  int a = 0;
  switch(x) {
case 0 -> { a = 3 };
case 1 -> () -> { a = 3 };
  }
 
or this one
  switch(x) {
case 0 -> { break 3; }
case 1 -> () -> { break 3; };
case 2 -> { return 3; }
case 3 -> () -> { return 3; };
  } 

the problem is that currently -> means create a new function scope and not 
creates a new code scope.

So if do not mixing arrows and colons is an important goal and i think it is, i 
think it's better to not use arrow.
After all, we need the arrow syntax in lambda only to know if (x) is the start 
of a lambda or a cast, there is no need to have an arrow in the expression 
switch.

Moreover, do we really need a shorter syntax given that we can use break and a 
value ?
Here is your example with no arrow and no short syntax,
  
var action = switch (light) {
  case RED:
log("Red found");
break "Stop";
  case YELLOW, GREEN: break "Go go go";
  default:
log("WTF: " + light);
throw new WtfException("Unexpected color: " + light);
};

and now we can discuss about adding a shorter syntax by making break optional 
if there is one expression.

Rémi


- Mail original -
> De: "Stephen Colebourne" 
> À: "amber-dev" 
> Envoyé: Lundi 9 Avril 2018 01:58:03
> Objet: Expression switch - an alternate proposal

> What follows is a set of changes to the current expression switch
> proposal that I believe result in a better outcome.
> 
> The goal is to tackle four specific things (in order):
> 1) The context as to whether it is a statement or expression switch
> (and thus what is or is not allowed) is too remote/subtle
> 2) Mixing arrows and colons is confusing to read
> 3) Blocks that do not have a separate scope
> 4) Fall through by default
> while still keeping the design as a unified switch language feature.
> 
> To tackle #1 and #2, all cases in an expression switch must start with
> arrow -> (and all in statement switch must start with colon :)
> To tackle #3, all blocks in an expression switch must have braces
> To tackle #4, disallow fall through in expression switch (or add a
> fallthrough keyword)
> 
> Here is the impact on some code:
> 
> Current:
> 
> var action = switch (light) {
>   case RED:
> log("Red found");
> break "Stop";
>   case YELLOW:
>   case GREEN -> "Go go go";
>   default:
> log("WTF: " + light);
> throw new WtfException("Unexpected color: " + light);
> }
> 
> Alternate proposal:
> 
> var action = switch (light) {
>   case RED -> {
> log("Red found");
> break "Stop";
>   }
>   case YELLOW, GREEN -> "Go go go";
>   default: -> {
> log("WTF: " + light);
> throw new WtfException("Unexpected color: " + light);
>   }
> }
> 
> How is this still a unified switch? By observing that switch can be
> broken down into two distinct phases:
> - matching
> - action
> What makes it unified is that the matching phase is shared. Where
> statement and expression switch differ is in the action phase.
> 
> The unified matching phase includes:
> - target expression to switch on
> - case null
> - constant case clauses
> - pattern matching case clauses
> - default clause
> 
> The action phase of a statement switch is:
> - followed by a colon
> - have non-scoped blocks
> - fall through by default
> - can use return/continue/break
> 
> The action phase of an expression switch is:
> - followed by an arrow
> - have an expression or a block (aka block-expression)
> - cannot fall through
> - cannot use return/continue/break
> 
> By having a unified matching phase and a separate (but consistent)
> action phase in each form, I believe that the overall language feature
> would be much simpler to learn. And importantly, it achieves the goal
> of not deprecating or threatening the existence of the classic
> statement switch.
> 
> All the key differences are in the action phase, which is clearly
> identified by arrow or colon (no remote context). Developers will come
> to associate the rule differences between the two forms with the arrow
> or colon, while the pa