`any` clause for `when` statements?

I’ve been encountering this problem a lot lately, where I want to execute the same code for a few conditions on top of the different code that each one of them has, like this:

when {
    A -> {
        foo
        bar
    }
    B ->  {
        moo
        bar
    }
    else -> baz
}

And I just want to avoid having to copy and paste that bar part in each one of them.
Am I missing something? Because it feels like there should be some way to do this. In similiar cases where there’s one condition that I don’t want to execute this ‘bar’ in, I can just put it at the top of the if or when statement and then nest another if or when inside the else statement like this:

if (C) baz
else {
   when {
       ...
   }
   bar
}

But I can’t think of any ‘clean’ way to do this in the first example.

So anyway, I thought it could be useful to have something like an any clause that would work like this:

when {
    A -> foo
    B -> moo
    any -> bar
    else -> baz
}

Where bar only executes if any of the conditions above it were true.

What do you think? My concern was that appending code like that might be a little too specific, and this also doesn’t provide a way to execute code before any of these conditions, but I still feel like this feature, or something similar to it, could be useful.

I don’t know about anyone else, but I’d find that highly misleading.

Right now, when cases are exclusive: only one is executed. That might seem a no-brainer, but it’s not: even if you’re listing objects rather than conditions, depending how equality is defined for those objects, more than one could match — but only the first match is taken. (So it’s rather like a single ifelse ifelse if construct.)

This makes them fairly easy to follow: even in a very long when construct, you only need to read down until the first match, and can ignore the rest.

Your suggestion would change that, allowing multiple cases to match. That would make it much harder to reason about the results. If some of the conditions got complex, it could get really hard to see exactly when the any branch could be get executed.

It’s also oddly specific. What if you wanted to execute some common code before the other branches? Should it allow multiple any branches, before and after the other conditions? What about in between other conditions? What order would the branches get executed in? Would it even check the later conditions at all?

What if you need to add a new branch that doesn’t cause the any branch to be executed? That would need a total rewrite, or squeezing further checks into the else branch.

So allowing multiple branches to be executed in some cases but not others would be inconsistent and confusing. It seems much more likely to lead to confusion and bugs. It would be much simpler to allow all matching branches to be executed — but then what you have is a very different structure (rather like a series of separate if constructs), with different use cases, and not a when at all.

There are several existing approaches to handling your particular case (such as defining a lambda or function to call in each branch, or setting a flag in the else branch that you check for below the when). So there’s no need to change the nature of a useful and well-used construct.

2 Likes

I was thinking about the any branch more like as shortcut for appending code to multiple other branches rather then a branch of its own. It wouldn’t change the way when statements work.

I don’t really like the solutions you’ve mentioned because they add just a little extra overhead, which I know is insignificant but it feels unnecessary.

If you need to add a new branch that won’t activate the any branch you could place it under it, or if you need it to be checked first you can nest a when statement inside the else branch like I showed in the second example in my post.

Like I said, I know it’s pretty specific to append code at the end of those other branches, I think the question is whether it’s useful or not, and I’m also hoping that maybe someone has a better idea for a feature that would solve that.

Also, the any branch can be added to if statements as well because they basically work the same as when statements, but I don’t know, that somehow feels wrong.