On Wed, Feb 16, 2011 at 13:22, David Chisnall <address@hidden>
One of the core points in the Objective-C philosophy is that there should be a direct correspondence between syntax and semantics. New semantics should always involve new syntax, old syntax should not be used for new semantics. This is very important because it makes it easy to understand what a piece of code is doing, without having to reference lots of other pieces of code.
A good philosophy. Considering that, it might have been wise for Apple to pick another syntax, and I tend to agree with you, Richard and other developers in favor of dropping the dot syntax.
However, for the sake of discussion (and to defend my own decision to keep on using dot syntax :-) I will provide a few more arguments.
Contrast this with C++, for example in this line:
In C++, this can be:
- A C function call.
- A static C++ member function (semantically equivalent to a C function)
- A non-virtual C++ member function, with this as a hidden parameter
- A virtual C++ member function, dynamically looked up depending on the type of the callee
In contrast, this line in Objective-C, the equivalents are:
All of these are distinguishable without looking at any other code. You can read this and immediately understand the semantics. This is very important for readability.
While much cleaner than C++, Objective-C 1.0 does have a similar example:
[NSString stringWithFormat:@"x %d", 5];
ObjC syntax does not differentiate between calls to + and - methods. someString might also be a class. You have to look up if it is or if it isn't an instance as opposed to a class method.
Contrast this now with the dot syntax:
This can be:
- A structure member reference
Just as you have to look up whether a symbol is a class or an instance, here you have to look up if it's a struct or an object.
- An Objective-C message send calling a synthesised method that access a property
- An Objective-C message send that calls a user-written method that may have complex side effects
Solution is the very discussion we're having, and spreading information to warn developers about possible consequences. Aside from dropping dot-syntax, another possible suggestion could be that user-provided methods should be carefully written, weighing whether or not to add complex behavior.
This can be made much worse by things like:
This is equivalent to:
[a setFoo: [a foo]+1];
I disagree that this is a downside :-)
But the syntax completely hides the fact that you're doing two method calls. It lets you write code that is very complex, but with this complexity completely hidden in the source. This is particularly dangerous with atomic properties, because you'd intuitively assume that ++ on an atomic property is an atomic operation, but it isn't.
I really think that this is a minor issue and that extra brackets in such short statements do not contribute to readability of code. Most often, one will not write code that will depend on atomicity of the operation. I don't write multithreading code because I don't want to worry about atomicity, locking, race conditions, et cetera.
I do not argue that everyone must use the dot-syntax, I just don't see that it is such a major problem. It is a nice convenience that can be quite useful to experienced developers. I do see the dangers of dot-syntax in the hands of beginners; I've worked enough with kids and grownups to see what kind of troubles they have, and indeed it could be an issue.
But whenever I use dot-syntax, I am very conscious of what I'm doing; I am conscious that I am making a method call (or two!) and it's not an issue. And, after all, large majority of my properties are synthesized. What harm in using that?
Finally, let me restate that I do see what bothers you, and I do agree with your stance a bit more. I do not, however, consider that we should call the dot-syntax deprecated, or avoid it when writing applications.