groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Remi Forax <fo...@univ-mlv.fr>
Subject Re: [GEP] Switch expressions syntax from Java 11 or 12 (perhaps)
Date Thu, 08 Mar 2018 19:52:53 GMT
----- Mail original -----
> De: "Jochen Theodorou" <blackdrag@gmx.org>
> À: "dev" <dev@groovy.apache.org>
> Envoyé: Jeudi 8 Mars 2018 19:51:57
> Objet: Re: [GEP] Switch expressions syntax from Java 11 or 12 (perhaps)

> On 08.03.2018 17:34, Remi Forax wrote:
> [...]
>>>> int accumulator = 0
>>>> LOOP: for (T element : someList) {
>>>>    accumulator += switch (element.type) {
>>>>      case PLUS_ONE -> +1;
>>>>      case MINUS_ONE -> -1;
>>>>      case ERROR:
>>>>        break LOOP;
>>>>      case default -> 0
>>>>    }
>>>> }
>>>
>>> with the idea that element.type is an enum... But my problem is with
>>> break LOOP. Is LOOP the label LOOP, or is it a constant/variable?
>> 
>> this will not compile, because you can not use return or break/continue inside
>> an expression switch.
> 
> you mean I cannot use the normal break/continue inside an expression
> switch, because this example
> 
>> int result = switch (s) {
>>     case "Foo" -> 1;
>>     case "Bar" -> 2;
>>     default:
>>         System.out.println("Neither Foo nor Bar, hmmm...");
>>         break 3;
>> }
> 
> is straight from the JEP 325 page. And that was actually my point, this
> overlap, but redefinition of break. 

yes, you can not use the normal break/containue inside an expression,
so break foo; in an expression switch has only one meaning. 

> break is what makes the switch-case ugly for most people in the first place. Giving that
special treatment like this looks off to me.

using break here is ugly, i agree with you but we (the amber EG) are not able to find a better
solution,
if you know a better way to handle local return of a value in the case of a switch, please
help us.

> 
>>> If they need the break only to break out of the switch, then why not
>>> capitalize on lambdas ?
>> 
>> it was the first idea :)
>> but lambda can capture effectively final local variable, when a case in an
>> expression switch acts more like a routine so you can access any variables with
>> no restriction. So re-using the same syntax for two different semantics is not
>> a good idea.
> 
> A problem you would not have in Groovy, because we don´t do the
> capturing like Java.

It's not like in java but you use a box so the perf model is still not the same between a
captured variable and a plain old variable in Groovy. 

> 
>> The idea is that the expression switch should be used when it's a simple switch
>> and the C switch with all it's subtle behaviors if the control flow is more
>> complex,
>> exactly like you use for(:) if it's a simple loop and for(;;) if it's a more
>> complex one.
> 
> maybe, but I still think it does not make so much sense on its own. With
> a step-by-step approach of getting features in I can understand this,
> but then it means to decide to use this here, before deciding the
> details of pattern matching... and that sounds wrong.

no, the Java part of the pattern matching is mostly decided (there is still corner cases like
how re-starting when a guard fails).
The pattern matching is delayed more because
1/ the VM support is not there, part will be in the jdk 11, but how to specify a sealed interface
to avoid to have to specify a default when you have cover all the cases is still open.
2/ the support of de-constructor (extractor) to keep encapsulation without allocation in the
middle of the pattern matching requires:
   2a/ value types, good progress have been made on the valhalla side, a release of value
types without changing generics (which is a major PITA) may be a temporary solution.
   2b/ another temporary solution is to make pattern matching only working on records (data
classes).
   
The only part of the pattern matching which is ugly IMO is how to specify a "local return"
of a value in a case with several instructions. 

Now, releasing an expression switch first has several advantages:
- allow to align the old switch with the pattern matching switch by modernizing the behavior
of the old switch with respect to null.
- it fixes several bugs of the current switch implementation:
  - having to recompile the switch when you change the enum
  - the switch on string being slow when the number of cases is small
  - reduce the switch footprint in term of bytecodes    
- and obviously allow to use a switch that "returns" an expression. 

> 
> bye Jochen

regards,
Rémi

Mime
View raw message