
Cargo-cult typing, or: Objective-C's default type is id - mpweiher
http://blog.metaobject.com/2014/03/cargo-cult-typing-or-objective-c.html
======
chc
This article is technically correct, which I'm told is the best kind of
correct. However, it's also missing the forest for the trees.

It is true that we can omit id and still satisfy the compiler. This is the
same way that we can leave out the int type in C function declarations, or
completely leave out function declarations altogether if we're dealing only in
ints. In both cases, though, _nobody does this_ — and if you do this, your
code will read as a mistake to anybody who has read any other Objective-C code
from the past decade.

We include these "extraneous" types not for the compiler, but to make our
intentions clear to the reader. This is the same reason many people and style
guides use one-line compound statements or typedefs that make the token longer
but more descriptive — at the same time we sacrifice a little brevity, we also
sacrifice ambiguity.

It probably isn't always true that explicit is better than implicit, but it's
a very good rule of thumb. If you have to choose one for a default mode,
"explicit" is definitely the better choice.

As for the larger point about dynamic types, I and a lot of other old-timey
Objective-C programmers felt the same way. It seems to me that powerfully
dynamic languages like Smalltalk are good, and powerfully static languages
like OCaml are good, but C's type system is just anemic and more bureaucratic
than anything else. However, in practice, all these static facilities in
Objective-C have proven really useful for writing real programs. The static
analyzer can catch all sorts of errors. A combination of very consistent
conventions and sophisticated static constraints has even allowed memory
management to be handled for us completely through static analysis — that is
just amazing, and the benefits of being rid of that responsibility are huge.
Apple keeps moving in the static direction because those are the additions
that Objective-C programmers are finding useful in practice.

I agree, the more loosey-goosey dynamic and implicit style works better for
exploratory programming. I'll sometimes write spikes that way. But a book
teaching how to write code in the language is not a throwaway spike solution,
and in that environment you should either explicitly tell readers you're
teaching them a style that nobody else uses in production code or — and this
is my preference — just write idiomatic code.

~~~
McUsr
I agree totally. I must say, that I have seen typeless declarations in code,
but I do find them to be a nuisance. Adding (id) to a declaration isn't really
that hard, and makes the code a lot more radable. Why raise the treshold for
the ability to read Objective-C?

------
seanalltogether
It seems though that if you're writing a book that is used as a documentation
reference, you should be fitting with the coding standards that Apple uses for
their own documentation. You would be hard pressed to find any framework
header or apple doc that doesn't use -(id)mymethod

~~~
mpweiher
Why? (Hint: the book demonstrates that quite a few things that Apple
recommends are, how shall I say it, not entirely optimal)

~~~
jasonlotito
> how shall I say it, not entirely optimal

In what way? Is there a measurable performance penalty paid for including the
return type of (id)?

There is clearly a penalty paid in understanding and clarity, which flies in
the face of the topic of your book. If you have explained that, than your
reviewers aren't reading your book (which is a different problem of sorts).

Considering your books is targeted at the Apple audience, I think these are
fair questions. Simply saying "because I can" or "this is how I've always done
it" isn't really good enough. However, if you can point to real benefits to
not including the default type in the definition (something more subjective
than clarity in your eyes), then you should spend time explaining that.

~~~
mpweiher
There is no execution side difference for writing or omitting the (id). The
point is that you shouldn't follow advice blindly, even if it comes from
Apple.

The KISS principle or Occam's razor strongly suggest that those who introduce
redundant entities are the ones who have to justify their choice, not the
other way around.

"Everybody does it this way, now" is a reason, though we can debate whether it
is a good one.

------
Greenisus
I've been developing in Objective-C for years now and I didn't know you could
declare a method without explicitly stating a return type. I imagine many
other people don't know that either, so I'd argue that saying
-(id)doSomething; is more readable.

Now that I know, though, it has become syntactic noise for me.

------
vor_
\- (id)foo tells me that the method returns an object rather than simply
performs an action. The article doesn't explain why this makes Objective-C
harder or less fun. It reminds me of the anal-retentive complaints from long-
time NeXTStep developers that I used to see on the Objective-C mailing list
before I unsubscribed. Those guys don't even want you saying "call a method"
instead of "send a message".

~~~
jayvanguard
What does drive me nuts is the non-sensical spacing.

\- (id)foo

reduces readability, while

-(id) foo

is much better.

I realize the first one is more common in Apple and is probably more standard,
but it begs the question why such a horrible convention ever caught on.

~~~
mpweiher
However,

-foo

is even better. :-)

~~~
myko
No, -foo is confusing and reduces readability.

~~~
mpweiher
How so?

~~~
myko
It is difficult to tell at a glance if -foo is returning something or just
modifying state.

~~~
mpweiher
No it's not. If it didn't return anything, it would be

    
    
        -(void)foo;
    

This is how C and by extension, Objective-C work: to indicate "nothing" you
have to put in something, specifically "void".

------
overcyn
This is equivalent to the semicolons in javascript debate. Pointless bike-
shedding. You save 4 characters, big deal.

~~~
jayvanguard
I agree. Putting in the id return or not is irrelevant.

I also think his larger point is important though. The general trend towards
more explicit typing being the default is a move away from Objective-C's
Smalltalk roots and this is a bad trend.

I suspect it is somewhat influenced by Java programmers invading the
Objective-C space and spreading their rigid typing, pattern-itis cancer.

~~~
mpweiher
You are right about your suspicion. In fact, one of the central characters
came out an flatly stated that Java was a better language. He had a hand in
the "modern syntax" (anyone remember that?), property dot notation and the GC
implementation that ultimately failed.

He also once said to me that Objective-C being a statically typesafe language
was a fact that could not be argued about.

Hmm.

Also agreed that whether the (id) is there or not doesn't matter (much). I
myself have been happily reading over it without really noticing for upwards
of two decades now. What bugs me is the claim that it _has to be there_.

------
AlexanderDhoore
You haven't actually explained why you think static typing is such a
problem... `Id` is still there. Use it when you want. But if I want to call
"setText:" on a UILabel and documentation says it needs an NSString... That's
pretty handy.

~~~
mpweiher
The reason I haven't explained why static typing is such a problem is because
I don't think it is, for example I agree with what you write.

The problem is the stricter enforcement, which I explain near the end "A
dynamic language": explorative programming, where you are still figuring out
what exactly to do, has become much more onerous, widening the gap between
Objective-C and other dynamic languages such as Ruby or Python.

Previously, the compiler would warn you that you hadn't gotten the types yet,
but as long as you were in the id subset (an extended subset, actually) that
didn't matter and you could continue exploring until you got it right...and
THEN write down all the types in order to have the positive effects of
machine-checkable documentation.

With the changes, this is no longer possible, so you have to alway juggle (a)
the site of the client (b) the implementation of the method and (c) the header
with the method. That gets old fast.

------
wsc981
Somewhat unrelated ...

I wish Apple would add local type inference to Objective-C, perhaps using the
existing id type or some keyword like var in C#. It would make the code so
much more quicker to write, less verbose, a bit easier to change.

I mean reading and writing something like:

    
    
        var color = [UIColor green];
        var viewController = [[MyViewController alloc] initWithBackgroundColor:color];
    

Is so much more pleasant as:

    
    
        UIColor *color = [UIColor green];
        MyViewController *viewController = [[MyViewController alloc] initWithBackgroundColor:color];

~~~
mpweiher
You could just write:

    
    
       id color = [UIColor green];
       id viewController = [[MyViewController alloc] initWithBackgroundColor:color];
    

The UIColor* is largely there for your benefit, for the compiler it makes
hardly a difference (pre ARC). If you don't find it a benefit, just leave it
out.

~~~
wsc981
Problem with using id is that it has no knowledge of type information. Xcode
wont be able to autocomplete. This in contrast with using the var keyword in
C#.

~~~
mpweiher
As I wrote: it's there for _your_ benefit...

------
btown
I'd argue that typing (id) explicitly is actually good, because it gets the
programmer and any readers of the code in the habit of seeing that there is a
_space_ to notate return types. Lowering the cognitive barrier to static
typing can only be a good thing.

~~~
dasil003
The semicolon debate is even more substantive because that potentially leads
to real bugs of the difficult-to-debug variety.

------
jcizzle
You can also define methods without labels:

\- (void):(int)arg :(int)anotherArg :(int)someArg { NSLog(@"%d %d %d", arg,
anotherArg, someArg); }

[self:1:2:3];

Try it. It compiles. It runs. How great is that? In fact, even Apple has done
this!

\+ (id)functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x
:(float)c2y;

So does this make this the best option? Should we even name our methods?

Of course, that is silly. Naming our methods appropriately tells us a lot. It
means we don't have to check the documentation as much, which means we can
effectively write faster. We're communicating with our code and our teammates
more efficiently. The same holds true for explicitly typing method return
values.

So ask yourself this: what's the default storage mechanism for a property,
assign or strong? Now what was it when ARC first was developed? That's right,
it was different. So you could see how someone might be confused reading your
code if you weren't explicit. They might spend time looking in the wrong
places for a bug. So why not be explicit? It's not about you, it's about
everyone else who is left with your code.

So Brad Cox doesn't explicitly type his returns. Neither did Nextstep
sometimes. That was 20+ years ago. We didn't have fancy IDEs with
autocomplete; keystrokes were a luxury. That's probably why they couldn't put
the 'e' on 'creat' in libc.

Last couple of Objective-C articles making it to the top of Hacker News have
been bad. Just a kind warning to any budding Objective-C developers: just
because it made it onto Hacker News doesn't make it good.

------
seivan
You could always use instancetype to indicate that you're getting an instance
of the class back.

    
    
      @interface NSArray (XXHelpers)
      -(instancetype)reverse;
      @end
    

or even better

    
    
      @protocol XXReversing <NSObject>
      @required
      -(instancetype)reverse;
      @end
    
      @interface NSArray (XXHelpers)
      <XXReversing>
      @end
    
      @interface NSOrderedSet (XXHelpers)
      <XXReversing>
      @end

------
slavoingilizov
Static typing is easy for newbie developers. It sets hard boundaries, and when
you remember those rules, it's easy to follow what the code does. You don't
have to step through it in your head and think about it much to figure it out.

With that said, I think Apple are pushing the language in that direction,
because recently everyone started developing for iOS, even people who didn't
program at all. Apple is trying to make it easy for them. I see nothing wrong
with that. It may not be the best from a programmer viewpoint, but I can
understand it.

P.S. I think this is why Microsoft has embraced static typing throughout its
developer ecosystem. It makes learning from scratch much easier and developers
(although not very experienced ones) flock to your platform. Of course this
same thinking created ASP.NET and shortened the lives of many good men. But
you cannot judge them, really.

~~~
enjoy-your-stay
Actually Microsoft's earlier and very successful development tools were all
dynamically typed versions of Basic.

Visual Basic, Access, Excel and ASP were all dynamically typed, and were very
responsible for exploding Windows' market share from Windows 3.0 onwards as it
encouraged many to start programming who never would have considered it
before.

Unfortunately they created an ecosystem of novice developers that many within
MS I think despised and looked down on and which gave their platform a bit of
an unprofessional reputation.

Then along came Java and showed them that a relatively sophisticated and
strongly typed language could raise the entry bar just a bit, but result in
generally much higher quality of end product, so along came C# and out went VB
and COM.

'Classic' ASP has also been responsible for much hair loss in early webmins.

~~~
poizan42
Sorry for nitpicking, but COM is in no way out - it forms the basis for WinRT.
Also COM in itself doesn't have much to do with dynamic typing - sure there is
IDispatch which allows your code to be called from dynamic languages, but
that's about it.

------
krazydad
The more vociferously a language-feature is debated on Hacker News, the less
it matters.

------
nextstep
Sounds like this guy wishes Objective-C was Smalltalk with C-syntax.

~~~
mikeash
Well, it pretty much _is_.

~~~
nextstep
No, it's not. That's what this guy is complaining about. Objective-C is
dynamically typed, but allows for static typing; Smalltalk is always
dynamically typed.

~~~
mpweiher
It's not Smalltalk with C syntax. It's C with C Syntax and an object system
with Smalltalk syntax smashed together.

It is having _both_ that is the beauty of it, in more ways than one. Very
expressive high level code _and_ low-level bit banging when you need it.
Dynamic, explorative programming that can be hardened to stricter typing
regimes once a design stabilizes.

What I am complaining about is not just that this duality seems to be getting
lost, but that it is lost by apparently combining the worst of both worlds,
the expressiveness and rigidity of statically typed language and the
performance of a dynamic language. And what's worse, it appears that it's
being done without even a conscious decision, but more by drifting aimlessly,
picking up features and practices more or less haphazardly.

