Objective-C has the best null handling

Objective-C has the best null handling of any object-oriented language. Here’s how it works:

  • If you try to call a member function on a nil pointer, it is treated as a no-op.
  • If the function returns a pointer, nil is substituted for the return value. If it returns a number, you get zero.

Since there are no pass-by-value semantics for objects in Obj-C, we don’t have to worry about functions that return entire objects by value. Bools are treated like ints, and zero is equivalent to false. Properties in Objective-C are implemented as functions and therefore adhere to the same rules.

You can still check to see if a pointer is nil before you use it, but this is unnecessary in a large percentage of cases. If all you’re trying to do is avoid calling a delegate function when no delegate was provided, or substitute false or zero for the return value of a function, you don’t have to write any extra code.

In every other language, working with nulls is more involved. C++ programs will crash if you derefernce a nil pointer. Java throws a runtime exception, and since the exception isn’t required to be handled, it effectively results in crashing many applications.

Modern languages like Swift and Kotlin are even worse: the languages force you to declare whether or not every variable is Optional (nullable), and if it can be null, you can’t use it without explicitly unwrapping it.

JavaSwiftObjective-C
if (delegate != null) {
delegate.someFunction();
}

if (customer != null)
isSubscribed = customer.isSubscribed();
else
isSubscribed = false;


if let delegate = delegate {
delegate.someFunction()
}

if let customer = customer {
isSubscribed = customer.isSubscribed()
}
else {
isSubscribed = false
}

[delegate someFunction];

isSubscribed = customer.isSubscribed;
Less code means less to maintain, less to go wrong.

Some would argue that substituting zero or nil is improper and could lead to unexpected errors later on. There’s some truth to this, but I think it describes a small minority of cases. Most of the time, having the program continue to work and produce some result better serves the user.

Swift-style Optionals produce the most code and in my opinion, the most confusing code: it’s not obvious why an expression like “let customer = customer” does anything useful. It’s an example of the defensive trend in programming. Rather than give good developers more powerful tools, the languages and IDEs focus on keeping bad programmers from making mistakes. Perhaps we’d be better off letting these programmers fail, and leaving the programming to the people who don’t need training wheels.