Saturday, August 1, 2009

Returing Null... again

so... thinking more about returning null. I'm thinkin' returning null is allowing you to return a second type from a method. And a null pointer exception is equivalent to a class cast exception. AND a null check if (foo == null) is the same as an instance of check.

nulls are syntactic sugar for a type! I refuse to think of them as values for references any longer. They are types, returning them from functions is returning multiple types from a function (not in a polymorphic way, but in a type system abusing way) and null checks are instance checks.


Brad said...

I agree and disagree here.

Null is abused often. The major way it is abused is that it tries to provide a signifier to the client program that something is in an exceptional state and needs to be handled.

I'd say if this is the case, you need to either a) provide a safe default implementation to the client (e.g., a Default well-formed object) or b) return an Exception.

(a) is dangerous because the client program can simply go about its job without knowing something is "wrong". It needs to check that its in this state using some other method than a null check. In essence, you're trying to use null as a way of creating a default signifier that the return object is in a bad state for every type out there without creating a type for it.

(b) is cumbersome because you're putting work on the user to catch this state and handle it properly.

So perhaps its simply a choice, (a) is you handling it and making it a "pull" function for the client, (b) is the client needs to handle it and you make it a "push" to the client.

So, I'm not sure if its really a "type" but its more of a "bad state" concept.

Zachary D. Shaw said...

So... I don't think it's always used for an exceptional state. It's often an excepted case. In the terms of a login it is excepted that you will fail login. In terms of file IO where suddenly there is no file system any longer, this is exceptional.

There's a big question of what is exceptional vs part of your domain, but returning null can either be because you have some exceptional state and are swallowing it (bad) or you're trying to signal something else to your client.

a) is okay sometimes, I think this depends on what you're doing. Returning an empty or null implementation of your object might be fine, it just depends on context.

there is C as well. Where there is no check (b) and there is no null object (a) where instead of directly returning an object you just get called back, with either the object or that there is a problem. Option C is what I am advocating (see the "Returning Null" post)

I'm not sure if it's really a "type" or not either (hence the BS tag on this post) but I think it behaves like a type, where null == foo == foo instanceof null and an NPE is a class cast. In terms of behavior, knowing that an object can be null is just the same as thinking that it could be some other object in disguise

Web Statistics