I'm sure it's a pretty common request to have `whe...
# language-proposals
a
I'm sure it's a pretty common request to have
when
statement support multiple conditions for the else block, does anyone know if there's an official feature request or discussion around this?
Copy code
when (x) {
  1, 2 -> println ("one or two")
  3, else -> printlnt("doesn't compile")
}
2
k
Can’t imagine a situation where I would want to do this. Why not just get rid of the
3,
Or rather (since this isn’t an assignment expression), you could replace
else
with
in 4..Int.MAX_VALUE
I’d most definitely go with the former though
a
The argument in favor of it is to document intent. While the functionality I want is achievable without
3,
, you can argue that the next developer who comes through might assume I forgot to consider a case.
a
My question would be: Is the case that is appears to be duplicated on the
else
case true duplication ("they change for the same reason at the same time"), or accidental duplication ("they change for different reasons at different times")?
I suspect a duplication would be accidental duplication and the two cases should not be combined.
k
Yea. I think cases and defaults should probably not be combined. Either you separate the cases from the default, or the default captures it all For example, do you think
else, 3 -> println("something")
should compile?
t
else
case is basically
true
, while
,
is
||
operator in boolean expression here. Why would anyone write boolean expression like this
x == 3 || true
?
a
I agree: If you want 3 to have the same functionality as everyone else, there's no real reason to specify 3 as a special case. I did see the argument for clarifying intent, to validate that I didn't forget to consider 3, but I'm intentionally lumping it with everything else, so that the next person doesn't think "oh, he forgot to consider case 3". Which is still a pretty nuanced scenario IMHO. I brought this up out of due diligence from a conversation in #getting-started , but it's not a hill I'm willing to die on so I'm not gonna stress over pushing for it. Just wanted to know if there was an official discussion somewhere that people could share their thoughts and hash it out.
👍 2
a
I actually do think it's worth considering. My reservations mainly lies in whether or not there are some good use cases. I'm really wondering if all of the real use cases are accidental duplication.
d
I also think it's worth considering, for the same reason as the original poster. There were multiple cases where I would've liked to be able to do the thing described to make the code more readable. I disagree with the argument put forward by @arocnies earlier, there just are (frequently) cases where you want a distinct case to do exactly the same as the else block, where there is no such thing as "accidental duplication". I think it would rather be "accidental duplication" if the programmer repeated the same code for a given case and the else case to achieve clarity of the code. @themishkun nobody is writing the expression
x == 3 || true
when they expressly indicate that the case
3
should do the same as
else
block, despite it being effectively the same. It's just for code clarity, programmer knows it isn't a necessity. Of course, the programmer can use a comment, but a comment can be anything. When compiled, the case can just be dropped and ignored like a comment, but that doesn't restrict the syntax or allow the programmer to move the case without thinking. Of course, it's not a big nor important change, just giving my 3 cents.
t
@adam-mcneilly @Dico Your usecase “clarifying that the programmer knows what he is doing” have the special instrument to deal with - code comments.
Copy code
when (x) {
  1, 2 -> println ("one or two")
  // 3 and other cases won't compile
  else -> printlnt("doesn't compile")
}
2
d
Which is much more verbose than just
3, else
. I've mentioned comments as a potential workaround along with my thoughts on that.
t
And much more versatile and can handle much more usecases without introducing any new features
d
I don't really mean to go on and on about this particular request, but allowing
case, else
is not adding a new feature.
Here's a question: Is the reason the compiler has not to allow it, better than the reason proposed to allow it?
k
I believe if the intention is to document indent, then a detailed documentation in comment goes with it nicely 😄 I'm not against the request though (even though like I said, I most definitely won't do something like this), I just don't see it as anything worth updating the language syntax for
d
Fair enough.
r
To reiterate a point from the #getting-started discussion, when doing it with comments, we're bound to have situations like this:
Copy code
when (it) {
    1 ->
    2 ->
    3 ->
    4 ->
    // case `1` is same as else-branch
    else ->
}
And suddenly you're on your own to figure out if someone just forgot to delete the comment, or someone mistakenly added the 1-branch he thought was missing because he didn't read the statement to the end, or whatever. Documenting intent in a way that the compiler or at least the linter can help you with is always superior to comments, imo.
A valid use case for this functionality that does not involve accidental duplication would be the case where the user can select a locale:
Copy code
when (locale) {
    DE ->
    FR ->
    EN, else ->
}
Which would very clearly document that the EN locale should be used if there is no specific instruction for the given locale. Of course you could do that mapping before the when statement, but then you might need to introduce a sealed class or an enum just to convince the compiler that the when statement is exhaustive, so it might be cleaner to just do it this way.
2
a
So to clarify, I'm not against the idea (my gut feeling is I like it), I just can't think of a use case that doesn't involve accidental duplication--I'm using that term from Bob Martin's book "Clean Architecture". @robin It's great to have another example. I'd argue that this example shows accidental duplication, not true duplication. The EN case and the default case change at different times for different reasons--sure, right now they may execute the same code, but it's not true duplication. ^ With that said, it may not matter. Maybe there's another case that show's true duplication, or maybe regardless, the else is convenient enough to use. I suspect either argument in support of this may be enough to add the feature.
d
Sorry for slandering the accidental duplication thing. It makes a little bit more sense to me now. I misunderstood what you meant.
r
I'd say it still is true duplication - the specification in this example explicitly states "if it's an unknown locale, the behavior should be the same as for the EN locale." So, if EN changes, the default behavior should definitely change as well, and for the same reason.