Or you could just require parentheses when the meaning might not be clear. And I mean _require_: allow
case P when e: case P, (Q when e): case (P, Q) when e: but NOT case P, Q when e: And if you object that case (P, Q) when e: should really mean a single tuple pattern (P, Q) plus a guard on it (I agree!), then that tells me that it was a bad idea in the first place to use commas as a separator of patterns in a case label. —Guy > On Aug 14, 2023, at 11:44 AM, Brian Goetz <[email protected]> wrote: > > So, there are two stable points here: make the where clause part of the > pattern, or match it with the case label entirely. The middle option is not > stable; a case like > > case P, Q when e: > > Is no longer clear, and worse, if the when clause binds to Q, then we would > have to repeat the guard if we wanted `(P|Q) when e`. We explored guards on > patterns (P && e) and concluded that it was better treated as part of the > switch rather than the pattern. > > > >> On Aug 14, 2023, at 8:28 AM, Tagir Valeev <[email protected]> wrote: >> >> I don't think that my example is contrived. Let's think of it from >> another angle. Are multiple patterns in the same switch label useful >> or contrived? If not useful, then let's disable them completely. If >> useful, then the next question: are guards with multiple patterns >> useful or contrived? Can you imagine a case when the single guard for >> the whole label will be useful (provided that we cannot declare any >> variables)? I'm not quite sure that a non-contrived example is >> possible. So probably we should disable guards with multiple patterns >> completely? >> >> My point is that having a separate guard per pattern is much more >> useful and less confusing than having a single guard for all patterns. >> You may convince me that I'm wrong by providing not-so-contrived >> examples. >> >> By the way, the following colon-style switch looks supported (though >> buggy again, reported JDK-8314226): >> >> void test(Object obj) { >> switch (obj) { >> case Integer _ when ((Integer) obj) > 0: >> case String _ when !((String) obj).isEmpty(): >> System.out.println(obj + ": Positive number or non-empty string"); >> break; >> default: >> System.out.println("other"); >> } >> } >> >> And it looks like there's no way to express the same with an >> arrow-style switch, or even replace adjacent cases with comma (which >> is possible for other cases). >> >> With best regards, >> Tagir Valeev. >> >> On Mon, Aug 14, 2023 at 5:04 PM Brian Goetz <[email protected]> wrote: >>> >>> 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.). >>> >>>> On Aug 14, 2023, at 5:15 AM, Tagir Valeev <[email protected]> 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. >>> >
