Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I know that null being added to every type in Java is a source of much frustration regarding the language's type system. At the same time I generally hear complaining about checked exceptions - that they clutter interfaces, encourage exception swallowing, etc. It seems to me like null inhabiting every type is a way around the language - like I want the type of this to be X, but it's actually X or null; it just doesn't look like that and is easy to forget. Don't checked exceptions provide a way for the type of something to be X or throws Exception instead of it appearing to just be X? It provides an in-code way to specify how something can fail.

Nulls in every type and unchecked exceptions seem like they are dual concepts, but one is scorned and the other praised. Why is that?

share|improve this question
add comment

2 Answers

Most people who scorn NULLs have never actually written in a language without them. People who scorn checked exceptions have written in a language with them. People have seen the downsides of checked exceptions much more then the downsides of NULL-less programming. Popular languages have used checked exceptions, but no popular language has gotten rid of NULLs.

Both of these idea are trying to prove some notion correctness in a program. In my view, that sounds like a good idea in theory but tends to fall apart in practice. The effort and restrictions placed on your attempts to prove correctness are generally not worth the benefits of the limited amount of correctness being proved.

Many specific criticisms of checked exceptions exist. I'm not going to repeat them all here, I'm sure that's been done to death. NULL may not have the same issues show up. However, the lack of widespread NULL-less programming may mean that we simply haven't had time to see them. Or perhaps checked exceptions simply produce more problems then NULL-less programming does.

share|improve this answer
6  
As somebody who has used Java (the only language with checked exceptions I know), I hate checked exceptions. So do some of the best Java developers I have ever met; they even wrote their own Java-like language without them (Gosu). I have also used a language without nulls (Haskell) and it is awesome. –  Tikhon Jelvis Jan 14 '12 at 1:04
    
I dunno what I would do without nulls but I definitely have been happy without checked exceptions. Definitely have their purpose in certain environments. –  Rig Jan 14 '12 at 1:12
    
@TikhonJelvis, I don't doubt it. I just suspect that's not the category most people find themselves in. –  Winston Ewert Jan 14 '12 at 1:24
1  
@WinstonEwert You say I'm going to repeat them all here. Aren't you mising a not in that sentence? –  PersonalNexus Jan 14 '12 at 3:22
    
@PersonalNexus, thanks –  Winston Ewert Jan 14 '12 at 3:42
add comment

I wouldn't call null and checked exceptions dual concepts; in fact, they're kind of the same thing in disguise (more on this later). Signaling failure in a return value and unchecked exceptions are dual concepts. Returning null is one way to signal failure in the return value, but it subverts the language's type system. You've already caught on to that fact - you can never have the type of just Strings, you must live with the type of Strings-and-null.

The correct approach to using the return value is to get rid of null and use a separate type (usually called Option or Maybe) that represents the concept of "a value of type T, or Nothing". An Option X is not an X - you can't assign one to the other, and you have to explicitly inspect the Option and handle both cases. You can't simply forget that the function could fail to return a value.

Maybe works well when failures are common and can be handled immediately. It doesn't work so well when failures are rare and the immediate caller can't do anything meaningful about it. When failure can only be handled further up the stack, you have to return Maybe all the way up - if you get a value, proceed, and if you don't, return Nothing, over and over again until you get to the point where you can actually handle the error. Imagine if division didn't throw an exception and instead returned Maybe Double - what a pain!

Not only is this clumsy, it forces everything between the handler and the error to know about the possibility of failure and change its return type to Maybe. This gets in the way when you're writing functions that take other functions as arguments. Sometimes you want to pass a function that could theoretically fail, but you've either ensured this won't be the case, or you can't do anything about it if it did. Unchecked exceptions come to the rescue here, because they do the forwarding of the error automatically and anything in between can be blissfully ignorant of the possibility of failure. If your only option were Maybe and checked exceptions, you'd be out of luck, because the possibility of failure is encoded in the function's return type and that makes it incompatible with the type of function you're expecting.

The problem with checked exceptions is that they're not fit for either purpose. When the error has to be handled further up, you force all code between the handler and the failure to reflect the possibility of failure in its signature. When the error can be handled immediately, you get all the benefits of Maybe - you can't forget to handle it - but it's clumsier to use than a simple if/switch! So it's kind of a clumsy Maybe in exception's clothings.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.