Saturday, December 1, 2012

Objective-C Does Not Belong Outside of Mobile

The power of Objective-C comes from its tight and nearly seamless integration with C. The power of C comes from its focus on efficiency and performance and its quasi-portability. Both of these qualities are essential for mobile development. Mobile devices run on a number of different platforms with different binary types (Android uses ELF, while iOS uses Mach-O) and generally have tight clock and memory constraints. Given these compromises, C is a great choice.

However, C doesn't support object-oriented niceties that were fashionable 10-15 years ago, and it doesn't support functional niceties that are en vogue now. Objective-C does an passable job at the former is trying to get better at support for the latter with the help of ReactiveCocoa and friends.

So, given that Objective-C minimally satisfies the requirements of a modern language, should we extend it to the web? I don't think so. The web doesn't operate under the same CPU and memory constraints, so we can use some of that power to make developers more efficient. In cases where bottlenecks occur, most programming environments still support C development. Objective-C may make sense there. However, most developers aren't building Facebook, and Facebook has even figured out a way to make its code more efficient while harnessing the power of its army of highly skilled PHP developers.

Kevin Lawler makes a case for Objective-C on the server. I'll break down my disagreements with his article below. I'll use Java as a counterexample since it is currently the dominant player and is widely deadpanned as being an awful language. If Objective-C can't beat Java, it doesn't stand a chance against ruby, python, javascript, clojure, scala, or any other server-side cult hits.

Objective-C is not a joy:

In the past few years, quietly, almost invisibly, Apple has transformed its Objective-C language into the best language available. I have been working with Objective-C since the release of the iPhone App Store in 2008. In that time Objective-C has evolved from a clunky, boilerplate-heavy language, into a tight, efficient joy. It is an amazing tool. Anything that I would not write in C I would want to write in Objective-C, were support available.
No. Objective-C is not an efficient use of developer time, nor is it a joy. There is still a ton of boilerplate present. I'm sure there are many other things I hate about Objective-C the language, but these are just a few things I came up with off the top of my head.
  • I must declare both an @interface and @implementation for every class.
  • The compiler doesn't support circular references, you must forward declare classes and protocols that are circularly referenced with @class and @protocol.
  • There is no support for namespaces, leading to names like kBluetoothAMPManagerCreatePhysicalLinkResponseAMPDisconnectedPhysicalLinkRequestReceived
  • There are no private methods. There is no way to be sure that a subclass won't accidentally override one of my internal methods simply by reusing one of my names.
  • No type variables (generics)
  • Can't add nil to Foundation collections
  • No support for inner classes
  • It is a superset of C, so everything you hate about C goes here too.

A paragraph full of fail:

To understand the opportunity facing Objective-C it will help to summarize where Java fails. The original promise of Java was that an application written once would compile and deploy on any architecture. Ignoring that this is false, web shops don't use Java for this reason. Platform inconsistency is an issue for almost no one, and it was never an issue to port correct C/C++ code, universal compatibility being the original promise of C as well. This promise however spurred the creation of the JVM, which was Java's first mistake. The JVM is a nonsense abstraction over the assembly and UNIX system layer. Now code runs through an additional layer, which can be slow, and system interactions must be translated through an otherwise pointless, just-for-this-purpose Java API. In the ideal case, this API replicates the entirety of the UNIX system layer in Java-ese, obscuring any helpful C idioms or UNIX-system knowledge in the process, and creating a pointless set of new knowledge to understand. In the less than ideal case, the API fails to implement system-level functionality and creates a barrier between the application and the machine.
 So much is wrong with this paragraph.
Ignoring that this is false, web shops don't use Java for this reason.
There are certainly edge cases, but this is far from false. Java is very much write-once run everywhere. More importantly, it is compile once, link and run everywhere. I'll grant you that some Java libraries have crazy mavenized builds that can take way too long to run, but that isn't Java's fault. Code that you write in Java will compile the same way on any machine and run basically the same way on any other machine, regardless of endianness, instruction width, or operation system. Web shops depend on this to easily consume libraries from all over the Java ecosystem. I invite Mr. Lawler to look at the amount of platform specific code in the average Apache Jakarta project. I'll bet it is effectively zero.
Platform inconsistency is an issue for almost no one, and it was never an issue to port correct C/C++ code, universal compatibility being the original promise of C as well.
I'm hardly a C badass, but I'm pretty good at Java. I'm not at all confident in my ability to write correct platform independent C code. Thankfully, I only target iOS, and I only build with xcode, just like every other iOS developer out there. Nearly all iOS developers build with Clang, and most are on one of a few key versions. I can't imagine trying to build a reusable library that would compile and link with all the different C/C++ compilers/linkers and run on nearly any system.

Even if we ignore the need to write universally compatible code, I would have to invest great amounts of time in consuming any library that wasn't written specifically for my platform. If I wanted to use Apache commons-codec, but it was written on 32-bit Windows, I'd be very skeptical about consuming it on 64-bit Mac without a thorough review. I have no such concern about Java. I can't believe it is 2012, and I have to make that argument.
This promise however spurred the creation of the JVM, which was Java's first mistake. The JVM is a nonsense abstraction over the assembly and UNIX system layer.
No. The JVM is a portable UNIX system layer that runs everywhere. The JVM brought UNIX to windows, and its portable bytecode has enabled an amazing ecosystem of languages, most of which has the power to interoperate.
Now code runs through an additional layer, which can be slow, and system interactions must be translated through an otherwise pointless, just-for-this-purpose Java API.
I guess Mr. Lawler has never heard of the Hotspot JVM's amazing inlining technologies in its JIT compiler. Also, he links to a stackoverflow answer that basically says Java is not slow at all, though the answer does list some downsides with respect to memory and startup time, both of which aren't issues for the web.

A few more nits to pick:

Garbage collection makes execution (and memory usage) unpredictable. You cannot postpone garbage collection forever. The more critical the execution, the more you want to postpone garbage collection, but the longer you postpone garbage collection, the more of a problem it will eventually be. This is a disaster for applications that need to scale.
There is truth here, but Azul's Zing basically blows it all away.
Oracle now owns Java and is a hostile entity. Java is done. Its future as a product is finished.
Although Oracle decimated the JCP, they have been a terrific steward of Java for features. They actually shipped Java 7, which greatly improved performance and includes many new features (including lots of missing UNIX APIs).
As an aside, tying any new language to the Oracle JVM is destined to be a mistake, for reasons previously mentioned.
The JVM is a great place to run a new language. JRuby applications saw free performance gains of up to 30% just from moving from Java6 to Java7.
In practice, object-oriented programming lets large teams of competent programmers build usable software. The same is rarely said for functional languages. In cases where functional language applications do succeed, they are often treated as prototypes and rewritten.
I can point you to a whole army of people that would disagree with that. I know of 3 different companies just in St. Louis that build very big systems with functional platforms. Of course, this is only anecdotal evidence, but I'm sure functional languages are taking off if a small town like St. Louis has such a good showing. Of course, twitter famously uses functional languages for many things, including processing its massive logs.

The lines that caused me to write this blog post:

5. Xcode is an excellent IDE, with tolerably good git support
This line just killed me. Xcode is the biggest piece of shit modern IDE I've ever used. I outlined my hatred in a presentation I gave to Lamda Lounge. If Mr. Lawler thinks it is excellent, he's clearly never used Eclipse JDT or IntelliJ IDEA, and he's never been amazed at swapping hot code at runtime with JRebel. He must not have ever wanted to use a structural code formatter, either. I'm sure he doesn't care about creating plugins or modifying the tools he uses. I doubt he wants a transparent bug reporting system.
IDE auto-completion works wonderfully.
No, it doesn't. I just barely works. If there are any compilation errors in the class, the autocomplete fails.   It stupidly suggests methods from all over the various C APIs that I've never used and I doubt would ever be applicable to my code. It never prioritizes local variables or methods that I most often use. "NSS" doesn't complete to "NSString", it completes to "NSStream". "NSLo" becomes "NSLoadedClasses".
The library import process is less tedious than in Java.
I think Mr. Lawler is trolling me. Xcode has no auto-import at all. In Eclipse, if I type "Set", "import java.util.Set;" is automatically added at the top. I would love this feature in Xcode. If I want a library in Xcode, I have to use the mouse to navigate through 5 modal operations.

Still Good For Mobile

Again, mobile development operates under a different set of constraints. We need C on mobile, and we need a modern superset of C to build mobile applications. Objective-C is a decent choice. As I outlined above, it has warts, but they are tolerable given the constrained environment of mobile. Thanks for journeying with me on my insane screed.