Dot Dot Dot

posted on

Emacs or Vim? Tabs or Spaces? Mac or PC? There are many arguments between developers. One of the biggest ones in the Objective-C community is over dot-syntax. It's the argument that just keeps going. I'm on the side that doesn't particularly like dot syntax, but people often misunderstand the reasoning behind this position. So I'm going to outline it here.

Overloading an operator

One of the big no-nos in Objective-C is overloading things. We don't overload methods, we use different names. We don't overload operators, we use different operators. Dot syntax is the one exception though. The binary . operator is used both for accessing structs AND accessing properties. For the most part this doesn't cause a problem, but some properties return/take structs. This means you get wonderful things like:

self.view.frame.size.width = 20;

This doesn't set the frame's width to 20 as you would expect from the code. So we have the same operator used in one line of code meaning (and allowing) for different things. This is bad.

This could easily have been solved by using a different operator. Maybe object•property or object~>property or object@property or one of many other possible combinations. It removes all ambiguity (and ambiguity is bad in syntax) and preseves the concept that overloading is to be avoided in Obj-C.

Strong Typing

Objective-C is weakly typed. This is because C is weakly typed. This means I can do things such as "if (object)" without having to convert it to a proper boolean expression. Objective-C also has a mix of static and dynamic typing. This allows for the compiler to catch most problems while providing the flexibility that dynamic typing allows when you need it.

Unfortunately dot syntax is strongly typed. It checks at compile time that an object's header says it implements a method. If you are using static typing then this isn't an issue. Unfortunately many classes use dynamic typing. Here is a common example:

NSArray *myArray = @[@"foo", @"bar", @"baz"];
NSLog(@"%lu", myArray[1].length);

That is a compiler error. Why? Because NSArray returns objects of type id. However, if we switch back to bracketed syntax:

NSArray *myArray = @[ @"foo", @"bar", @"baz" ];
NSLog(@"%lu", [myArray[1] length]);

That isn't an error because it is weakly typed. So it has a different behaviour.

object.foo != [object foo]

In most cases the above title is false, but it isn't always the case. Take the following code:

@property (readonly, getter=isComplete) BOOL complete;
- (void)complete;

==============

- (BOOL)isComplete {
	NSLog(@"isComplete");
	return YES;
}

- (void)complete {
	NSLog(@"complete");
}

That looks like pretty innocent code. But what if we try to access it, what will happen? Well lets use bracket syntax first:

[self complete];
[self isComplete];

==============

complete
isComplete

Makes sense. As dot syntax should map to methods this should work the same:

self.complete
self.isComplete

==============

isComplete
isComplete

Oh dear. It seems that dot syntax doesn't follow the same rules as bracket syntax. If we removed the -complete method then the dot syntax would still be valid, but the bracket syntax would throw a warning. Why? Because -complete doesn't exist.

Why Some Devs Dislike Dot Syntax

The problem isn't the idea of a simpler syntax for accessing properties. Every developer I know is in favour of that. The problem some developers have is with the implementation. It's painted by its proponents as a simpler syntax for accessing properties, but due to its implementation it should really be seen as a completely separate feature.

If they had used a non-overloaded operator and made it map exactly to how the bracket syntax works then there would be no complaints. Look at other features Apple has added to make life simpler. @property directly replaces code you would have written before. The new literals directly replace code you would have written before. Dot syntax doesn't. Dot syntax is like ARC. It works mostly the same as the old way, but with less typing. However it's not a direct replacement as it brings its own set of problems to deal with.

Depending on your viewpoint these may all be non-issues. But those of us who find these to be genuine issues are not some "old fashioned" programmers who are stuck in the past. Quite the opposite, we are often amongst the first to use any new API, developer tool or language feature. I love everything else about Objective-C, but this is the one thing I think is poorly designed. I have softened my stance a bit and found that I can cope with having to put in an otherwise unnecessary cast, so I now use dot syntax for getting values in my own code. I doubt I'll ever use it for setting them though, because I genuinely believe it leads to worse code.

You may disagree, but that's your choice that you've probably arrived at through reasoning over the past 5 years, the same way I (and many others who share the same view) arrived at mine.