The Absurdity of Apple’s New iPhone Restrictions

These are the new clauses:

  • Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine

I’m tempted to say that the clause is absurd and to talk about metaprogramming with C++ templates or JavaScript prototypes, but the fact is that it’s perfectly cromulent. The common-sense reading of this is straightforward: no code generation.

The constraint, however, is utterly illogical. Good programmers don’t write all their code: they write code that generates the boring stuff. This is probably the type of thing that was used in “The Elements” — automatic generation of the .xib files, asset directories and resources, and generation of  Objective C animation code (the video explicitly says that animations were generated). Forbidding Domain-Specific Languages (and the parser generators that help build them) flies in the face of the very people you want to attract to your platform.

C, C++, and Objective-C were all developed more than 20 years ago and all, on the iPhone, require explicit memory management — the most error-prone detail in software development. You know how you tell when an app for the iPhone was written in MonoTouch? It doesn’t leak memory.

You can play the semantic game of “Well, since a C program is not ‘originally written’ until it’s been compiled, if we use a higher-level language to generate C and compile that then we are within the letter of the clause.” But try getting that past your company’s lawyer when you’re trying to get the go-ahead for a business-critical application.

Apple may feel that they are in such a strong position in the market that they can dictate that outsiders use the same techniques to write software that are used internally at Apple. But that’s not how programming works: it is a continually evolving melange of abstractions, techniques, and tools. It has to be allowed to vary at the individual, team, and industry level if it is to progress. I’ve worked on C and C++ at the level of standards compliance suites, I’ve done my fair share of JavaScript, and I can stumble along in Objective C. But personally, when it comes to the iPhone, my language choice is C#: it’s significantly higher-level than C or C++, it’s a little more terse and cleaner than Objective C, it has certain language features that are undoubtedly ahead of Objective C (LINQ), and it provides a better type system. That is just one person’s opinion and Apple can certainly afford to ignore me, but if they think can ignore the last two decades of advancement in the programming marketplace, they’re over-confident.

Those with a sense of historic irony might observe that Objective C for many years existed only as a code-generating preprocessor and that a similarly restrictive clause could easily have killed its development and prevented NeXT from creating the software development toolchain that Apple is using today.

  • Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited

This clause makes more logical sense. Mobile development is still a resource-constrained environment. While memory, storage, and processing speed are beyond the dreams of yesterday’s hobbyists, processor use drains the battery and that is a very big deal indeed. Desktop developers today are generally free to live in whatever abstract model they choose: you want to live in a world where everything is an object, a mathematical function, or an S-Expression? Go for it! There’s enough power under the hood to make your program “fast enough.”

Not in mobile development. For instance, reading the color of a single pixel on the iPhone is kind of a big deal: you have to allocate a new data buffer, draw into it,and then read the raw bytes at the calculated offset. In Erica Sadun’s iPhone Developers Cookbook, she dedicates about 50 lines of Objective C code to demonstrate the technique. In MonoTouch, I did it in 45 lines of C# code. Of course, once you’ve written the function you can call it forever-more with a single line, but you probably will remember that your function has implications in terms of memory and computation resources. Unless you’re a very bad programmer, you probably would ensure that you don’t create and destroy that buffer every time you want to read or set a pixel.

On the other hand, a Flash developer has the functions pre-written for them: BitmapData.getPixel() and BitmapData.setPixel(). And they probably don’t think about those functions having significant overhead — part of the reason people use Flash is because it’s abstracted away just such things. So how can a cross-compiler for Flash deal with the line myBitmapData.getPixel()? There are three choices:

  1. Treat it as a single programmatic intention — allocate the buffer, read the data, and deallocate the buffer.
  2. Treat it as two intentions — (a) “allocate a buffer for further use” and (b) “read the pixel.” Keep the buffer around for further use.
  3. Divine the programmer’s intent — if they really only intend to do this once then treat it atomically, if they are going to be doing a lot of pixel manipulation, keep the buffer around

All three choices have problems:  if you choose 1, but the program does do lots of manipulation, you destroy performance. If you choose 2, you consume memory at a potentially prodigious rate (and even so, you have to write a garbage collector). If you choose 3, you’re going to have to wait until researchers develop the “do what I mean” compiler switch, which is still a research project.

That’s Apple’s legitimate concern with “intermediary translation or compatibility layers”: the efficiency and restrictiveness of such layers. MonoTouch is quite efficient, maybe some others won’t be. One thing that MonoTouch does (garbage collection), it does well — perhaps some other implementations won’t. MonoTouch makes it very easy to “drop down” to unsafe code or to link in new CocoaTouch APIs, that clearly won’t be the case with some others.

So what if Apple kept the clause forbidding translation and compatibility but dropped the first one? So that I  write my flow-of-control using whatever language I choose, but I don’t write my own “translation or compatibility layer”? That seems reasonable until you realize that there’s no difference between a translation layer and a 3rd-party library call. Functions are translation layers: the difference is solely one of intent and extent. And even as far as “extent” goes,  C++ template metaprogramming, Boost, and smart pointers have lots of consequences that absolutely reach throughout the application. What if I wanted to use a port of libgc? Legal or not?

In one day, Apple has damaged projects as diverse and good for the iPhone as MonoTouch, Unity3D, and Appcelerator. They’ve sowed Fear, Uncertainty, and Doubt about projects like RunRev and Flash Packager for iPhone. And they’ve done it with 2 lines of technical absurdity. One hopes that they can come to an understanding with 3rd parties that helps ensure the performance and consistency of applications written for CocoaTouch without draconian restrictions against fundamental programming techniques.

If not, one hopes they go fuck themselves.