Design Element
Comment on "CocoaHeads: Objective-C 2.0"
by Nicko — Sep 23
I'd rather see that form deprecated for use with Object pointers and attempts to use it will just cause the compiler to warn objClass may not respond to '__add__:' or something of that ilk.

One of my bugaboos (Woohoo! Bugaboos is considered a word!) about C++ is that it's not a perfect superset of C, while Obj-C is. In other words, any C program will compile in Obj-C, while it's possible to make a C program that either won't compile with C++, or will compile differently. This is my major sticking point. As soon as you have to use "Extern C" or similar, you no longer have an upgrade. You have a completely different language.

I'm not sure I agree with your completely different language assertion but irrespective of that, we don't need to worry in this case. Due to the way that ObjC works, by the time the compiler has to worry about what foo + bar means it already knows the type of "foo" (and "bar", see below) and it knows if foo is a base type (behave normally), a pointer (perform pointer addition), a structure (throw an error) or, since this is ObjC, an object reference. Thus correct pure C code would not need to have its behaviour modified in any way.

But I could see a use for something like: endTime = [startTime + delay];

I can see that working in some ways, and it helps in dealing with questions about operator precedence between different classes, but I see a couple of big problems. Firstly, you're heading towards context-sensitive grammars, which are bad in a number of ways. Secondly, unless you deprecate pointer addition on object references you still have confusion over what [startTime + offset + delay] means.

With an int, the compiler would swap in -[addIntValue:]. With a long, the compiler would swap in -[addLongValue:]. And NSObject's -[addLongValue:] would call -[addIntValue:], etc. With an object, it'd be -[addObjectValue:], and so forth. Yes, this wouldn't allow for overloading based on which id. But part of Obj-C's foundations is that it's not the kind of object that matters as much as what it can do; check at runtime for [respondsToSelector:].

The exact behaviour for this was something I had been thinking about for a while. For base types as the right-hand operand I'm inclined to convert it into an NSNumber (and an NSValue for structs) and pass it as an object, that way the programmer never has to implement more than one call if she does not want to. Conversely, since ObjC does not have multiple inheritance, since we know the class of the operand at compile time and since we know the messages that the recipient responds to at compile time, I think that it would make sense to look at all the messages of the form __add__XXX: to find the XXX that is furthest down the class ancestry for the right hand operand. If there is no match then we pass it to the base __add__: message, which may or may not be implemented and will be warned about if it is not. This would have both valuable static type checking benefits (which would avoid some of the classes error one gets in languages like Python) and would have profound performance improvements, since the ObjC runtime can ensure that the conversion from SEL to IMP only has to happen once and get cached rather than having a full dynamic lookup every time.
Back to "CocoaHeads: Objective-C 2.0"
Design Element

Copyright © Scott Stevenson 2004-2015