Dot notation for messaging isn’t just an Objective-C code smell. It’s evil, I tell you!
Update: I recently changed my mind! See my post In Which I Embrace Dot Notation…
This post is part of the Code Smells in Objective-C series.
…OK, so that’s hyperbole. I do manage to coexist with dot notation in projects that have it. But I won’t write it myself. Here are 3 reasons I avoid dot notation in my code:
1. Dot notation confuses objects with structs
Tell me, what does the following code do?
foo.bar = 10;
In C, it’s clear what this code is doing:
foo is either a struct or a union. It’s assigning 10 to
Underneath the hood, the compiler writes code to calculate a memory offset from
foo, then write the value 10 into the storage at the calculated address. Very fast & lightweight.
Objective-C is a strict superset of C, so all of this could apply to Objective-C code as well. Or not. …You can’t tell, can you?
2. Dot notation obscures messaging
Because dot notation is syntactic sugar for messaging, you could write code like this:
NSMutableArray *a = NSMutableArray.array;
Of course, that’s beyond evil. But why? “Because
array isn’t a property, it’s a method.” Oh, so the decision to use brackets or dots depends on whether the thing is a property? But it’s messaging either way! Why add a second messaging syntax at all?
The addition of dot notation to Objective-C smacks of someone at Apple saying, “Java is such a popular language. Our square brackets freak out Java programmers. Let’s replace brackets with dots; it’ll look just like Java which will increase adoption of Objective-C.”
But before getting into Objective-C, I wasn’t a Java developer. I was a C++ developer. And in C++ (which is almost a superset of C),
foo.bar = 10;
this is member access.
foo could be a class, a struct, or a union, but this is member access regardless.
But how does an object access its own members? In C++, you could write
this->qux = 10;
But it’s more common to omit the this-arrow and simply write
qux = 10;
qux is a member variable with class scope.
Now come over to Objective-C. In the evil new land of dot notation, you often see this:
self.qux = 10;
qux is a property. A typical Objective-C newbie mistake is to say, “Well, that self-dot is redundant,” and change it to this:
qux = 10;
This compiles and runs without any problems. So what’s all the fuss?
The problem is that in the former case, we’re sending a message to the
qux method. In the latter case, we’re making a direct assignment to the
qux instance variable. These are two very different things! With scalars, it may not matter, but it makes a huge difference with objects, especially for writing correct memory management.
Now see what happens if you avoid dot notation:
There is no ambiguity. This is clearly a message.
3. Dot notation encourages Law of Demeter violations
How often do you see code like this? How often do you write it?
foo.bar.baz.qux = 10;
What’s wrong with that? Let me rewrite it without the dots, to make the messaging explicit:
[[[foo bar] baz] setQux:10];
People who complain that square bracket notation “looks weird” point to examples like this, to show how unreadable it is.
The problem is, it’s unreadable for a reason: it’s violating the Law of Demeter.
If you’re not familiar with the Law of Demeter, it’s about polluting the clear boundaries between objects by letting them become overly familiar with each other. Here’s a quick way to remember it: You can pick your friends. You can pick your nose. But you can’t pick your friend’s nose.
All those lumped-up brackets are a clue that you may be poking around where you don’t belong (in your friend’s nose). It’s a code smell that responsibilities may be misplaced. But now, dot notation makes it possible to keep using that same stinky violation, but look good doing it!
Since almost all Objective-C code I see uses dot notation, I realize I’m swimming against the current here. Well, unless you count a couple of heavy-hitters, like Big Nerd Ranch and Cocoa Is My Girlfriend.
Question: Agree? Disagree? What do you think? Leave a comment below.
But also see my follow-up post In Which I Embrace Dot Notation…
Did you find this useful? Subscribe today to get regular posts on clean iOS code.