

Adopting Objective-C Generics - gmac
http://www.miqu.me/blog/2015/06/09/adopting-objectivec-generics/

======
pavlov
I've been programming in Obj-C for 14 years. When I started, I was worried
about adding the wrong kind of object into an NSArray. But turns out that this
practically never happens. I can't remember the last time I had a bug that
would have been prevented by generics.

So why was this added to the language? I have no idea. I guess it's just some
kind of CS dogma -- the same that guided the design of Swift.

~~~
mikeash
I've never had an error where I added the wrong kind of object to an array.

I have, however, spent untold cumulative hours looking up the documentation of
a call that took or returned NSArray* just to see what kind of objects it
expected or provided in that array.

Cocoa is filled with methods like:

    
    
        - (NSArray *)items;
    

What does it return? An array! What's in the array? Items! What class
represents items? Who knows!

Sometimes it's obvious, sometimes it's not. Sometimes you have to look up the
documentation and see. Sometimes, if you're really unlucky, you have to just
print the thing out at runtime and see. It's almost always a pain in the ass.

Good Objective-C code will add a comment to the above to the effect of, //
This returns an array of MyFooItem instances. This allows the programmer to
quickly see what they can expect. Generics just formalizes this and puts it in
a form that the compiler can understand. What's so bad about that?

~~~
pavlov
There's nothing wrong with that, it's nice. But that's all it is IMHO -- just
nice. So I'm not sure why they're bothering to add it to Objective-C now.

One of the reasons I've always liked Obj-C is that it is (was) such a thin
layer over C, and the amount of new syntax was minimal. Devising new ways to
litter code with <> brackets smells suspiciously like C++.

~~~
potatolicious
They're adding it to Objective-C now to make it interop better with Swift.

Objective-C classes have Swift interfaces automatically generated so you can
call them from Swift code. Up until now this has been pretty shitty, since
Swift is overall a stricter language than Obj-C. e.g., calls in Swift can
enforce a return value to be non-nil, but Obj-C cannot, therefore all Obj-C-
Swift interfaces leaves these values in an unknown nullable state even if the
code itself makes guarantees on nilness.

The "nice" bits being added allow proper generation of Swift interfaces so
that Swift code calling Obj-C code doesn't lose type safety (or nil-safety).

------
kinofcain
Curious as to how this actually works under the hood.

This looks like type erasure (checking the types in the compiler but treating
everything as id under the hood, similar to what Java does), whereas swift, if
I'm not mistaken, uses reification for generics (creating separate copies of
each class/function for each parameter type used in the application).

Does that mean that the compiler is doing erasure for generics coming in from
Objective C, inserting runtime casts where needed, but then doing full
reification on swift code?

Seems like that would have to be how it works, no?

~~~
mikeash
There's not much reification to be done when dealing with ObjC objects and
calling ObjC methods. For example:

    
    
        let a = A()
        a.someMethod()
        
        let b = B()
        b.someMethod()
    

If A and B are Swift types, then the code to invoke a.someMethod() might be
substantially different from the code for b.someMethod(). There's struct
versus class, final methods, the potential for inlining, maybe more.

If A and B are both Objective-C classes, however, then the code for the two
invocations is identical. Both will compile down to a call to objc_msgSend,
passing the object and the "someMethod" selector to it as parameters.

So yes, it looks like the types get erased on the ObjC end of things, but I
don't think the Swift end of things has to care very much. It can emit code
without any runtime casts or any adjustment for the actual generic type.

------
powzapbiff
The author mentions "kindof" but uses "__typeof" in code. Should really proof
read before posting.

~~~
mikeash
You can never catch everything. I'm sure the author would appreciate a quick
note pointing out the mistake, if you can leave out that second part.

