In future, could Kotlin have checked exceptions?

@elizarov

They don’t work in a functionally-oriented language.

No other modern language has them.

I don’t think this is true. Some counter-examples:

Purescript: Control.Monad.Except.Checked - purescript-checked-exceptions - Pursuit

Also, arguably Koka: GitHub - koka-lang/koka: Koka language compiler and interpreter

Note that both are functional languages. Really anything with some form of extensible effect/coeffect system lets you do something akin to checked exceptions in a very functional context.

The “problem” with checked exceptions and functional languages as I see it is that most languages with functional features do not have good support for “graded” categorical structures. From what I remember, these ideas are fairly new (I wrote my master’s thesis on the topic – but it’s been awhile since I’ve actively studied the topic). For instance, this paper was published in 2016.

For instance, people often give the example of a “visit” function. Here’s what that would look like with a graded “MonadThrows” monad that models checked exceptions in Haskell:

visit :: MonadThrows m e => [a] -> (a -> m e ()) -> m e ()

The exception type e is propogated out of the lambda in the second argument.

For even better usability (this is where lack of language support for graded structures comes in) you really want to have something that looks like this (using a pseudo-haskell syntax) for a monadic bind:

class GradedMonad m e where
    identity :: e
    return :: a -> m identity a
    bind :: m e1 a -> (a -> m e2 b) -> m (e1 | e2) b

where here | is a union type, so for instance to give a really contrived example you could do things like:

test :: MonadThrow m (IOException | SomeOtherException) ()
test = do
    contents <- readFile "test.txt"
    if contents == ""
        then throw SomeOtherException
        else putStrLn contents

John (a fictional character in this story), just died.
The machine that was keeping him alive stop working properly.

The machine was controlled by an Android device.
Even do the app was wrote in Kotlin, most of the libraries related with Android were wrote in Java.

One of the nurses, just happen to try to send a report by sharing it with another app.
In that moment, the app crashed.

IT Forensics took a look into the log and found out this exception: PackageManager.NameNotFoundException

When the developer was approached, they found out that the person was new in Kotlin but had a background in Java.

Normally, when working with Java, modern IDEs would provide some warning when an exception needed to be caught:

Please notice the red line below the method sleep, indicating to the developer that there is a problem that should be taken care of

This feature allowed the developer to cover most of the cases of things that could go wrong. Just leaving weird cases to be discover later.

However, when working with Kotlin, the IDE was quiet:
image

Yes. The developer could hover the mouse over the method and wait until a box would show up and read that there was an exception; however…

Why the IDE was quiet then?

Why the IDE didn’t mark the method to make it easy to spot a possible problem?

Could it be that those behind the IDE forgot to provide some mechanism to detect these exceptions and report them back to the developer as when developing with Java?

Could it be that when developing the IDE that would parsing the Kotlin code, they didn’t add the feature due Kotlin’s documentation? Exceptions | Kotlin

I mean, Kotlin has a different approach as shown in the video below:

Yes. It is the fault of the developer because didn’t take the time to go over the documentation of every little thing he or she encounter and trust the IDE; however, isn’t the idea of using a smart IDE to speed up development?

Or perhaps is that Java still remain behind the scenes. Java has different rules than Kotlin and Kotlin should support them, if we insist that Java should remind behind the scenes.

Perhaps, Kotlin could actually change the paradigm related with Exceptions if would get rig of everything related with Java behind scenes?

However, until that day arrives, is it possible to provide something that could help the IDE’s to notify the developers about these exceptions in an active way? How about an Annotation? Something.

Anything that could help to prevent to go over every little piece and check if there are some exceptions to take care of?

Or this is something that IDE should take care of?

We do have a plan for effects and coeffects via the multiple receivers. They, indeed, help with organizing error-handling strategies in code. You can read more in the corresponding KEEP - KEEP/context-receivers.md at context-receivers · Kotlin/KEEP · GitHub

For an application like the one you describe it should be something that a static analyzer is used to detect and flag. It is a cheap inspection that could also be integrated into the IDE default analysis.
Unfortunately exceptions are a deceptively attractive, but in many ways broken, in particular in the various contexts where exceptions pass through a library layer. Neither exceptions wrapping exceptions; excessively long expected exception lists (many of which cannot be handled by the caller anyway); nor overly generic exceptions (eg. throws Exception) are desirable. A better approach is not definite, but things like Result monads seem more promising. Most importantly, there is nothing stopping you from having a coding standard (enforced by static analysis) that forces catching, but you will have to deal with the fact that many Kotlin libraries do not declare thrown exceptions.

As to correctness, one of the challenges here is that exceptions are meant for stuff that is never supposed to happen, not just to support invalid inputs made by a user (entering text into a field that allows that but expects numbers is not an error from the program perspective). Also keep in mind that writing exception safe code is extremely hard, and in your life-and-death case, you would need to build tests to ensure that your code is exception safe (if an exception is thrown anywhere the system is always in a valid - and correct - state).

1 Like

Speaking as someone who writes medical software for a living, although I would love to see better support around error handling in all sorts of languages (a) adding some IDE feature to warn you about Java checked exceptions propagating into Kotlin still wouldn’t handle RuntimeException being thrown where it shouldn’t be or wasn’t expected, from one of your many Java dependencies; and (b) if your quality system relies so heavily on IDE warnings to prevent loss of life, you ought to be heavily fined, or never certified in the first place!

Also, showing warnings for Java checked exceptions in a Kotlin context might lead the developer to gain a false sense of security, since exceptions from Kotlin code won’t be highlighted. It’s not the developer’s fault, necessarily, but it is the company’s fault for allowing them to work on safety-critical software without adequate training.

1 Like

Hugh,

My previous message was a general example.

If you write medical software, then you should know that most of the time, C is the language used.
The reason is that C allows the developer to be closer to the hardware that must control.
A good C developer can have a good clue on the Assembly being created.

How do I know? Well, my former roommate quit the field after he couldn’t handle having to install electrodes inside monkeys brains.
They would analyze the signals when the monkey would move its eyes and other things.

Regardless, we are not here to talk about your credentials or mine, Hugh.
We are here to talk about Kotlin.

Now, don’t get me wrong. I like Kotlin. I think is great.
However, the issue here is that Kotlin is working together with Java and Java has some idiosyncrasies that Kotlin isn’t addressing.

You see, as a developer, I’m counting in the documentation, the API, and the libraries wrote in Kotlin to do my work.
To provide another example, if I’m building a parser, an analyzer, or some short of auto-help, for example, I am going to use those things.
If those things are missing the idiosyncrasies from Java, when Java does produce a side effect, then we have a problem at hand.

Also, there is a matter of speed Hugh.
Why do developers must be breaking into proprietary code or spend hours going over every line of code in relation with Kotlin to do their job?
There is a reason we create tools and solutions to write robust code faster.

Plus, the IDE is only one of those tools. You know that there are unit test, automated test, solutions such as SonarCloud to verify code smell and short.
However, the fact is that the documentation is leaving side effects, coming from Java, out. That’s a big no.

So, either lets take Java out of the equation or lets build something that takes the idiosyncrasies of Java in account.