“Originally Written in…” vs. Code Generation

My assertion that the iPhone license phrase “Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine” can only mean zero code generation has been questioned. Here’s why I stand by that assessment (and consider the clause beyond the pale).

Let me point out that the common-sense reading of that clause is straightforward. The word “originally” clearly implies that writing this:


UIView.BeginAnimations("");
UIView.SetAnimationTransition(UIViewAnimationTransition.FlipFromLeft, this.Superview, true);
UIView.SetAnimationCurve(UIViewAnimationCurve.EaseInOut);
UIView.SetAnimationDuration(1.0);

and transforming it into:


[UIView beginAnimations: nil context:context];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView: [self superView] cache: YES];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration: 1.0]

is forbidden. To take it to the extreme, can you imagine betting your company on convincing a jury that writing the first (which is C# and MonoTouch) and generating the second means it was “originally written in Objective C”? If so, you have some hard lessons about the legal system to learn.

I should point out that even though this code is clearly very similar, there are some slight differences, such as C#’s enumerated values UIViewAnimationTransition.FlipFromLeft as opposed to Objective C’s constant value UIViewAnimationTransitionFlipFromLeft. The . makes a difference in the parse tree and in the programmer’s mind — a small one, but a helpful one.

I should also point out that today MonoTouch does not generate the Objective C 2nd listing. It probably generates something like:

{
.entrypoint
.maxstack 8
L_0000: nop
L_0001: ldstr ""
L_0006: call void Foo.UIView::BeginAnimations(string)
L_000b: nop
L_000c: ldc.i4.0
L_000d: ldsfld class Foo.UIView Foo.UIView::Superview
L_0012: ldc.i4.1
L_0013: call void Foo.UIView::SetAnimationTransition(valuetype Foo.UIViewAnimationTransition, class Foo.UIView, bool)
L_0018: nop
L_0019: ldc.i4.0
L_001a: call void Foo.UIView::SetAnimationCurve(valuetype Foo.UIViewAnimationCurve)
L_001f: nop
L_0020: ldc.r8 1
L_0029: call void Foo.UIView::SetAnimationDuration(float64)
L_002e: nop
L_002f: ret
}

which is “Common Intermediate Language.” The .NET Virtual Machine loads CIL files directly, while MonoTouch generates at compile time native code, which  which is an exercise left for the interested student (and, while hardly trivial, is a mechanical process that can be reviewed for efficiency, improved, etc.). (The “nop”s, by the way, are for breakpoints and wouldn’t be generated in a release build).

Generating two levels of low-level code (C# -> CIL -> Native Code) may seem to be the source of inefficiencies, but generating for an intermediate assembly language is very common with modern compilers. Code generation may be a source of inefficiencies or it may be a place of optimization — that’s dependent on the skill of the compiler writers.

The reason why it’s absurd to forbid native code compilers but allow Objective C code generation is that there is no difference between generating assembly language and generating C. If you can write an IL->Native Code compiler, of course you can write a IL->C compiler. So were code generation legal, a potential strategy for other alternative language vendors would be to do FooLanguage -> Foo IL -> C (”OK, lawyers, as you can see, we are simply generating C code”) -> Apple Approved C Compiler -> Native. Kafka-esque absurdity, but perfectly cromulent. Indeed, I strongly suspect that all of the alternative language vendors are preparing just such a tactic as “Plan B” or “Plan C” in case Apple relents on the word “originally.”

The Double-Edged Sword

Why should Apple allow alternative code generation? They fear inefficiencies, they cannot control the efficiency of code generation, therefore it is logical to forbid code generation. Why is that unreasonable?

The reason is that if you forbid code generation, you forbid huge swaths of good programming techniques. Rather than go on about lex and yacc and report generators and screen managers, though, we have the delightful “The Elements” iPad app to make the point. Don’t take it from me that code generation is good, read the article:

Even the amazing animation synchronized to Tom Lehrer’s iconic song “The Elements”, which plays the first time you open the e-book, was generated entirely by a Mathematica program.

QED.

5 Comments

  1. I think you hit the nail on the head here. And however absurd it would be to do:

    FooLanguage -> Foo IL -> C -> Apple Approved C Compiler -> Native

    I think the 3rd party vendors should do it to prove a point, perhaps even a vendor (like Adobe) who has expensive lawyers and could take it to court if necessary.

    Whenever businessmen limit developers with arbitrary limitations using various legal contracts (like Terms of Use and the like), it always turns into a game of cat and mouse. The business types almost never catch all the mice, because the mice are always a little more clever.

  2. [...] Originally written in vs. code generation. I agree and he makes some of the points I did (although I disagree over “original language” being quite as narrow as he does – to me programming with Yacc is akin to using a C template with my text editor). [...]

  3. Allen Bauer says:

    I’ve been trying to make this same exact point, but only without the “code-generation” angle (http://bit.ly/bgOMgb). What about *any* library code code that you call that in-turn calls an Apple API? Isn’t that the same as using an “intermediary translation or compatibility layer” in the strictest sense? This would mean that even “by-the-book” XCode developers have a very real risk of running afoul of Apple’s agreement! What if one were to develop their own set of abstraction libraries that are used among many iPhone applications? Then, what if your success on the iPhone were going so well, that you decided to port your application (You originally used the “blessed” C or C++ language for your iPhone/iPad app) along with your nice abstraction libraries to, say, Android or WP7. Then Apple caught wind of your application on those non-Apple platforms and began an inquiry. They *could* use this clause to say that you’ve violated their terms of use because you’re using even your own privately developed “intermediary translation or compatibility layer”!

    The interesting thing is that no-one can even claim this is hyperbole (oh, I guess they still can, and maybe it is), given Apple’s willingness to quickly pull the litigation trigger.

  4. I don’t think the issue is code generation, but meta-platforms since they sit on top of multiple lower-level platforms and don’t take fill advantage of the native platform. If you look at John Gruber’s article (http://daringfireball.net/2010/04/why_apple_changed_section_331) on this, there is a good example at the end of the article on Amazon’s Kindle client for iPhone OS and Mac OS X. The actual iPhone OS (including iPad) app is excellent. The Mac Kindle app “is a turn that doesn’t look, feel, or behave like a real Mac app.” It was produced using a cross-platform Qt toolkit. They are trying to protect the quality of iPhone Apps.

    This comment (http://news.ycombinator.com/item?id=1250946) by raganwald (and the follow-up comment by tzs) seems to be a plausible reason why Apple wants to protect its brand.

    I don’t think Objective-C developers are against code generators. mogenerator (http://github.com/rentzsch/mogenerator) is an example of Objective-C code generation for Core Data.

  5. Daniel Cheng says:

    Qt have a simple method for adopting those ok-button-on-right kind of setting. It’s Kindle/Mac’s developer ignoring them, not the framework’s limit.