[patterns] Several patterns and guards

Remi Forax forax at univ-mlv.fr
Mon Aug 14 15:14:18 UTC 2023


----- Original Message -----
> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Tagir Valeev" <amaembo at gmail.com>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.org>
> Sent: Monday, August 14, 2023 5:04:19 PM
> Subject: Re: [patterns] Several patterns and guards

> While we could certainly do this, I think the cost-benefit runs in the wrong
> direction here.  This sort of thing is better expressed as an if, and that’s
> fine.  (I think you’ll agree that this example is a little bit contrived.).

And also the formatting does not help, you can compare

void test(Object obj) {
  switch (obj) {
    case Integer _,
         String _ when !((String) obj).isEmpty()
            -> System.out.println("Number or non-empty string");
    default -> System.out.println("other");
  }
}

with

void test(Object obj) {
  switch (obj) {
    case Integer _, String _
      when !((String) obj).isEmpty()
            -> System.out.println("Number or non-empty string");
    default -> System.out.println("other");
  }
}

I think that if a comma is used in a "case", the "when" should be moved to the next line to make the semantics more obvious.

Rémi 

> 
>> On Aug 14, 2023, at 5:15 AM, Tagir Valeev <amaembo at gmail.com> wrote:
>> 
>> Hello!
>> 
>> Currently, when the switch label contains several patterns, only one
>> guard could be declared, which is applied to all the patterns at once.
>> In other words, the following code is not possible:
>> 
>> void test(Object obj) {
>>  switch (obj) {
>>    case Integer _ when ((Integer) obj) > 0,
>>         String _ when !((String) obj).isEmpty()
>>            -> System.out.println("Positive number or non-empty string");
>>    default -> System.out.println("other");
>>  }
>> }
>> 
>> Does it make sense to lift this restriction? Probably it could be
>> useful to declare separate guards? Ideally it should be possible to be
>> able to declare a pattern variable, which is visible inside the
>> pattern-specific guard only (but not inside the rule body).
>> 
>> Another confusing thing here:
>> 
>> void test(Object obj) {
>>  switch (obj) {
>>    case Integer _,
>>         String _ when !((String) obj).isEmpty()
>>            -> System.out.println("Number or non-empty string");
>>    default -> System.out.println("other");
>>  }
>> }
>> 
>> Now, the guard is applied even if obj is Integer (resulting in
>> ClassCastException). This is not quite evident from the code. We may
>> say that 'when' precedence is lower than ',' precedence, but people
>> may expect the opposite. Should not we reconsider this and make guard
>> a part of the lebel element, rather than the part of the whole label?
>> 
>> With best regards,
> > Tagir Valeev.


More information about the amber-spec-experts mailing list