With the birth of Swift, we face the passing of Objective-C. To mark this historic moment, long-time Objective-C developer and trainer Aaron Hillegass delivers an impassioned eulogy for a language he knew well.
Deploying the standard tropes of the genre, we learn about the life of the deceased, we celebrate their finer qualities, and we reflect on how their influence continues to live on, in the minds and work of those who knew them. From Simula, Smalltalk, and Xerox PARC, to NeXTSTEP, OpenStep, and Objective-C 2.0, it’s a narrative rich in anecdotes and achievement. But as we ready our farewells, a twist. Could it be that the reports of a passing have been, perhaps, a little exaggerated?
If you’d like to share your thoughts about this post, you can comment here.
A Eulogy for Objective-C (0:00)
With Swift coming out last year and everyone being very excited about it, including me, I thought it might be fun to do a talk that was sort of a eulogy for Objective-C. I’ll try to stick with the standard eulogy tropes: we go over the life of the person, we say what we appreciated about them, then we talk about how their influence lives on. Then, in a break from tradition, at the end I’m going to say that Objective-C is not really dead. It’s a eulogy with a twist.
I Love Objective-C (1:52)
I have to admit that I really love Objective-C. Everyone has been talking about what a wonderful language Swift is, and it’s a nice little incremental improvement on Objective-C. But it’s not a really radical departure, and so I have a hard time understanding what people are so excited about.
Objective-C has never really gotten in my way. It has let me create the class structures that I wanted, it has let me do all sorts of low-level things without working too hard. Objective-C is a real treat and I have spent the last 20 years of my career writing Objective-C and teaching people how to write Objective-C.
I really want to stress, right off the bat, I have a deep love for Objective-C. But I thought I’d talk about the history of Objective-C. Just like we would at a eulogy, let’s talk about the person’s parents.
Simula-67 (3:17)
In 1962 there were two guys at the Norwegian Computer Center who were writing simulations in ALGOL and they thought, “Wouldn’t it be cool if our simulations were easier to write?”
They came up with several ideas that they added to the language. These were class and instance and methods. They really dreamed up a lot of what we consider Object-Oriented Programming. They added it to ALGOL, it became Simula, and that was released to the world in 1967: Simula-67.
rg:- New Edge (67,28);
length :- rg.length;
If you look at the code, it actually looks kind of familiar. This was the beginning of the great division between dot notation and not dot notation. Simula 67 went with dot notation — you create objects, and you use dots to call methods on them.
Smalltalk (3:38)
Not too much later the Smalltalk team started writing another object-oriented language. Alan Kay in particular did a lot of work with children, teaching them to program, and he found that children really liked the style of having a label and then what was going on for that parameter. Smalltalk ended up with a label, colon, argument, label, colon, argument style. That was 1980.
The thing about Smalltalk was that the Smalltalk people were so far ahead of everybody else that they didn’t just write a language, they wrote essentially an operating system. You would start up this Smalltalk image, and it took over everything. Everything you needed was inside: your development tool, your browser, and so on. Inside the browser you could browse any of the classes, including things like the Smalltalk interpreter, and you could reprogram the interpreter while you were using it. It was awesome.
myButton := Button new.
myButton label:'press me'.
myButton action:[ myView displaySum ].
Let me also mention this: square brackets. This is how Smalltalk did blocks. We needed a way to set aside message sends, so we put the square brackets on for Objective-C messages instead. You can see that already, Smalltalk was way ahead of everybody else.
Xerox PARC (5:30)
The Smalltalk people - Adele Goldberg, Dan Ingalls, Alan Kay - had all gathered at Xerox PARC, the Palo Alto Research Center, and they spent their time doing groovy stuff. I love this interview with Steve Jobs, remembering his first visit to Xerox PARC.
Smalltalk was a major influence on a lot of things. They were way ahead of their time. They were doing Model View Controller work in the ‘80s, and we are still catching up with some of the stuff they were doing at that time.
But there was a problem, once again, with this idea of the whole image that took over everything. You had to really swallow the whole Smalltalk build, you had to go whole hog into this world, and you were going to give up everything you had ever done before to become part of the Smalltalk image. Then, when you were done, you would ship this image to people, they would start it up on their computers, and it would take over everything.
Brad Cox and Tom Love (7:48)
A guy named Brad Cox came along, and he said we need to take not a revolutionary approach, but rather an evolutionary approach. We should take one of the common systems programming languages and add object-oriented Smalltalk-like message sending to it. This is where Objective-C came from.
A book I’d highly recommend is Brad Cox’s Object-Oriented Programming: An Evolutionary Approach. It is prescient in so many ways, and it lays out Brad Cox’s motivation behind Objective-C. He was working towards the idea of Software ICs, separating the specification of the class from its implementation, which came to be embodied by the h
file and the m
file.
In the second chapter, he talks about the fact that, during the Civil War, the production of rifles became much, much faster, and rifles became much more reliable. They had parts you could swap in and out, because someone had the great idea of separating the specification of the rifle parts from how you built them. The buyer would say what all the measurements had to be, and you could build it any way you wanted, you just had to make sure that it lived up to the spec. Suddenly, when a piece broke on your rifle, you could go to a bin, and you could find the exact same part, possibly created somewhere else, maybe years in between.
Brad Cox and the co-creator of Objective-C, Tom Love, created a company to support it, which was called Stepstone. Stepstone’s version was just generated C code, so it was essentially a pre-processor or a C compiler that took all your message sends and turned them into C function calls. There was no idea of reference counting. You would malloc
an object, you would use it, and when you were done with it you would have to free it. And we just used regular old C, malloc
, and free
. They had a standard library, the ICpak 210, which had all the standard stuff you would expect, like strings, and it also had some user interface things like buttons and windows that worked under Unix.
Objective-C (9:41)
Note that Objective-C had no dash in it at this point. When NeXT bought the trademark, in a radical departure they added the dash. It was named “Objective-C” with a space, and was sold by a company called Stepstone.
At this point, it’s interesting to note that Apple adopted Objective-C as its language for writing GUI toolkits. In fact, for all the hype about functional languages, every time somebody comes forward with another GUI toolkit that’s a hit, it’s always object-oriented. It’s good to stop for just a moment and think, why are object-oriented languages so ubiquitous in writing graphical user interfaces?
Why Object-Oriented? (10:41)
The answer is that they were designed from the beginning to be simulations. When we talk about a button, NSButton
, UIButton
, this is not really a button, it’s a simulation of a button.
As such, all the ideas that made Simula 67 a great language for writing simulations has made object-oriented languages the choice, whether it’s C# on Windows, or Java on Android, or Objective-C or Swift on iOS, and the Mac. We’re seeing again and again that we’re not seeing Lisp as the language for object-oriented programming, or Haskell, or Erlang, which are all incredible languages on the server, but haven’t fit well to these ideas.
NeXTSTEP (12:03)
When Steve left Apple and started NeXT, he had to commission a GUI toolkit. At this point he had learned his lessons, and so from the very beginning, the NeXT computer had not only the graphical user interface that the Mac had, but also object-oriented programming and networking.
Although it was based on Unix, we didn’t want to use X-Windows as our windowing system. Instead, we did a Display PostScript server and your GUI objects were all written in Objective-C. We still didn’t have things like retain counts, and we were relatively new to the game so we hadn’t put prefixes on anything, which immediately started creating problems as the systems got really big.
Steve Naroff and Blaine Guest (12:54)
Here are the heroes of our story. Scott Ritchie worked at Xerox PARC and NeXT, and now he works for Big Nerd Ranch. Next to him is Steve Naroff. Steve came over to NeXT from Stepstone, and has spent the vast majority of his career making Objective-C more and more capable and more and more high performance.
Next is Blaine Garst. Blaine has done incredible things as well, including blocks. Blaine actually retired recently but Steve is still there at Apple making the language go faster and faster.
These are the real heroes because the dynamism of Objective-C, and the way we use selectors, made it a very difficult language to optimize for speed. We didn’t use vtables or other things. These are the people who made the caching mechanism and the lookup as fast as it could possibly be.
Dynamic (13:58)
The wonderful thing about Objective-C is that it’s so dynamic. As we start moving into languages that are a little bit more uptight about such things, it’s nice to take a moment and think about the huge benefits that we get from some of this.
We had, from early on, the idea of introspection. We didn’t have a word for introspection until the Java people came along and made it look special. We would just go to the runtime and look up classes and instance variables under types and manipulate them. Then Java came along, with a tiny API which lets you look up a couple things, and they called it introspection, so we now know the word for it.
Introspection made things like key-value coding possible. You could, say, set this value for the key foo
, and it would go and look to see if there was a method called setFoo:
. If there was, it would call it, and if there wasn’t it would go and set the variable foo
by directly looking at what type it was.
Then we had loose typing. In the early days of Objective-C everything was just id
, we didn’t put types on any of the objects. We just had this one pointer to an object type id
, and then, later on, we went to OpenStep and it became en vogue to explicitly say this is an NSArray*
.
Loose typing made it easy to do things like unarchiving, and target-actions. For example, with target-action you would have a pointer to some object, and you would know what selector you were going to send to it, but you didn’t know at compile time if that object was actually going to respond to that selector. So, at runtime you would click the button, and if you had put in the wrong label in Interface Builder you would get an “object does not understand selector” message.
Loose typing made a lot of things that were difficult in other languages much easier, or possible. It also made bugs that didn’t exist in other languages possible as well. And you embrace that as an Objective-C programmer. You’re like, “This is a language for smart, pedantic, uptight people. I’m going to be very careful and do the right thing when I’m typing in names.”
Take isa
-swizzling. Every object in Objective-C had a pointer to its class structure that defined it, the “is a” or isa
pointer, and you could actually change that at runtime. You couldn’t change the size of the object but you could change what it pointed to. And this made something really nifty possible, something called faulting.
If you’re using Core Data, and you fetch in a whole bunch of employees, and they all have pointers to their department objects, it’s not going to immediately get all those department objects. Instead, it’s going to put in a bunch of placeholders called faults. When you go to that department and ask for its name, at that point Core Data will go out and actually get the data, put it in place, and then change the isa
pointer to point to the appropriate class.
One of the things that made the performance of Core Data so great, and made this faulting mechanism so seamless, is the ability to do isa
swizzling. Once again, this could be very dangerous, but in the right hands it was a really powerful mechanism.
Another thing that you could do was actually create classes at runtime. It was pretty rare, but this is actually what made key-value observing possible. If you had an object with an instance variable called foo
, and you wanted to be informed when that object had its foo
variable changed, a new class could be created at runtime that would override the setFoo:
method, send out a notification that it was just about to change it, then call superset foo and say that the change had happened.
That’s what made key-value observing work. So, even though you may not go in every day and take advantage of this incredibly dynamic stuff that Objective-C can do, in the background a lot of it has been happening for you. It will be interesting to see how we get over some of the challenges in a language like Swift, which is a little more pedantic about such things.
Already, we’re starting to see things like @NSManaged
, which is a nod to dealing with the NSManaged objects and the capabilities that the Objective-C runtime let us do.
Categories Rule! (18:26)
Here’s one that people take for granted at this point, but it’s something that at the time was crazy: categories. The idea that I could take a class that NeXT had sent me, add methods to it, and then use that inside my program - that was really, really weird in object-oriented languages at that time. And it really scared Java people. I don’t know why the Java people were so uptight about it, but they were like, “I don’t understand, you’re extending the standard objects, that seems like a recipe for disaster.” “Calm down”, we said, “it’s going to be fine.”
One of the things that this changed was our sense of frameworks, because you could define a class like in a string in NSFoundation
, and then, when you needed capabilities in AppKit that added to NSString
, like the drawInRect:withAttributes
method, you could just add a category to that inside the AppKit framework.
So as you added frameworks, your classes got more and more capabilities. As a result, not everybody had to write their own NSString class. Which is a really common problem for a lot of languages. If you go into the C++ world, I have no idea how many people have defined NSString and NSData for themselves when every time you loaded a new framework you got a new implementation of NSData.
This was a nice, easy way for us to be able to start with a simple class and then add capabilities to it as we added frameworks.
The Worst Book Ever Written (20:02)
Objective-C: Object-Oriented Programming Techniques by Lewis J. Pinson & Richard Wiener was the main book available at that time, and it was the absolute worst book ever written. I went through it, and I got so mad I started marking it up with red pen as I read it. I sent it back to the publisher, which ironically turned out to be my publisher several years in the future.
I think that, probably, Objective-C would have been adopted much more quickly had this book actually been readable.
A Much Better Book (20:40)
Shortly after that, a much better book came out: this was NeXT’s Object-Oriented Programming and the Objective-C Language, written before I got to NeXT. There’s an urban legend about it, and I can’t tell you if it’s true or not.
As the urban legend goes, the person who wrote this — and I don’t know what their name is — worked night and day to get everything that we knew about object-oriented programming at NeXT into this one spectacular book. Immediately after they shipped it, they had a total nervous breakdown, and never wrote another word. At least, that’s the rumor.
This was a great book. One of the reasons why I didn’t write an Objective-C book for a very long time is because it’s a spectacular book.
OpenStep (21:33)
We started realizing stuff we had done wrong, so we started the OpenStep re-write. OpenStep was not originally going to be open, but we were adding retain counts so we could share objects and they wouldn’t get cleaned up prematurely. We added the NS prefix, which was our answer to namespaces. Then we made more explicit names. In the old days, instead of objectAtIndex
we used to just have a colon. We added a lot of types, giving an indication of what you were going to get back, and what arguments were expected in the method names. The method names all became much longer at that point.
The reason it was called OpenStep was because Sun was getting very frustrated with their X-Windows experience, so they showed up with a big wheelbarrow full of money and said, “if you will give us a license to this source code we’ll add it to Solaris”. We thought a big wheelbarrow full of money sounded pretty good, so we shipped it to them.
This introduced quirks. For example, have you ever noticed on the Mac that you never use NSText
, you always make the subclass NSTextView
? Well, when we took the wheelbarrow full of money we hadn’t finished rewriting the text system, so we just had this class NSText
and that’s what we sold to Sun. Then we added NSTextView
: the signatures and all the methods that take it are always NSText
, but we actually create an instance of NSTextView
.
GNUstep (23:10)
One of the deals with Sun was that we had to make the OpenStep specification an open standard. So, as soon as we made just the headers and not the implementation an open spec, the GNUstep project was announced. It took a gazillion years to actually get anywhere, and it took so long that nobody cares about it anymore, but it is there.
There’s an OpenStep implementation that is open source, and you should check it out, it’s kind of cool.
Web Objects and Windows (23:37)
One of the things people don’t realize is that WebObjects used Objective-C under the covers, and that it was running on Windows. So we actually had Objective-C running on Windows, Solaris, HP-UX, long before it ever got to the Mac. Writing OpenStep applications on Windows wasn’t a huge hit actually, but we kept hoping.
The Fragile Base Class Problem (24:03)
One of the things that was plaguing us around this point in time was the fragile base class problem. Here’s an example: we created NSView
, we gave it a bunch of instance variables, and then we shipped it out to the world. Then people started making subclasses out of it and compiling those up.
We couldn’t add or remove instance variables to NSView
without breaking all the things that were linked against it. So, there were all sorts of crazy instance variables in there that you would never care about anymore, and we couldn’t get rid of them, and we couldn’t add new ones that we would have really liked to have had. That’s a bad position to be in.
Objective-C 2.0 (24:42)
Objective-C started becoming more and more modernized, what we call Objective-C 2.0. They eliminated the fragile base class problem, they added fast enumeration, they added garbage collection, and then ARC. We got blocks and properties.
There’s been a lot of excitement about properties. I don’t know, I’m not that excited about properties, it just seemed like a nice shorthand for doing accessor methods to me. But these other four are huge steps forward for the language.
Pandering (25:11)
Then we did a couple things that were obvious pandering to the people who had been living on the Simula 67 line of languages (Simula 67, C++, Java). They liked the dot notation, so we added the dot notation. Then we added subscripting of arrays and dictionaries. I never had any problem with objectAtIndex
or objectForKey
, but it was frustrating for some people, so we started putting it inside square brackets and people thought that was pretty cool.
Stabs at Concurrency (25:44)
Throughout the history of Objective-C we kept making stabs at trying to do concurrency. At the beginning of OpenStep, we had NSThread
and NSLock
, and then we added @synchronize
, if people remember this. I don’t think anybody uses @synchronize
for anything. Methods could be marked @synchronize
with a variable that would act as a lock. Most recently, we had the operation queue.
Really, the most successful concurrency thing has been NSRunLoop
, which is essentially preventing concurrency. The goal of NSRunLoop
is to allow you to do all sorts of things in a single thread, which other people are doing multi-threaded. It just sits around and waits for events to come in, or network events to come in, or file operations to come in, and then it triggers some code. Before you go and try multi-thread things, if your CPU is not already pegged, NSRunLoop
might be a good answer to it.
Swift is a Step Forward (26:38)
Swift is a step forward. Swift has less C. To me, this is not an obvious benefit. I actually do a lot of stuff with C, and I like to be able to call it and have it look just like regular C in there. I like low level stuff. But by doing less C, we have given the developer tools people at Apple a lot more room to be innovative, and it creates the possibility for things like Playgrounds.
So, less C is actually a big step forward because it creates that sort of flexibility. We do get a more terse syntax when we implicitly declare variables. We get more pedantic type checking including the idea of nil versus not nil, and fewer files. It’s just one Swift file.
Swift is a Mutt (27:22)
But we also end up with the problem that, to maintain interoperability between the two, we end up with sort of a mutt language. In Objective-C you would give a label and a colon for each argument. In the perfect world, you get this middle one where you would have a verb and you would have the two parameters, each with their own label. Instead we get this mongrel thing in Swift, where the verb and the first noun appear there in the method name, and then inside the parentheses you get a bunch of labels after the first one. But not the first one.
[myString insertString:”Ping”
atIndex:12]
myString.insert(string:”Ping”, index:12)
myString.insertString(“Ping”, index:12)
Swift is not the ultimate language, and it’s not flawless - it is compromised because of Objective-C interoperability.
The Apple engineers had this question: “Well, do we keep evolving Objective-C, or do we just throw away all of UIKit and start again with a brand new language?” As an answer, they went with a very reasonable middle of the road. Certain things were a little bit awkward, but the interoperability was still there.
Objective-C is Not Really Dead (28:33)
Here’s the punchline: Objective-C is not really dead. Apple has made a huge investment in the Objective-C libraries that it owns - all of UIKit, all of AppKit, Foundation - everything that is making Apple things run is written in Objective-C. And, they are actively improving Objective-C. We saw templates come out, we saw the non-nil types come out. Objective-C is going to be around for a very long time.
If you’re writing a lot of code that talks directly to C code or C++ code, Objective-C is really still the way to go. If you have stuff that’s a little bit higher level, I think Swift is a beautiful incremental step forward and I’d recommend that to anyone.
If you’d like to share your thoughts about this post, you can comment here.
Receive news and updates from Realm straight to your inbox