Hacker News new | ask | show | jobs
by gigantor 1971 days ago
There is no doubting the legacy of Objective-C (especially given the high likelihood you are reading this post on a mobile device, using app written in Objective-C), but to truly appreciate Brad's legacy, am curious about the appeal of using Objective-C.

Having developed only one small iOS app with Objective-C code, I was mostly turned off by its overall verbosity in the context of NS prefixes. Hence, I ask the question on behalf myself and others who did not appreciate the language and did not give it a proper chance... what did I miss and what are its top appeals?

Nevertheless, Rest In Peace to a pioneer.

6 comments

In the context of the time, C++ didn't exist yet. Objective-C was actually introduced just prior to C++, and both languages were effectively solving the same problem in different ways: C was the dominant language, and both language designers were trying to graft the OOP paradigm onto it.

Objective-C is a thin-layer on top of C, adding Smalltalk-inspired object support. That's pretty much all there is to it. C, with some new syntax for objects. In the context of a world where C is the norm, that's pretty appealing. This is before Java existed, too.

The "NSWhatever" stuff, as far as I'm aware, isn't part of the language. That's all in the frameworks Apple/NEXT developed for Objective-C. (Note that the base object is called Object, not NSObject, and the integer class is Integer.) NSString is probably named that way because Objective-C doesn't include a string class (nor does C, as a string is just an array of bytes until you write a wrapper to get fancy) and NEXT made one. They were just namespacing the NEXTStep classes.

> Note that the base object is called Object, not NSObject, and the integer class is Integer.

Objective-C actually doesn't require a base object (although these days it essentially does), but Object and NSObject are both examples of root objects. IIRC, reference counting is not in Object and was a NeXT invention.

I'm curious--what happened to Objective-C in that fight with C++? Why didn't people go for its simplicity?
As usual, platform languages win.

C++ was born at Bell Labs and quickly integrated into their workflows as C with Classes started to get adopters.

This raised the interest of the C compiler vendors, so by the early 90's, all major C compiler vendors were bundling a C++ compiler with them.

Additionally, Bjarne got convinced that C++ should follow the same path as C and be managed by ISO, so the C++ARM book was written, which is basically the first non-official standard of the language.

So C++ had ISO, the same birthplace as C and love of C compiler vendors, while Objective-C was initial a work from a small company and later on owned by NeXT.

So, naturally Apple, Microsoft, IBM decided to go with C++, and everyone else followed.

Here is an anecdote for Apple fans, Mac OS was written in Object Pascal + Assembly, when market pressure came adopt C and C++, the MPW was born and eventually a C++ framework that mimic the Object Pascal one (there is a longer story here though, ending with PowerPlant framework).

Copland was based on a C++ framework, and Dylan team eventually lost the internal competition to the C++ team regarding the Newton OS.

Apple was one of the major OS vendors that never cared much about C for OS development, only the NeXT acquisition ended changing it. And even then they weren't sure about C and Objective-C, hence the Java Bridge during the first versions.

> Apple was one of the major OS vendors that never cared much about C for OS development

It's true that MacOS Classic kept providing Pascal headers for most of its APIs for a long time (I don't recall whether they ever stopped), but internally, they started switching to C by the late 1980s (as an external developer, I could tell by one bug which would never have made it through a Pascal compiler, but was typical for the kind of bugs that wouldn't get caught by a K&R C compiler), and by the late 1990, it was all C and C++, just with Pascal calling conventions for all public facing APIs. In my time at Apple, I never encountered a single line of Pascal code.

I bet it was actually C++ with extern "C", which was my point, specially given the MPW and PowerPlant frameworks.

I never knew anyone doing bare bones C on classic Mac.

There was a lot of extern "C" (and there still is a lot of that), but there also was a lot of extern "Pascal" back then, I seem to recall.

There was a quite a bit of regular C in classic MacOS, though there was also a good deal of C++. You're right that MacApp (Which I think is what you're referring to with "MPW", which was an IDE) and PowerPlant were written in C++, but I'm not talking about the clients of the MacOS APIs, but about the implementations of those APIs.

I tried out both Objective C and C++ in 1988, when neither were popular though C++ was more talked about.

What I remember was that with Objective C you needed to track all intermediate values and release them, so you couldn’t write an expression like [[objectA someMessage] anotherMessage] - you had to capture the intermediate in a variable so you could release it at the end.

So this was annoying and I didn’t like Objective C at the time. (25 years later I wrote several iOS apps in it)

C++ let you manage memory and temporary values though constructors and destructors, which was much more appealing, though pre-templates it was quite constrained.

Part of it was licensing. Probably more of it was the personalities involved at e.g. Microsoft or SGI.
Objective C loses to C++ for performance if you really start exploiting OOP a lot. The fact the you can swizzle methods in ObjC says a lot about the "weight" of the underlying implementation ("it's all messages") compared to C++.
The fact that you can swizzle methods also says a lot about its power and flexibility. When Steve Jobs was at NeXT, he was quoted numerous times bashing C++ as having 'dead objects' while pointing out that ObjC objects were 'alive'. One seldom needs to make use of swizzling, but when you do need it, it's an awesome capability.

As prabhatjha pointed out in another comment in this thread, swizzling was used to automatically capture networking calls just by adding our framework to your app and initializing it. You could then log into our app's web-based dashboard and see stats about networking calls (counts, latency, errors, etc.). This simple and elegant solution would not have been possible with C++. We also supported Android at the time (Java), and the developer was required to change his code to call our networking wrapper calls to get the same tracking for their Android apps.

Absolutely. I've used swizzling myself to fix issues with audio plugin's GUIs (to limit how fast they are allowed to redraw themselves). It's very clever and sometimes very useful.

But the ability to do that comes with certain costs, and performance is one of them. The fact that these "methods" are dynamically dispatched sometimes matters, and you can't change that any more than you can swizzle in C++.

> This simple and elegant solution would not have been possible with C++

Actually, it would, but not via any feature of the language. You can use features of the linker to accomplish this (particularly LD_PRELOAD). It's not the same thing, really, but it felt worth mentioning for the record.

In our case, the LD_PRELOAD approach would not have worked because this was on iOS devices where you can't set that variable. However, I do appreciate you mentioning it because it too is a powerful mechanism that enables some creative and non-invasive solutions in some cases.
> Having developed only one small iOS app with Objective-C code, I was mostly turned off by its overall verbosity in the context of NS prefixes.

This is actually a blessing because NS-/name prefixes are a simple approach to naming that keeps you humble. If you let programmers have namespacing they will invent enterprise software frameworks where every class is six layers deep in a namespace of random tech buzzwords they thought up.

> Hence, I ask the question on behalf myself and others who did not appreciate the language and did not give it a proper chance... what did I miss and what are its top appeals?

It implements message-based programming, which is "real" OOP and more powerful than something like C++, where OOP just means function calls where the first parameter goes to the left of the function name instead of the right.

In particular it implements this pattern: https://wiki.c2.com/?AlternateHardAndSoftLayers which is great for UI programming and lets you define the UI in data rather than code. Although iOS programmers seem to like doing it in code anyway.

This plague of object wiring in code is pervasive in the Java world as well. The joy of declarative late binding and decoupled objects at compile time seems to be very lost on the vast majority of programmers.
> It implements message-based programming, which is "real" OOP

No, it's message-based programming, which is a very powerful and useful tool. It's not the one true inheritor of the fundamental OOP concept.

OOP wasn't defined by "you send messages to objects", it was defined by the idea that objects had their own semantics which in turn constrained/defined the things you could do with them. Some OOP languages implemented "doing something to an object" as "send it a message"; some didn't.

ObjC is in the former group; C++ is in the latter.

Well, considering that Alan Kay coined the term...
Alan Kay didn't invent object oriented programming though he was instrumental in expanding its scope and usage. Simula 67 was a big influence on Kay's work, and as he has noted, the "revelation" that "it's all messages" was a huge one.

But Smalltalk is just one OOP language, not the only one and not even the original one (though we could argue about how much Simula was or was not OOP, and I'd rather not).

The message from Kay you cite about is strictly about Smalltalk & Squeak:

> The big idea is "messaging" - that is what the kernal of Smalltalk/Squeak is all about

He doesn't say "what OOP is all about".

Actually he did invent Object Oriented programming.

Simula was an inspiration, but was never considered as object oriented. After Kay came up with the concept, Simula was identified as part of the historical background.

“I invented the term object oriented, and I can tell you that C++ wasn't what I had in mind.” —Alan Kay.

Dahl & Nygard would not agree with you:

https://www.sciencedirect.com/science/article/pii/S089054011...

http://kristennygaard.org/FORSKNINGSDOK_MAPPE/F_OO_start.htm...

Kay came up with the term "object oriented programming", but he has made it very clear that what he had in mind has little relationship to what most people mean by that term today.

If you want to give Kay veto power over the correct application of the term, be my guest but please be consistent across all other cases where a word or phrase changes its meaning over time.

Contemporary OOP pays only lip service to Kay's ideas (something he would be the first to say), and is only tangentially influenced by Smalltalk at this point (Objective C probably being one of the few widely used counterpoints to that).

Objective-C is a very simple, clean language–very much unlike its other "object-oriented-C competitor" C++. Unlike C++ it's a 100% superset of C, and it takes its cues from Smalltalk where objects send messages to each other rather than statically call each other's procedures. To support this, there is a very rich runtime that allows all sorts of reflection and metaprogamming atypical in a compiled language.
Tastes may differ. To me, C++ looks like an organic extension of C syntax, while Objective C looks like an alien graft on top of C.

Same with semantics: In C++ there is a continuum from POD structs to adding non-virtual methods to adding virtual methods. In Objective C there is a gaping chasm between C types and Objective C types, and weirdness occurs when you mix the two (e.g. pass a method taking an (int) to a place expecting a method taking an (NSNumber *)).

Containers (arrays and dictionaries) in Objective C, I find particularly ugly, especially in earlier (pre-2010 or so) versions of Objective C. They can contain only Objective C objects, not C objects, but can wildly mix and match objects of different types (this has been helped by Objective C generics by now). Access to elements is very verbose (this has been helped by syntactic sugar by now).

Just recently, I had to review Objective C code using a multidimensional numeric array. Even in modern syntax, it was no joy to read, and I wept for the senselessly murdered memory and CPU time. But if it had been written in pre-2010 Objective C, I might have lost my will to live for weeks.

I don't see how you can call ObjC any more of a superset of C than C++.

Object-related syntax in ObjC is completely alien to C. Object-related syntax in C++ (mostly) extends C structure syntax.

Yes, ObjC takes its cues from Smalltalk. C++ does not. And so... ?

[EDIT: ok, so people want to interpret "superset" as meaning "every valid C program is a valid Objective C program too. This is, with very few exceptions, true of C++ as well ]

Because ObjC is a strict superset of C in the technical sense. That is: every valid C program is also a valid Objective-C program.

Of course idiomatic ObjC is heavily tilted toward the non-C parts of the language (OOP features), but that doesn’t mean it’s not a true superset of C.

"Yes! C++ is nearly exactly a superset of Standard C95 (C90 and the 1995 Amendment 1). With very few exceptions, every valid C95 program is also a valid C++ program with the same meaning."

https://isocpp.org/wiki/faq/c

Objective-C has no exceptions.
Whaddya mean?

   @try {
        // do something that might throw an exception
    }
    @catch (NSException *exception) {
        // deal with the exception
    }
    @finally {
        // optional block of clean-up code
        // executed whether or not an exception occurred
    }
https://developer.apple.com/library/archive/documentation/Co...

(I'll see myself out. For at least two reasons.)

We are on C17 nowadays.
ObjC doesn't change any existing C syntax, it only adds messages. C++ is an entirely different language with a different spec that merely looks like C.
"Yes! C++ is nearly exactly a superset of Standard C95 (C90 and the 1995 Amendment 1). With very few exceptions, every valid C95 program is also a valid C++ program with the same meaning."

https://isocpp.org/wiki/faq/c

The implicit casting rules are different, it doesn't allow VLAs, you can implicitly create static constructors instead of having your program rejected for non-constants at the top level, more keywords are unavailable as variable names…
VLAs are optional since ISO C11, clang and gcc are probably the only C compilers that care to support them.

C17 also has its share of keywords and C2X plans to replace some of the _Keyword with they keyword version, as enough time has passed since their introduction.

It's not a modern language, so appreciating it has to be in its original context. I think it does an admirable job of augmenting C with object-oriented capabilities. It's certainly easier to master than C++.

I'm not an expert on this, but I suspect that the main reasons it was chosen for iOS were:

- The technical limitations of the original iPhone meant that you needed to use a low-level language.

- The legacy of NeXT at Apple.

Mostly the latter, I would assume. Apple didn't really use anything other than Objective-C for its application frameworks (and still generally does not, for the most part).
I read in multiple sources, usually the kind of comments that is only possible to validate with inside info, that to this day not all business units are sold on Swift.
Sold or not, it's easy to see that most of the code being written is still in Objective-C just by looking at the code that Apple ships publicly.
Objective-C is verbose not just because of the NS suffixes. Everything is verbose (by today standards anyway). ObjC is a "child" of the 1980's when verbosity was considered a merit and a norm in programming.

Two things that I used to like about it:

- Combination of static typing and at the same time pretty high level dynamic typing: it was practically possible to call any method on any object, right or wrong, just like in dynamic languages. For performance critical parts you could always resort to C. Later, as a little bonus it was also possible to resort to... C++. There was such a beast as Objective-C++.

- The method calling syntax. Quite unusual but neat. I liked it a lot.

However, Swift ruined it for me. Now that I'm a total Swift convert and I feel a 2x or even 3x boost in productivity I can't even look at Objective-C code anymore.

> ObjC is a "child" of the 1980's when verbosity was considered a merit and a norm in programming.

It's still considered a merit by some.

I agree with this. Verbose code is code you can come back to an understand years down the road.

The easiest projects for me to pick back up are the ones I wrote in Objective-C, hands down.

>Verbose code is code you can come back to an understand years down the road.

For ObjC, "verbose code" means "code you can come back to years down the road and hope there's still a manual to translate those message argument names into whatever current programming terminology uses".

Thankfully, in computer science terms like "array" and "string" still mean what they did many years ago.
It's not about "array" or string".

     [[NSNotificationCenter defaultCenter] addObserver:self
   selector:@selector(appDidBecomeActive:)
   name:NSApplicationDidBecomeActiveNotification
   object:[NSApplication sharedApplication]];
can you explain to me what any of those terms mean without looking a fairly extensive reference manual?
I loved the idea that the OOP world and the C worlds were syntactically different. It made the language significantly more elegant than C++, which doesn't even take into account the beauty of its Smalltalk message passing semantics.
That verbosity is exactly why I love it.

It's easy to write and easy to read (especially years later). It's just such a joy to work with.