Hacker News new | ask | show | jobs
by nostrademons 3388 days ago
Outside of very specific low-level operations like Maps or taking .first() of an empty list, you don't handle errors with null in either Java or Kotlin. You handle them with exceptions. You can't ignore the topic of exceptions as an alternative - that is the idiomatic way to signal an error in Java and Kotlin. Nobody seriously considers having high-level APIs return "null" on error; for one, there's no way to differentiate the different things that can go wrong.

Now, there's an alternative school of thought that's gaining currency in languages like Rust, Go, and apparently Scala, and is how we used to handle them in C. That's to return special out-of-band values as part of the result type. The Either type in these languages (realistically, you wouldn't use an Option for any high-level API) in these languages makes this really easy, and sum types in general make pattern-matching on the specific error code & passing back diagnostic information a lot easier than it was in C.

I don't really want to get into a debate about error-by-value vs. error-by-exception, because there are good arguments on both sides of the debate and it's far from a settled question. Personally, if I were starting a new language today, I'd use return values for "expected" error conditions and some sort of panic/recover mechanism to indicate that the programmer forgot to handle a case.

But there's a really strong reason why Kotlin uses exceptions: interoperability with Java code. It's the same reason that Google bans exceptions in their C++ code: you can't really change the error handling mechanism of a large body of existing code, because the existing code's API all assumes certain language conventions, and if you break those conventions, you might as well rebuild the ecosystem from scratch.

So sure, if I were starting a language & ecosystem from the ground up, I'd probably use return values & pattern-matching. But I use Kotlin specifically because I want a "better Java", and need to integrate with Java libraries that may return null and will throw exceptions. If I didn't have those constraints, I'd use Rust instead.

2 comments

I have seen plenty of libraries using null to indicate an error. If this wasn't the case, as you allege, then why do Kotlin devs act like it's such a big deal? Why add a language feature for something that isn't even considered an issue instead of e.g. improving how Kotlin handles checked exceptions?
One thing I find really frustrating is that Ceylon didn't take advantage of its union types to represent checked exceptions that way :(
Go uses multiple returns for this, IIRC, not an Either type.