8
Jul
2008
 

A Case Against Dot Syntax

by Marcus Zarra

I was not born an Objective-C developer. I know that in some circles that is considered a mortal sin. Before learning Objective-C and Cocoa I had developed in a great number of languages dating back to the early 1980′s. I tell you this so that what you are about to read next is taken in the light that it was intended.

Take a look at the following lines of code:

- (void)doSomethingSpecial
{
	myVar.itsAttribute = 10;
	myOtherVar.itsAttribute = 20;
}

Now tell me, what is myVar and myOtherVar. Is it an object or a struct? Can’t tell from that piece of code can you. That is half of my argument against dot syntax in Objective-C. It makes the meaning of your code unclear. Objective-C is known for its self documenting nature. Dot Syntax removes that.

Next, lets take a look at another piece of example code:

-(BOOL)myCompliatedMethod
{
	MyObject *object = [[MyObject alloc] init];
	object.attribute1 = 10;
	object.attribute2 = 20;
	OtherObject *nextObject = [[OtherObject alloc] init];
	[nextObject doSomethingAmazingWith:object];
	if (nextObject.result > 10) {
		[object doSomethingElse];
		return NO;
	}
	return YES;
}

Yes, this is clearly contrived code. However, hopefully, its meaning is clear. dot syntax breaks up the flow of the code. Code should be elegant. It should be graceful and beautiful to look at. This is ugly, nasty code that you want to fold as fast as possible so that you can stop looking at it. The message passing lines are completely at odds with the dot syntax lines. The difference is striking and distracting.

When we write code, we care about its formatting. We care that the code is properly indented and that the indentation is consistent. We should care equally as much about its consistency of style and design. Switching from message passing over to dot syntax and back is not consistent.

Now lets compare this against keeping the entire method within message passing:

-(BOOL)myCompliatedMethod
{
	MyObject *object = [[MyObject alloc] init];
	[object setAttribute1:10];
	[object setAttribute2:20];
	OtherObject *nextObject = [[OtherObject alloc] init];
	[nextObject doSomethingAmazingWith:object];
	if ([nextObject result] > 10) {
		[object doSomethingElse];
		return NO;
	}
	return YES;
}

There is now a consistency of form and style. The code flows more smoothly and is not as jarring.

Dispelling some myths

I want to dispel a couple of myths about dot syntax in Objective-C while I am on the subject.

  1. Dot syntax is not faster than message passing. It is syntactic sugar that is translated to normal message passing.
  2. Using dot syntax to set an attribute to nil is not a more efficient way to release an object. It is less lines of code but just as heavy as [object setAttribute:nil].
  3. Using dot syntax will not directly access the attribute on an object. While this is true in some languages, the actual call path for an Objective-C dot syntax accessor is:1
    • Resolve the accessor selector from the call
    • The accessor method, if that does not exist
    • The attribute itself, if that does not exist
    • The unknownValueForKey: method is called last.

Why did Apple add it?

I have my own theories on why this nastiness was added to the language. It could be due to all of the windows hacks coming over to OS X and a desire to make them feel a little more comfortable.

It could be that a battle rages between the Carbon developer and the Cocoa developers and this was a concession to the Carbon developers since Carbon is going away.

It could be that while adding properties (a most useful feature of Objective-C 2.0), the developers decided “why not” and threw them in there.

We may never know the real reason behind adding these to the language. However it is clear that they are here to stay and I mourn their coming. They are a confusing addition to the language and cause developers new to our platform to bring bad habits with them.

Unfortunately they have made their way into Apple’s sample code as well as the language. This is truly unfortunate. As I have mentioned in the past, the sample code that Apple provides is not the best case solution; however many developers will think so. By adding dot syntax into these examples, it exacerbates the problem. New/young developers coming to the platform will see this dot syntax as the “right way” to do things and they will become a maintenance nightmare.

Maintainability

The last thoughts on this subject are with regard to maintainability. We often forget about this aspect when we are working by ourselves. However, maintainability is not just a factor when we hand off code to another developer, it is also a factor when we have to come back to our own code 6 months from now! I don’t know about you but when I look at code I wrote a year ago all I can think is: “That moron! What the HELL was he thinking!”

Since dot syntax is not as clear with regard to intent as message passing is, then we should avoid it for maintainability as well. Who wants to have to constant flip back to the header file while reviewing a piece of code to remember if we are talking to an object or a struct. Keep the intention clear, keep the code clear, and maintainability will follow.

Conclusion

In the end, it is a matter of preference. I hope that these topics have helped to show the negative effects of using dot syntax in Objective-C. It is purely syntactic sugar and adds nothing to the language. However, there are so many cons that I cannot suggest that anyone use it in any situation.


  1. Thanks go to Chris Hanson for setting me straight on this precise order.

Comments

jbaldwin says:

As a relative newcomer to Objective-C, I have found the dot syntax somewhat confusing initially. This is because I’m accustomed to it being THE way to access everything, I find that once I start using it, I go crazy and try to use it where I shouldn’t.

Then I curse the language, the developer tools, the platform, Steve Jobs, this blog, and then walk away waggling my head smugly knowing I’m superior for having used anything else before this.

Devon says:

What about [myViewController.view addSubView:newView]; bwahaha
Sometimes I use the above syntax which is pretty clear, at least to me.
I actually like the message passing syntax now over the typical dot syntax.
I guess the dot syntax goes hand in hand with the properties as Apple seems to prefer to use it for accessing properties rather than [[myViewController view] addSubView:newView]. Multiple nested brackets can sometimes get hard to read.

atomicbird says:

Maybe I appreciate the dot syntax solely because I so rarely use plain structs these days. After a few years with Cocoa and object oriented thinking, I find that whenever I might have used a struct in the past that I also imagine some behavior that has to go along with the data. So I end up writing a class, however small, rather than a struct. The upshot is that the struct/class confusion never comes up when I’m using dot syntax, because I’m never using a struct. Without the possibility of this confusion I find the dot syntax to be more convenient, and I confess I’ve become addicted to it.

I seem to recall that when the syntax was first announced at WWDC (2007? 2006?) it was explicitly described as helping to make the language more accessible to people familiar with Python and Ruby. They’re probably in a similar boat, where they’d (correctly, in their case) just assume it was an object anyway and therefore not suffer any confusion.

But regarding those “myths”: Does anyone think those are true? I don’t think I’ve encountered those mistaken ideas before. Maybe I just “get” how they work because, since I knew Objective C already, I paid close attention to what exactly was implied by the new syntax and therefore avoided potholes that might trap the unwary.

schwa says:

So now that the speed arguments have been demolished (@chanson FTW) your entire argument against dot notation boils down to the fact that it is “just” syntactic sugar and therefore is hard to maintain and/or understand?

Well yeah it is syntactic sugar. But I for one am a big fan of syntactic sugar. It makes my work day (*) more pleasant. I don’t have to care about balancing the braces in:

[[[someObject someProperty] someOtherProperty] setYetAnotherProperty:42];

I can just very explicitly:

someObject.someProperty.someOtherProperty.yetAnotherProperty = 42;

If part of that property path changes I can merely add or remove atoms as needed. No balancing braces. I hate balancing braces. Don’t you?

And as for maintainability, I really don’t think either is necessarily more or less maintainable than another. When I think software maintenance I think about software complexity, not details of syntax. In fact I’d say that most if not all syntactic sugar by its very definition reduces complexity and therefore might contribute to ease of maintenance?

Also don’t forget that the foo/setFoo convention is just that, a convention. And a convention often ignored, for example -[NSSet setByAddingObject:]. Oops!

People tend to poo over syntactic sugar. If I had a penny for every time I heard the phrase “oh that’s just syntactic sugar” I’d be knee deep in hookers and blow right now. Honest. But a lot of language features we take for granted are just syntactic sugars. Hell the C array syntax is a classic example of syntax sugar. Hell isn’t Objective-C just one big syntactical sugar on top of objc_msgSend? Amiright?

So yeah, there are issues with Objective-C’s dot notation. Namely the handling of arrays. MyObject.frame.origin.x just can’t be done and you’re struct with [MyObject frame].origin.x (see what I did there?) and need to be careful when assigning to struct members. That’s a flaw. I grant you. But in practice it is one that is easily understand and avoided after you use dot notation for a while.

But the nice thing is, you don’t have to use it. The language is happy with both styles. Use whatever makes that inner geek happy. I’ll be using dot notation because it makes mine happy.

schwa says:

Oops. I meant the “handling of structs” not of arrays. My bad.

Marcus Zarra says:

atomicbird,

Those are all myths that I have heard recently within the last couple of months!

Marcus Zarra says:

Devon,

That makes the eyes bleed!

schwa says:

Oddly enough I’ve not heard the myths either. I’m not really anyone really needed these non-myths dispelling.

I do have to say. I really like halving the line count of my dealloc method by using self.foo = NULL; so much easier to scan.

Marcus Zarra says:

Schwa,

Your probably not abrasive enough for people to throw strawman arguments at you :)

Either that or I am hanging out in the wrong places.

Could be both…

I fail to see how dot-syntax is anything but easier to read and write. You need a push-down automaton to balance []‘s, but you only need an FSM to get the dot’s in dot-syntax right. Dot-syntax is less to write, and I expect it is measurably faster to read.

I don’t understand why knowing if something is a struct or an object is necessary. If every struct in Cocoa became a proper object overnight, and via dot-syntax all code that used them still worked… what would be the loss? (From a programmer’s perspective; not judging by the performance of the machine). I have never defined a struct in any Obj-C code I have written. I just don’t see what they add over objects, and they don’t play nice with Cocoa containers, so I avoid them. What I’m trying to say is, “yes, dot-syntax hides a bit of type information .. so what? I don’t see how that hides the *intent* of code.”

Chris Hanson says:

I still have to correct #3, unfortunately.

Say you have a property like this:

@property(copy) NSString *message;

And you use it like this:

self.message = @”Hello, world!”;

That use of the “message” property will compile exactly the same as this Objective-C 1.0 code:

[self setMessage:@"Hello, world!"];

There is NO difference between dot syntax and bracket syntax in terms of the generated code. Therefore, there is NO difference in how property use behaves.

I’m not sure why people have been assuming that dot syntax behaves like key-value coding, but it doesn’t. It’s just a different way of sending a message. There aren’t even objc_setProperty or objc_getProperty calls that dot syntax compiles to – dot syntax actually compiles to invocations of objc_msgSend, just as bracket syntax does.

davidarve says:

Doesn’t the dot syntax come quite natural from old objective-c’s key paths: NSString *mn = [selectedPerson valueForKeyPath:@"spouse.scooter.modelName"]; (Hillegass Cocoa Programming for Mac OS X, pp.134 2:nd edition)? Even so, I do sort of agree that it doesn’t really look as nice.

joconor says:

Schwa,

Your example:

someObject.someProperty.someOtherProperty.yetAnotherProperty = 42;

is EXACTLY why I agree with the cimgf article that the dot syntax is not a good thing. The example is a pretty bad violation of the ‘Law of Demeter’ (see http://c2.com/cgi/wiki?LawOfDemeter). The fact that the bracket syntax version of your example looks ugly is a clue to anyone reading the code that something is wrong. The dot syntax goes some way to masking this. The ugliness of the nested bracket case is what some refer to as a ‘Code Smell’ (see http://c2.com/xp/CodeSmell.html).

If you are routinely nesting the sending of messages to the results of messages as deeply as in your example, you may want to reexamine your coding style, as this ends up creating dangerously brittle code.

countach says:

I think they did it to mirror key path syntax, which makes some sense.

I don’t agree that it makes code brittle. It could, but it all depends on the circumstance.

Since Objective-c is a hack on a hack on a hack, its hard to get too excited about ruining the purity of the language. I think they should redesign the language from the ground up with the same semantics (for backwards compatibility) but a whole new syntax, abandoning the legacy cruft of C. Whether it becomes even more like Smalltalk, or more like Java wouldn’t matter.

[...] This blog post by Marcus Zarra made me happy. Now I know that I’m not the only person who dislikes the dot notation which has been introduced in Objective-C 2.0. The “Properties” feature is great, since it takes a lot of work writing accessor methods away from the developer. But accessing your object members sing the dot syntax makes your code ugly and cofusing. [...]

oomu says:

I totally agree with Marcus Zarra. It was a not necessary addition to the language. It adds two way to do things and it’s just plain confusing.

the very nice aspect of Objective-C was its readability . Maybe you want convenience, but I just see useless addition and more and more lost of objective-C.

@countach

on the contrary! Objective-c is an elegant extension to C. and C compatibility is still a great asset. You can link to whatever c library you need. Don’t ask more changes which bring nothings to improve applications.

and C is not a “legacy cruft”, you can see the runtime allow objective C to be completely dynamical. I cannot fathom why “c” can bother you.

it’s a tool, and the important quality for a tool is to be easy to use.

themaccircle says:

Dot syntax is really only helpful to people who have years of HTML DOM and JavaScript experience under their belt. Not that the purpose and use is the same, but the syntax x.y that links y to x is very helpful for readability.

[...] be interested in reading more about views on Objective-C 2.0 properties, here are two references: Marcus Zarra — A case against dot syntax Matt Gallagher — In defense of Objective-C 2.0 [...]

[...] you can use the dot syntax, I do not recommend it. Read this post for the reasons [...]