Wednesday, April 16, 2014

Tuples and NSError

Edge Cases episode 88:

Andrew Pontious talks with Wolf Rentzsch about the simplest of things, the tuple: what it is, how it is used in other languages (specifically Python), and how, in an alternate universe, it could bring some sanity to Cocoa error handling.

Tuples in Python are great, particularly because there’s syntax for unpacking (a.k.a. destructuring). It even works with nested structures.

They hypothesize that NSError was introduced in Mac OS X 10.4 with Core Data. My recollection is that it was added with Safari 1.0 and WebKit, which could be installed on Mac OS X 10.2 and was built into 10.2.7.

Although I would certainly welcome Objective-C support for tuples and language-level support for errors, I’m not sure that it makes sense to implement the latter using the former.

One of the few virtues of using (NSError **) parameters is that you can pass in NULL if you only care about success/failure, not the reason for the failure. I’ve found that this is sometimes very useful for performance reasons. There’s a tension between putting lots of useful information in the error object and creating the error object quickly. NULL lets you have your cake an eat it, too. If you know that you will be making many related calls that could fail, you can do this without creating any NSError objects. Then you can generate one higher level NSError to represent the whole operation, and possibly retry one of the lower level calls without NULL to get a suitable underlying error object. This level of control would not be possible if methods always returned a tuple with a full error object.

Secondly, tuples would require more lines of code because if you want to save the error you can’t use the return value in an if statement. Instead of:

if ([self fooAndReturnError:&error])

you would write something like:

BOOL ok, NSError *error = [self foo];
if (ok)

You can see what this is like by calling Cocoa APIs using PyObjC.

1 Comment RSS · Twitter

It would be interesting to see if you could make NSError construction lazy such that if you pass a NULL parameter, all of the “if error != NULL …” stuff could be completely elided. Not in the current Objective-C of course, but hopefully one day we’ll end up with a runtime more aware of what’s going on.

Leave a Comment