Using an "else-less if" as an expression should not compile

This is inconsistent:

println("Unexpected: ${ if ( n == 5) "x" }")

println("Invalid: ${ when(n) { 5 -> "x" } }")

A non-exhaustive “if” statement always returns unit when used as an expression, while a non-exhaustive “when” statement is a compile error.

I think that those two should behave in the same way when they are non-exhaustive and I think defining it as a compile error is the best solution:

  • “when” already works that way.
  • Using an “else-less if” by accident is probably more likely than doing it intentionally [[citation needed]]
  • If you really need to use if without an else as an expression where you don’t actually care about the return value you can still add an “else” branch that returns null.

I often use first expression with if (e.g. to add suffix in version names for specific build types) and for me it is clear enough. I never thought about adding "else null". It is implicit. It would create only boilerplate code.

Could you give an example? Do you mean this?:

var versionName = "GreatProgram${ if( isBeta() ) " BETA"}"

Because that doesn’t work, it would ALWAYS set versionName to this:

GreatProgramkotlin.Unit

If you would do this instead:

var versionName = "GreatProgram${ if( isBeta() ) " BETA" else ""}"

Then, depending on whether isBeta returns true or false you would get one of these:

GreatProgram

GreatProgram BETA

Ok, I must apologize you, because I have else statement:

 
"${BuildConfig.VERSION_NAME}${if (isTestHost) "-test" else ""} (${BuildConfig.MODEL_VERSION})"
 

so I am for throwing exception or returning empty String (in else-less if).

We are considering something along these lines