Bracket-notation syntax

I don’t agree with The Big Nerd Ranch’s philosophy. When I teach, I make sure to mention the bracket-notation added to C by Objective-C. Then, I make sure to tell the students never to use it ever, ever, ever again. Buy why? To keep our code consistent and maintain readability.

The Intent of Code

When we look at well written C code, we can tell exactly what is going on by glancing at it. That’s the power that C gives us. If I want to take a drink of water while doing a cartwheel, I call the function:

drink(water, TRUE);

We know exactly what that means. There is no room for interpretation. It is pure, simple, and good, just as Jesus intended.

Then comes Objective-C…

Objective-C comes along, sprinkling diabetes-inducing syntactic sugar all over our code. We wind up having to read code like this:

x = [foo value];

What is that? Can anybody interpret that? Of course not! That’s because the compiler could translate it into a call to any one of the functions objc_msgSend, objc_msgSend_fpret, or objc_msgSend_stret. But we have no way of telling which one! It’s impossible! For all we know, the compiler just picks one at random!

It’s incredibly confusing, which is why I recommend that students exclusively call those C functions directly, so there is no doubt about which one is being called. That way the code is readable.

But I’m used to Smalltalk. Bracket notation looks like I’m at home!

You are not at home. You’re in the forest, and wolves are trying to kill you.

Apple uses it in their sample code, though!

That’s right, they do. But should you really be trying to emulate Apple? Have you heard about the App Store review process? They are totally incompetent and can’t do anything!

In the end, there is a wrong way and a right way to write Objective-C code. I will not say that using brackets is wrong, even though I tell my students never ever to use it. Is that confusing? Not as confusing as brackets are.

5 Responses to “Bracket-notation syntax”

  1. The nice thing about brackets in ObjC, is they are used in such an obviously distinct and unique manner from “vanilla C”, that there’s never any misunderstanding about what they mean.

    In my opinion the only real reason dot notation in ObjC2 gets the push-back that it does is because it hijacks a notation that can be easily confused with the common C-language notation for a struct element offset.

    So, if you want to argue for dot notation, argue on its merits. I don’t think your implication, that opponents of dot notation are merely luddites, is true.

    We’re up-in-arms about blocks, for instance. The use of the ^ notation for blocks is handled in a way that makes it very unlikely to get an ambiguous reading of the programmer’s intention.

    I think that the dot notation syntax was simply a mistake. I don’t fault the designers, it’s hard to come up with something that will stand the test of programmers, and how they actually work with the language. But hindsight is 20/20 and to me the dot notation’s problems outweigh its benefits.

  2. (Meant to say “We’re NOT up in arms about blocks, for instance.”)

  3. Benjamin says:

    My problem is with appeals to “readability” that are arbitrary and ridiculous. Dot notation is unambiguous if you know the type of the variable preceding the dot. More importantly, if used correctly the intention of foo.value is pretty much the same whether foo is an object or a struct.

    The arguments basically state that “foo.value” is confusing because, without context, you don’t know what it might compile to. That’s a useless metric, because nobody ever needs to evaluate a line of code without any context.

    It’s about as valuable as arguing that “x = y + z” is confusing because you don’t know what machine instructions it will compile to, since x, y, or z could be any mix of char, int, float, long, double, long long, etc.

    So, I’m not saying that opponents of dot notation are Luddites. I’m saying they are misguided. They are setting arbitrary boundaries for what’s “confusing” based on useless measures of “readability.”

  4. Jim Dovey says:

    I’d add a little something to the preceding paragraph in Benjamin’s last comment: “x = y + z” could be all sorts of different things. In C or Objective-C the possibilities are as listed above. In C++ (or Objective-C++) the possibilities are much larger, since any one of those could be a C++ object, any of which could have overridden = or + to perform different operations. In C++, you even get to implement different versions of those for different types.

    I’ve seen plenty of C++ code where something went wrong because a compiler did something behind-the-scenes which resulted in a different operator method being called, and often the type error messages wouldn’t help at all. At least in ObjC with property syntax, the compiler can look at the property itself and point the user back to the property declaration. It can also enforce things like ‘readonly’ properties where a writer is defined inside the class for its own internal use— ‘[foo setValue: x]‘ would work, since -setValue: exists, but ‘foo.value = x’ would fail because the property is declared as readonly.

  5. Benjamin says:

    I agree that operator overloading is objectively terrible.