I disagree most emphatically. The whole point of dot notation is that, when combined with properties, it’s not just an alternative syntax for invoking methods. In fact, if that’s how you think about dot syntax, STOP. That’s not what it’s for at all.

What dot syntax and property declarations are for is separating object state from object behavior. Classical OOP only really defines objects as only exposing behavior but the past 30+ years have demonstrated rather aptly that objects consist of both. C# was actually pioneering in this; its concept of properties is rather similar to what the combination of property declarations and dot syntax enable in Objective-C.

To write idiomatic Objective-C 2.0 you should use @property to declare properties, and use dot syntax to access them. Period. Doing otherwise is a bad idea because it will create code that isn’t intention-revealing to other experienced Objective-C 2.0 developers. Teaching students to do otherwise is doing them a disservice, because you’re directly contradicting those responsible for the language and its evolution.

In short, Objective-C 2.0 has properties and dot notation as another way of expressing intent in your code. Use them for that, don’t refuse to use them just because they weren’t in earlier versions of the language, or because they require teaching another concept.

{ 17 } Comments

What dot syntax and property declarations are for is separating object state from object behaviour

So what? Why is that a good thing?

I don’t like dot notation because I think it makes code less readable (partly because they look like structures). Readability, to me, is a higher law than this separating object state from object behaviour law (that we’ve done fine without for so long).

If I might make another related point: I think it’s unfortunately that the choice of forms now exists; I’d rather that we were forced to use one way or the other as that would, to some extent, prevent these arguments (which are a waste of time) and force consistency. Of course I realise that there’s the small matter of backwards compatibility to take into account.

Great response Chris.
Properties are a phenomenal addition to the language, and the dot syntax is a great way of differentiating between accessing properties and calling methods. The readability of Objective-C is enhanced by this syntax, and I think most think so. You clarify it all very well here.
Thanks.

The proliferation of -setWhatever:animated: messages in Cocoa touch gives the lie to “it’s just state”. Clearly, what you are doing is sending a message to the object to ask it to perform an action, namely to change some internal state; and clearly there is more than one way to do this, namely with or without animation.

Indirect access to state (encapsulation) is one of the main advantages of object-oriented programming. Dot-syntax seeks to pretend that the access is more direct than it really is. It’s not just confusing because of the operator overloading, it actually engenders bad programming practice.

I love the argument from authority that you use to end this post. “We made it, so do it the way we want” is not actually a good argument to make. I hope you realize that.

As for the rest, I don’t think that separating state and behavior is a good thing. In fact, I always thought that one of the fundamental tenets of object-oriented design was that an object’s state should never be exposed. All you should ever expose to the outside world is behavior. Setting a name? That’s behavior. Getting that name? Behavior. That the name is ultimately object state is an implementation detail.

By encouraging programmers to expose these implementation details as explicitly declared state, I think that the whole @property business is broken, and dot syntax goes along with that.

In any case, I really hope that we can have this discussion without the completely pointless “it’s our language, so you must agree with us” stuff.

When talking about platform technologies, argument from authority isn’t automatically invalid. You don’t have to agree with how Apple is doing things, but if you insist on doing them differently, you will find yourself fighting the framework, not taking advantage of productivity enhancements, having to adjust template code to conform to your own coding style, and so on.

An example of the productivity enhancements properties and dot syntax can give you: Because dot syntax (intentionally) requires more compile-time type information, Xcode can also offer better code completion for it. Thus dot syntax doesn’t have the “800 methods added in categories on NSObject” problem that bracket syntax does.

Argument from authority is always automatically invalid. Doesn’t matter what it is or who it is. The reasons you listed are actual reasons. THEY are the arguments to make to defend this idea. But “because we say so” is, as always, a bad reason. If Apple makes a bad recommendation about a “platform technology”, then it remains a bad recommendation despite the fact that it comes from Apple. Conversely, if Apple makes a good recommendation, then that recommendation’s worth stands apart from who makes it.

Mike, I agree with you wholeheartedly about the main issue, but Chris said “Teaching students to do otherwise is doing them a disservice, because you’re directly contradicting those responsible for the language and its evolution”, for which I think “You don’t have to agree with how Apple is doing things, but if you insist on doing them differently, you will find yourself fighting the framework” is a more natural interpretation than “it’s our language, so you must agree with us”. In other words, you’re right that argument from authority is invalid, but I don’t think Chris really made one.

Chris, I would still be interested in hearing your response to the real substance of Mike’s and my comments here: that exposing state without behaviour is not desirable.

I was also interested to hear bbum’s take (http://twitter.com/bbum/status/3209032840), that state and behaviour should be kept entirely separate. If only the language enforced that! (i.e., dot-notation was not syntactic sugar, but a separate mechanism altogether) I do see the value in an object having synthesized memory-managed accessors to its own ivars, though to my mind it’s not worth spoiling ObjC1’s syntactic purity for.

I really don’t have a dog in this fight. I’m a VB.NET programmer who is learning Obj-C specifically to port/create some software for the iPhone. I’ve been doing this for less than a month.

As I’m reading through HeadFirst iPhone development (GREAT! book, BTW), I come to page 110.

The topic at hand is memory management, which is still a little fuzzy for me on this platform. .NET has garbage collection and what I consider to be fairly straightforward memory management techniques.

Anyway, page 110 is a Q&A page, and one of the questions is:

“Do I have to retain things I want to set on my properties?”

The answer in the first paragraph is basically “no.” Then, they add this paragraph:

“One more quick note: the automatic retain/release ability of properties only works if you use the “.” notation. If you explicitly modify the field that backs the property, there’s nothing the property can do about it and can’t retain/release properly.”

Again, this is a bit of a fuzzy area for me, but let me see if I could break this:

(in @interface section of .h file):

IBOutlet UITextField *notesField;

(after @interface section of .h file):

@property (nonatomic, retain) UITextField* notesField;

(in .m file):

@synthesize notesField;

Now, what happens here:

[notesField setText:@”This is my new text.”];
notesField.text = nil;

Am I missing their point, or does the first line above not increment the retain count and the second line decrements it (so retain count would == 0), so my object could be cleaned up at any time?

Is this a valid reason to use dot-notation in code?

Thanks for helping me!

(BTW, I also post this on the Big Nerd Ranch blog relating to this subject.)

Is there evidence that developers have difficulty distinguishing state from behavior? If so, what is it? What problems does it cause? Does it result in a significant fraction of bugs? What fraction, what kind of bugs, and how difficult are they to find and fix?

Is there evidence that this particular syntactic sugar reduces this difficulty? If so, what is it?

I haven’t seen any evidence that there is an actual problem to be solved here. For now, we’ve just made it harder to read Obj-C code, since now when I see foo.bar, it might be a struct field access, or it might be a method call. I can’t tell without looking at the static type of foo.

So, a lot of people like to get worked up on this subject. I hate to contribute to that too much. I use properties and dot notation, just out of good practice and citizenship. And as a practical matter when dealing with Interface Builder, etc. However there are some downsides. I have some sympathy for the question whether the problem was real/justified enough for the confusion. Especially for newcomers.

The whole property and dot notation thing is unfortunately a bit more wrapped up then just a theoretical aspect of state vs behavior. They are overloaded, and I suspect used much more as implementation conveniences than to develop better object interfaces. The prime example is in memory management. See the comment by Mike above. Hey, it sure is handy to have a retain attribute on a property and not have to worry about the release until you need to (dealloc). But this habit, at least for those new to the ObjC world, can lead to inadvertent memory leaking, through a retain attribute property as the target of an alloc/init. And if someone is already trying to learn the semantics of GC vs retain/release and ownership via alloc/init vs the need to grab ownership through factory methods, etc it gets a bit confusing I suspect. Add in some more confusion when someone forgets to use self.foobar syntax in an implementation and just uses foobar, ie suddenly referencing the ivar not the property. It is easy to see how some folks might get a bit frustrated, certainly they probably waste time which wasn’t necessary. None of these are huge issues on their own, but it just seems a bit messy. I have personally thrashed about a bit between ivars and properties before settling onto a good pattern, use an alias for the property and an underscore decoration on the ivar.

An even more subtle case, and another example of overloading the state argument, is the fact the KVO can be triggered by a property. Yes, it can be triggered by any keypath implementation (ie a standard message interface). But again there is a bit of a candy store appeal, a UI client wants to know when some data is ready, it observes a property and viola. While the synthesis and behind the work implementation is handy, it can lead to some surprises, which again can be confusing to the newcomer. If in an implementation you use self.foobar = ‘value’ to change some aspect of an objects state, you can be creating notification calls as a side effect. You might not remember / know you are creating these notifications (that is the whole point of the pattern!). But if your object isn’t consistent yet, ie your implementation method isn’t done doing all it’s work, your clients are going to get some potentially funny results if they query other data on the observed object. Again, not a huge issue, perhaps most times the convenience outweighs doing things yourself. But at least in a programmer implemented model, or one that was more explicit about the consequences or allowed for deferring notification until ready, you might be more aware of ensuring all work was complete before issuing any notifications.

Convenient yes, but certainly, more is going on than just “state”.

The virtual ivar concept is perhaps a help in all this, as is the GC world of the Mac (I suppose anyway). But my guess is most newcomers are coming to the iPhone. And practically speaking you can’t use these features (okay you could use virtual ivars but not in the simulator, but that is truly a pain in the ass).

I’d be more willing to use dot syntax if it was restricted to @property accessors so that a class author could clearly state which methods are for use in dot syntax and which are computational methods. You’re left wondering if it’s okay to be calling “.uppercaseString” or “.anyObject.” Unfortunately, trying to be a good citizen by using only brackets for computational methods can lead to lines of code with both dots AND brackets in them. These gray areas put me off of dot syntax for now.

It would be nice if dot syntax was restricted to @property accessors. Even better would be if dot syntax was expanded to include key-path functions like @count, @sum, and included [ ] indexed array access. If that happened, I’d be all in for using it as the primary way to access an object’s properties.

Since my last post, I’ve reconsidered my position and now use dot syntax. I still think my previous concerns are valid, but I can’t argue against the practical advantage of the more compact syntax, particularly when setting values.

Seems like my biggest issue now is AppKit’s older method naming scheme; e.g., methods like -setFrame:animate: that present themselves as setters based on their naming scheme but don’t fit in with the dot syntax paradigm because they take additional parameters.

Still think it’d be neat to have key-path functions like @count and @sum, which could call -valueForKeyPath: behind the scenes using the respective functions.

Post a Comment

Your email is never published nor shared. Required fields are marked *