The nature of software is to always be evolving. COBOL jokes aside, it’s rare to find programming frameworks that reach a level of maturity and support that allow them to just exist without being supplanted by a newer language or a better abstraction. Which naturally is great. Who wants to find themselves writing software with the expectations of today while performing the tasks of manual memory management or manipulating strings that are just raw pointers in a block of memory terminating with a null (
But sometimes in this constantly evolving space, you find a framework that resonates, and you hold on to it tightly. I wanted to share how this happened for me, first with Ruby (no surprise) but then oddly with Objective-C.
Discovering Ruby was like unwrapping a nested set of presents inside of other presents:
- “Wait?! Everything’s an object?!” – Running
1.nextin an irb console still makes me chuckle
- “Who’s _why?”1 – I still prefer the Poignant Guide to the Pickaxe
- “No way. You can’t build a blog in 15 minutes?”2 – Rails exposed me to convention over configuration, the active record pattern, the model-view-controller pattern, and test driven development all at once
But then the iPhone shipped and everyone wanted to write an “app” for it, myself included. There was a catch though, you had to write it in Objective-C. Which, if you think is an obscure language today, check the TIOBE index on Objective-C for 2007 at the launch of the iPhone.
Also, discovering Objective-C had a little rougher beginning:
- “Wait?! I’m typing square brackets around everything? What is this?!” – Objective-C is C, extended in new ways via square brackets
- “Why does every class start with the letters ‘NS’?” – Namespaces are not a thing, so avoid collisions by prefixing all your class names
- “Where is my garbage collector?” – You are still on C, so keep track of those
releasecycles or segfault and cry
But after you wipe the tears away and the dust settles, you can begin to understand that at it’s core, Ruby and Objective-C actually share a lot in common:
- Ruby has
Objectthat all classes extend from, Objective-C similarly has
- Ruby has
Procfor passing methods around, Objective-C has blocks
- Ruby has open classes for monkey patching, Objective-C has Category and Extensions to do the same
- Ruby has
Object#method_missingfor metaprogramming, Objective-C has a very analogous
- Ruby has
Object#sendfor sending raw dynamic messages to objects, Objective-C runs every message through
- Ruby has runtime/reflection methods for querying objects and changing instance variables like
Object#instance_varaible_set, Objective-C allows you to interact directly with the runtime as well
Architecturally, they actually share enough in common that there have been quite a few attempts at bridging the two together over the years. The earliest of which I discovered dates back to 2001 and was built as part of the GNUstep project – an open source implementation of Apple’s Objective-C and Cocoa frameworks.
Much has changed since then in both the Ruby and Objective-C worlds, but I was surprised that after some tweaks to call modern versions of its Ruby C extension code and Objective-C runtime, and then accomodate for 64-bit architectures, the project’s code runs on modern versions of macOS and Ruby. It’s really a testament to the Objective-C runtime (and Ruby C extension API) that while much of the original code was written in 2001, an incredible amount of it runs unchanged over 20 years later on modern versions of macOS and Ruby.
Now, it’s not lost on me that Objective-C currently shares a spot on the TIOBE index right alongside COBOL in 2023 (position 25 and 26, respectively). Apple’s attention turned to Swift in 2014, and they haven’t looked back. However, even today in iOS 16, Apple ships over 66% of their native binaries still using Objective-C. The language has respectably reached that level of maturity and support that allows it to just continues on, quietly running in the background.