views:

1083

answers:

14

In Objective-C 2.0 we got the "dot" notation for properties. I've seen various back and forths about the merits of dot notation vs. message notation. To keep the responses untainted I'm not going to respond either way in the question.

What is your thought about dot notation vs. message notation for property accessing?

Please try to keep it focused on Objective-C - my one bias I'll put forth is that Objective-C is Objective-C, so your preference that it be like Java or JavaScript aren't valid.

Valid commentary is to do with technical issues (operation ordering, cast precedence, performance, etc), clarity (structure vs. object nature, both pro and con!), succinctness, etc.

Note, I'm of the school of rigorous quality and readability in code having worked on huge projects where code convention and quality is paramount (the write once read a thousand times paradigm).

+3  A: 

I've mostly been raised in the Objective-C 2.0 age, and I prefer the dot notation. To me, it allows the simplification of code, instead of having extra brackets, I can just use a dot.

I also like the dot syntax because it makes me really feel like I'm accessing a property of the object, instead of just sending it a message (of course the dot-syntax really does translate into message sending, but for the sake of appearances, the dot feels different). Instead of "calling a getter" by the old syntax, it really feels like I'm directly getting something useful from the object.

Some of the debate around this is concerned with "But we already have dot-syntax, and it's for structs!". And that's true. But (and again, this is just psychological) it basically feels the same to me. Accessing a property of an object using dot-syntax feels the same as accessing a member of a struct, which is more or less the intended effect (in my opinion).

**Edit: As bbum pointed out, you can also use dot-syntax for calling any method on an object (I was unaware of this). So I will say my opinion on dot-syntax is only for dealing with properties of an object, not everyday message sending

jbrennan
+19  A: 

Do not use dot for behavior. Use dot to access or set attribute like stuff, typically attributes declared as properties.

x = foo.name; // good
foo.age = 42; // good

y = x.retain; // bad

k.release; // compiler should warn, but some don't. Oops.

v.lockFocusIfCanDraw; /// ooh... no. bad bad bad

For folks new to Objective-C, I would recommend not using the dot for anything but stuff declared as @property. Once you have a feel for the language, do what feels right.

For example, I find the following perfectly natural:

k = anArray.count;
for (NSView *v in myView.subviews) { ... };

You can expect that the clang static analyzer will grow the ability to allow you to check that the dot is being used only for certain patterns or not for certain other patterns.

bbum
Wow, I didn't even know you could use the dot syntax for anything other than properties. Colour me surprised! (But I agree, dot should only be used for properties)
jbrennan
@bbum: try to put four spaces before your code, so it gets marked up as code.
Martinho Fernandes
@Martinho Thank you.
bbum
Dot notation is used only for accessor methods. This mean that cal be used as alternative to [foo getBar], or [foo setBar: bar]; it cannot be used for a generic method.
kiamlaluno
That is incorrect. Dot notation is a straight forward synonym for an equivalent method call; nothing more, nothing less.
bbum
I wonder why dot notation was not restricted to @property-declared accessors. It seems like it would have allowed class authors to resolve gray areas over which methods should be allowed in dot notation, and it wouldn't feel so ambiguous whether or not to use methods like `.uppercaseString` if the class was allowed to express its intent and have it enforced by the compiler. Perhaps there's something I'm missing that requires the current implementation of dot notation.
Preston
It could have been limited to `@property` only but that would both require the consumer of an API to learn another boolean dimension of information and designers of API to quite likely drown in arguments over what should and should not be an `@property`. Note that Xcode prefers -- weights more heavily -- `@property` implied methods when completing code.... It is encouraged, but not enforced.
bbum
+10  A: 

Let me start off by saying that I started programming in Visual/Real Basic, then moved on to Java, so I'm fairly used to dot syntax. However, when I finally moved to Objective-C and got used to brackets, then saw the introduction of Objective-C 2.0 and its dot syntax, I realized that I really don't like it. (for other languages it's fine, because that's how they roll).

I have three main beefs with dot syntax in Objective-C:

Beef #1: It makes it unclear why you might be getting errors. For example, if I have the line:

something.frame.origin.x = 42;

Then I'll get a compiler error, because something is an object, and you can't use structs of an object as the lvalue of an expression. However, if I have:

something.frame.origin.x = 42;

Then this compiles just fine, because something is a struct itself that has an NSRect member, and I can use it as an lvalue.

If I were adopting this code, I would need to spend some time trying to figure out what something is. Is it a struct? Is it an object? However, when we use the bracket syntax, it's much clearer:

[something setFrame:newFrame];

In this case, there is absolutely no ambiguity if something is an object or not. The introduction of ambiguity is my beef #1.

Beef #2: In C, dot syntax is used to access members of structs, not call methods. Programmers can override the setFoo: and foo methods of an objects, yet still access them via something.foo. In my mind, when I see expressions using dot syntax, I'm expecting them to be a simple assignation into an ivar. This is not always the case. Consider a controller object that mediates an array and a tableview. If I call myController.contentArray = newArray;, I would expect it to be replacing the old array with the new array. However, the original programmer might have overridden setContentArray: to not only set the array, but also reload the tableview. From the line, there's no indication of that behavior. If I were to see [myController setContentArray:newArray];, then I would think "Aha, a method. I need to go see the definition of this method just to make sure I know what it's doing."

So I think my summary of Beef #2 is that you can override the meaning of dot syntax with custom code.

Beef #3: I think it looks bad. As an Objective-C programmer, I'm totally used to bracket syntax, so to be reading along and see lines and lines of beautiful brackets and then to be suddenly broken with foo.name = newName; foo.size = newSize; etc is a bit distracting to me. I realize that some things require dot syntax (C structs), but that's the only time I use them.

Of course, if you're writing code for yourself, then use whatever you're comfortable with. But if you're writing code that you're planning on open sourcing, or you're writing something you don't expect to maintain forever, then I would strong encourage using bracket syntax. This is, of course, just my opinion.

Recent blog post against dot syntax: http://weblog.bignerdranch.com/?p=83

Rebuttal to above post: http://eschatologist.net/blog/?p=226 (with original article in favor of dot syntax: http://eschatologist.net/blog/?p=160)

Dave DeLong
Beef #1 seems a little specious to me. I don't see how that's a concern any more than you might try sending a message to a struct and then have to figure out that the variable is actually a struct. Do you actually see a lot of people who understand how it works getting confused by this in practice? This seems like the sort of thing that you'd mess up once, learn about the lvalue thing, and then do it right in the future — just like, say, not trying to treat NSNumbers like ints.
Chuck
@Chuck it is somewhat of an edge case, but I do quite a bit of contract development, which involves inheriting projects and having to work with them. *Usually* `something` is an object, but I've come across a couple places where the original authors have created structs (for speed, lower memory usage, etc), and I have to spend a good couple minutes trying to figure out why the code doesn't compile.
Dave DeLong
+2  A: 

I much prefer the messaging syntax... but just because that is what I learned. Considering a lot of my classes and what not are in Objective-C 1.0 style, I wouldn't want to mix them. I have no real reason besides "what I'm used to" for not using the dot syntax... EXCEPT for this, this drives me INSANE

[myInstance.methodThatReturnsAnObject sendAMessageToIt]

I don't know why, but it really infuriates me, for no good reason. I just think that doing

[[myInstance methodThatReturnsAnObject] sendAMessageToIt]

is more readable. But to each his own!

micmoo
I do this from time to time, but only if I'm accessing a property. For example: `[self.title lowercaseString]` or something. But I can see stylistically why it's bothersome to mix and match syntax. The only reason I do it is to keep straight what's a property and what is a method that returns an object (I know properties are really just that, but you hopefully get what I mean).
jbrennan
+8  A: 

I'm a new Cocoa/Objective-C developer, and my take on it is this:

I stick to the messaging notation, even though I started with Obj-C 2.0, and even though the dot notation is more familiar feeling (Java is my first language.) My reason for this is pretty simple: I still don't understand exactly why they added the dot notation to the language. To me it seems like an unnecessary, "impure" addition. Although if anyone can explain how it benefits the language, I'd be happy to hear it.

However, I consider this a stylistic choice, and I don't think there is a right or wrong way, as long as it's consistent and readable, just as with any other stylistic choice (like putting your opening curly brace on the same line as the method header or the next line).

Ellie P.
+1 great answer. I'd really like to know the "why" behind it as well. Perhaps bbum or mmalc knows the answer... (they both work at )
Dave DeLong
+5  A: 

Using the style of a language, consistent with the language itself, is the best advice here. However, this isn't a case of writing functional code in an OO system (or vice versa) and the dot notation is part of the syntax in Objective-C 2.0.

Any system can be misused. The existence of the preprocessor in all C based languages is enough to do really quite weird things; just look at the Obfuscated C Contest if you need to see exactly how weird it can get. Does that mean the preprocessor is automatically bad and that you should never use it?

Using the dot syntax for accessing properties, which have been defined as such in the interface, is open to abuse. The existence of abuse in potentia shouldn't necessarily be the argument against it.

Property access may have side-effects. This is orthogonal to the syntax used to acquire that property. CoreData, delegation, dynamic properties (first+last=full) will all necessarily do some work under the covers. But that would be confusing 'instance variables' with 'properties' of an object. There's no reason why properties should necessarily need to be stored as-is, especially if they can be computed (e.g. length of a String, for example). So whether you use foo.fullName or [foo fullName] there's still going to be dynamic evaluation.

Lastly, the behaviour of the property (when used as an lvalue) is defined by the object itself, like whether a copy is taken or whether it is retained. This makes it easier to change the behaviour later - in the property definition itself - rather than having to re-implement methods. That adds to the flexibility of the approach, with the resulting likelihood of less (implementation) errors occurring. There's still the possibility of choosing the wrong method (i.e. copy instead of retain) but that's an architectural rather than implementation issue.

Ultimately, it boils down to the 'does it look like a struct' question. This is probably the main differentiator in the debates so far; if you have a struct, it works differently than if you have an object. But that's always been true; you can't send a struct a message, and you need to know if it's stack-based or reference/malloc based. There are already mental models which differ in terms of usage ([[CGRect alloc] init] or struct CGRect?). They've never been unified in terms of behaviour; you need to know what you're dealing with in each case. Adding property denotation for objects is very unlikely to confuse any programmer who knows what their data types are; and if they don't, they've got bigger problems.

As for consistency; (Objective-)C is inconsistent within itself. = is used both for assignment and equality, based on lexical position in the source code. * is used for pointers and multiplication. BOOLs are chars, not bytes (or other integer value), despite YES and NO being 1 and 0 respectively. Consistency or purity isn't what the language was designed for; it was about getting things done.

So if you don't want to use it, don't use it. Get it done a different way. If you want to use it, and you understand it, it's fine if you use it. Other languages deal with the concepts of generic data structures (maps/structs) and object types (with properties), often using the same syntax for both despite the fact that one is merely a data structure and the other is a rich object. Programmers in Objective-C should have an equivalent ability to be able to deal with all styles of programming, even if it's not your preferred one.

AlBlue
+2  A: 

In my opinion, the dot syntax makes Objective-C less Smalltalk-esque. It can make code look simpler, but adds ambiguity. Is it a struct, union, or object?

dreamlax
+2  A: 

Honestly, I think it comes down to a matter of style. I personally am against the dot syntax (especially after just finding out that you can use it for method calls and not just reading/writing variables). However, if you are going to use it, I would strong recommend not using it for anything other than accessing and changing variables.

+4  A: 

I use it for properties because

for ( Person *person in group.people){ ... }

is a little easier to read than

for ( Person *person in [group  people]){ ... }

in the second case readability is interupted by putting your brain into message sending mode, whereas in the first case it is clear you are accessing the people property of the group object.

I will also use it when modifying a collection, for instance:

[group.people addObject:another_person];

is a bit more readable than

[[group people] addObject:another_person];

The emphasis in this case should be in the action of adding an object to the array instead of chaining two messages.

rebo
+1  A: 

I think I might switch to messaging instead of dot notation because in my head object.instanceVar is just instanceVar that belongs to object, to me it doesn't look at all like a method call, which it is, so there could be things going on in your accessor and whether you use instanceVar or self.instanceVar could have much more of a difference than simply implicit vs. explicit. Just my 2¢.

Mk12
+2  A: 

One of the main advantages of object-oriented programming is that there is no direct access to internal state of the objects.

Dot syntax seems to me to be an attempt to make it look and feel as though state is being accessed directly. But in truth, it's just syntactic sugar over the behaviors -foo and -setFoo:. Myself, I prefer to call a spade a spade. Dot syntax helps readability to the extent that code is more succinct, but it doesn't help comprehension because failing to keep in mind that you're really calling -foo and -setFoo: could spell trouble.

Synthesized accessors seem to me to be an attempt to make it easy to write objects in which state is accessed directly. My belief is that this encourages exactly the kind of program design that object-oriented programming was created to avoid.

On balance, I would rather dot syntax and properties had never been introduced. I used to be able to tell people that ObjC is a few clean extensions to C to make it more like Smalltalk, and I don't think that's true any more.

hatfinch
A: 

I personally don't use dot-notation at all in code. I only use it in CoreData KVC binding expression when required.

The reason for not using them in code for me is that the dot-notation hides the setter semantics. Setting a property in dot-notation always looks like assignment regardless of the setter semantics (assign/retain/copy). Using the message-notation makes it visible that the receiving object has control over what happens in the setter and underlines the fact the those effects need to be considered.

I'm still considering whether I might want to use dot-notation when retrieving the value of a KVC compliant or declared property because it admittedly is a bit more compact and readable and there are no hidden semantics. Right now I'm sticking with message-notation for sake of consistency.

VoidPointer
There still might be hidden things going on. A getter can do other things than just return an instance variable. Even if it is a declared property the getter doesn’t have to be synthesized or it could have been overridden in a subclass.
Sven
+1  A: 

The dot notation tries to make messages look like accesses to a member of a struct, which they are not. Might work fine in some cases. But soon someone will come up with something like this:

NSView *myView = ...;
myView.frame.size.width = newWidth;

Looks fine. But is not. It's the same as

[myView frame].size.width = newWidth;

which doesn’t work. The compiler accepts the first, but rightfully not the second. And even if it emitted an error or warning for the first this is just confusing.

Sven