0

If kotlin promotes safe code such as:

val currentName = "Some Guy"
getDataFromServer()?.getUsers()?.find { it.name == currentName }?.profilePicture?.let {
  showPicture(it)
} ?: let {
  showAddPictureButton()
}

Why there is no similar syntax for exception handling, for example using imaginary ??. operator:

val someUserId = 123
val newName = "Cool Dude"
connectToDatabase()??.getDao<UserDao>()??.changeUserName(someUserId, newName)??.let { newUserData ->
  reloadView(newUserData)
} ??: let { error ->
  interpretAndHandleError(error)
}

I don't see drawbacks here. Is there any reason this is not a part of language?

xinaiz
  • 7,744
  • 6
  • 34
  • 78
  • Unlike Java, try/catch is an expression in Kotlin. What would this proposed syntax buy us beyond that? It's confusing what happens when something could be null *or* have thrown an exception. – Tenfour04 Mar 09 '20 at 15:53
  • As for expression, the same applies to `if else`. We could write `if ( someVal != null ) { someVar.property } else { null }` but it's much more healthy to write `someVal?.property`. About nullable return types, yeah, that's a concern. Maybe limit it only to non-null types? Alternatively, `??.` operator still could result in nullable type if expression is of nullable type, and to handle that as well even stronger operator could be used (`???.` operator? That's many question marks though) – xinaiz Mar 09 '20 at 16:33
  • What would `??.` exactly return here? An exception can be more or less any class, and might require custom handling, whereas with null you have a "single" case/value and there's an implicit convetion you don't do anything when you encounter a null. – al3c Mar 09 '20 at 16:35
  • @al3c It would still return the same type as original expression. There would have to be separate flow for nullability and error handling. That means that `??.` operator doesn't return `null` on exception, but starts error flow, which can be resolved (or must be resolved) by the `??:` operator. – xinaiz Mar 09 '20 at 16:48
  • It seems you're trying to 'hide' an exception together with a value, which seems quite suprising, you can have variables of any type actually concealing an exception. By the way kotlin has `runCatching` and `Result` which can be used to do something like what you suggest, but in a typesafe way. – al3c Mar 09 '20 at 17:38

1 Answers1

4

It isn't about drawbacks, but about not having sufficient benefits. Consider writing your first example without ?.:

val data = getDataFromServer()
if (data != null) {
    val users = data.getUsers()
    if (users != null) {
        val user = users.find { it.name == currentName }
        if (user != null) ...
    } else null
} else null

You can see it's much more complex than the original code. Now consider writing your suggested ??. without it:

try {
    connectToDatabase().getDao<UserDao>().changeUserName(someUserId, newName).let { newUserData ->
        reloadView(newUserData)
    }
} catch(error: Exception) { 
    interpretAndHandleError(error)
}

Where is the complexity you want to eliminate?

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487