Multi "if" language construction


#1

How about adding new language construction, for example “multiIf”. Like “when”, but without return and with check all conditions

someFlag = true
someOtherFlag = false
multiIf {
    someFlag == true                           -> doSomeWork()        // executed
    someOtherFlag == true                      -> doSomeOtherWork()   // skipped
    someFlag == false && someOtherFlag == true -> doSomeSpecialWork() // also executed
    else                                       -> doNothing()         // skipped
}

x = 3
multiIf(x) {
    3        -> doSomeSpecialWork()      // executed
    isEven() -> doSomeWorkWithEven()     // skipped
    isOdd()  -> doSomeWorkWithOdd()      // also executed
}

For example parsing command line options/

Now:

 if(cmd.hasOption("t") {
     doSomeWork()
 }
 if(cmd.hasOption("m") {
     doSomeOtherWork(cmd.getOptionValue("m"))
 }
 if(cmd.hasOption("g") {
     gFlag = true
     doSomeOtherWork2()
 }

My variant(draft):

multiIf(cmd){
    hasOption("t") -> doSomeWork()
    hasOption("m") -> doSomeOtherWork(getOptionValue("m"))
    hasOption("g") -> {
       gFlag = true
       doSomeOtherWork2()
   }
}

#2

I don’t see a great enhancement on distinct if statements.


#3

Why would you want that?

You do know the compiler is open source, you can always fork it and add this yourself.


#4

I don’t see a great enhancement on distinct if statements.

“When” is syntax sugar for “if-else if-else” construction. It make code more clear.

Multiple “if-else” also is a dirty pattern.

One of Kotlin principles - make the code short, simple and clear. For that reason I do not see any barriers for adding some useful sugar, that can make code more clear.

It is not great enchancement. It is small, but useful enchancement.


#5

If the ‘when’ statement had fallthrough (which I believe is being considered for a future version using the ‘continue’ keyword), then this would meet the aims of this proposal.

I’m assuming of course that you always include an ‘else’ clause in the statement form of ‘when’ so that it is exhaustive.


#6

How is if-else “dirty”? You seem to be saying that this construction looks prettier. I’m sure people will disagree or agree with you but that is a matter of opinion.

But the bigger point is that this change in no way comes close enough to being significantly better than the existing structures with no objective additional benefit (just your opinion that it’s neater). Every last user of the language would have to know and understand this redundant and unfamiliar feature and the authors of the compiler would not be working on objectively useful features to implement this one.

When you consider that you have to admit that there is no basis for this sort of a change.


#7

and the authors of the compiler would not be working on objectively useful features to implement this one.

And who determine, that ability is useful or not? You? Maybe let community and authors make decision?

I just suggested thinking over good (imho) improvement. If you think that it is not good - ok, I respect your opinion. But please do not speak for everyone.


#8

Rolled my own version: https://try.kotlinlang.org/#/UserProjects/udo4u9qf5kbhr6jugonaak3q61/rk6pnb9a1bqd4jhdig2u5m5ivs

The first example could take x as a receiver like the other examples, which would improve things a bit.

// --- Example similar to the proposal 
fun multiIf(vararg conditionPairs: Pair<Boolean, () -> Unit>) {
    conditionPairs.forEach { (bool, func) -> if (bool) func() }
}

multiIf (
    (x == 3)     to { doSomeSpecialWork() },      // executed
    (x.isEven()) to { doSomeWorkWithEven() },     // skipped
    (x.isOdd())  to ::doSomeWorkWithOdd           // also executed
)

The second example uses the standard with(...) function.

// --- Example using `with(...)` and custom function
infix fun Boolean.then(block: () -> Unit) { if (this) block() }

with(x) {
    equals(3)   then { doSomeSpecialWork() }
    isEven()    then { doSomeWorkWithEven() }
    isOdd()     then ::doSomeWorkWithOdd
}

The third example does nothing special and is my favorite:

// --- Example without using custom function
with(x) {
    if (equals(3))  doSomeSpecialWork()
    if (isEven())   doSomeWorkWithEven()
    if (isOdd())    doSomeWorkWithOdd()
}

In my opinion, a multiIf feature could improve some things–prettier syntax and maybe an exhaustive check–but it still doesn’t hold enough weight to be added alone.

The proposed use of the arrow (->) is basically the same as the second examples Boolean.then(...) function but the then function requires parentheses around the condition.

Note: All of these examples lack the exhaustiveness check built into when.