Functions not only returns single values but they also gives us errors/exceptions

As the functions can take multiple inputs, same it can give us multiple outputs including a Value (In case of success) or a Failure object (in case of failure).

Currently we handle expcetions using try catch and kotlin.Result. Which does not gives us information about what errors a funcation could throw without reading the documentation.

I think that function should be defined as something following

fun getContent(txtFile: String) : String, FileNotFound, SecurityError

Above function describes that it returns String on Success and one of the error object on failure.

use site code

fun main () {
  val txt = "some.txt"
  val result =  getConent(txfFile)
  when(result){
    is Ok -> { printlin("content: $result.value") }
    is Err -> {
        when(result.kind) {
            is FileNotFound -> { println("file not found.") }
            is SecurityErr -> { println("Permission is required to read the file.")  }
        }
    }
  }
}

There should be similar way of describing errors

1 Like

See the Either datatype or Result from Result4k

2 Likes

It seems like you want to recreate checked exceptions. So I’d first suggest looking into what those are, and the possible reasons why they were deliberately removed from Kotlin.

1 Like

I think he probably wants to have union types instead. Personally I would also like to opt for this feature in Kotlin.

1 Like

Combine this with sealed classes, and you can get what you want. So in this case, your function would return Either<String, GetContentError> (or Result<String, GetContentError>, which ever library you prefer), and then you create a sealed class called GetContentError, and have subclasses that represent the possible different error states.

sealed class GetContentError
class FileNotFound : GetContentError
class SecurityError : GetContentError

I might be wrong on the syntax; I forget if you extend the sealed class, or put stuff inside the sealed class as subclasses. Hopefully you get the general idea. :slight_smile:

1 Like

There are a proposal for your requirement: https://youtrack.jetbrains.com/issue/KT-68296/Union-Types-for-Errors

Isn’t that merely recreating — in a more awkward and less supported form — exactly what Java already has and Kotlin deliberately removed?

1 Like

If you are talking about checked exceptions, they are quite different. Exceptions are a non-local control flow - a restricted form of goto if you will, which is breaking the referential transparency of functions (which in turn makes them harder to reason about).

Union return types are nothing special, they can be simulated with types like Either, but as a very common use case, it would be nice to reduce the clunkiness and make their usage more stream-lined and convenient.

1 Like

Yes, but using a union return type with an error code gives you only a subset of what checked exceptions do: like error codes, they too let you (effectively) return either a value of a given type or else a throwable; like error codes, they too force you to deal with or at least acknowledge the possibility of an error; and like error codes, they clearly document that possibility.

The mechanics and syntax are of course very different, and as you say exceptions have the option of being handled elsewhere — but you must at least acknowledge them (by catching, or by declaring as thrown by the enclosing function).

And since checked exceptions are now recognised by many as having various undesirable properties (as per my link), won’t error codes also be equally undesirable? Or if not, it’s necessary to explain why not.

What do error codes give you that checked exceptions don’t? And do they avoid those pitfalls? (And if so, how?) Without good answers for those, it’s hard to see any benefit.

(Of course, that’s not an argument against supporting union types generally — but that’s not really what the question was about.)