views:

87

answers:

3

In Objective-C, I usually see methods that return a dynamically typed object defined as follows:

- (id)someMethod:(id)someParameter;

I know that I can do this, though, as well:

- someMethod:someParameter;

Interestingly, I see the latter convention in more core-level foundation classes, but everyone else seems to use the first. Since the Objective-C runtime infers that an untyped method or parameter will return id, why should I include it? Doesn't it break the flow of reading?

I would like not only to know that devs think about possible problems with using this convention, but also whether you guys think it is just plain weird?

+5  A: 

Since the language permits both forms, it's really a mater of style. Given that, Objective-C leans heavily on readability over terseness, and most devs would prefer the first (-(id)someMethod) becuase it makes explicit the return type.

Not directly relevant to your question, but id is not dynamically typed. It is a pointer to an Objective-C object. Since message dispatch is dynamic in Objective-C, id can often be treated like a dynamic type, but it's still actually a static type. In other words, Objective-C is dynamically bound but statically typed.

Barry Wark
Similarly, C functions default to returning int, but it's very bad C style to depend on this. In Objective-C this default return type is changed to id for methods, but it's still considered bad style to depend on that.
Chuck
+2  A: 

First, I believe it's the compiler that infers the type, not the runtime.

I believe the second convention comes from the deep-set object-oriented-ness of Objective-C. Most code is meant to be dealing with objects, and so the default return type and argument type is id. The convenience of this is that the compiler doesn't care if you declare the specific type of an object, as long as the methods you use on it exist somewhere.

The biggest potential problem would be sending messages to an object that it doesn't respond to, because you accidentally thought it was another type of object. This is a reason why you shouldn't leave off types, but instead use the most specific one possible.

I would say the second convention is only a good idea for code that's oriented towards flexibility using lots of dynamic features of the language and runtime, not the specific objects and classes that you'll run into most of the time when making applications. Using the first convention where appropriate improves readability and makes it harder to make mistakes. It's an issue of semantics — being as specific as possible with your types leaves out the possibility of misinterpretation and can help you write better code overall.

jtbandes
+1  A: 

A lot of NeXT-era code followed this convention of excluding the (id) for the return type, and most of that code carried over into OS X. I find it confusing when the code excludes the type, and saving 4-5 characters is pretty pointless nowadays anyway. My guess is that old habits die hard — my experience is that best practice is to always include the return type. It certainly makes things clearer for newcomers to the language and makes fewer assumptions.

Quinn Taylor