June 9, 2009

Java on the iPhone?

Is it possible? Can you run Java on the iPhone? Well, no, at least not at this time. Perhaps never, due to the rules Apple have in place disallowing interpreted languages from operating on the iPhone. This is a real shame because quite frankly, Objective-C is not an easy language to work with. And since it is the only language we have to work on for the iPhone, our hands are extremely tied. (One could argue that Objective-C++ allows C++, but in my opinion, this is a much uglier situation than just coding in Objective-C.) I am a former Java coder. Java may not be the most enabling language (think Python or Groovy), but the grammar is clean and simple and arguments about Java being too verbose are lost when comparing it to Objective-C. I like the power of the Cocoa-Touch run-time environment. However, the vehicle to get to that power (Objective-C) is a nightmare. Objective-C is clunky, verbose, inconsistent, and archaic. It is loosely based on SmallTalk, a relatively unused language in the industry. There's a reason for that. To me, doing anything in Objective-C is painful. Take the mundane task of creating a dictionary and adding a key/value pair to it. In Objective-C, it would look something like this:
NSMutableDictionary* dict;
dict = [[NSMutableDictionary alloc] initWithCapacity:3];
[dict addObject:@"Some data" forKey:@"key"];
I have many issues with this code:
  1. Why does Objective-C insist of dealing with pointers? Since you can't instantiate an object on the stack like you can in C++, having to specify the "*" character is superfluous. The fact that these are pointers should be hidden, as they are in Java. In the rare cases you need to actually refer to the class name and not the pointer, use some other syntax.
  2. The [object method] call syntax is really whacked. My opinion is that this is not an intuitive syntax, nor is it easy to read or write. It is nearly impossible to visually parse, especially with nested calls.
  3. Semicolons? Come on. There is no reason why a language parser cannot figure out the end of a statement. These are artifacts from the days of Pascal and C when they didn't know better. Tcl, Groovy, Python, Ruby, JavaScript, et al prove that semicolons are extraneous syntax fluff. It's a shame that most programmers accept them as the de facto for languages, when in fact they indicate a poorly designed grammar.
  4. Look how verbose and awkward it is to add a single element to the dictionary. I get carpal tunnel syndrome just reading Objective-C code. Objective-C forces you to use positional arguments and named arguments at the same time. If it wasn't for Xcode helping to write Objective-C, it would be a horrid language to type.
  5. I miss the commas between arguments. These are not needless syntactical fluff, as the "*" and ";" characters are. Commas help visually separate arguments. Without them, the args all blend together and make it hard to read.
  6. What's with the @ characters in front of strings? I understand they are trying to differentiate between C-style string constants and NSString constants, but why give the simpler syntax to C? I have never used a C-style string in an Objective-C program. I would have made "string" automatically be an NSString constant, and if you want a dinosaur C-style string, then use @"string".
Okay, that's six major complaints in just 3 lines of code. This doesn't even go into my other major beefs, such as separate files for class definitions and declarations, the @property/@synthesize malarkey, the use of "@end" as a block terminator, etc. Java can do the same task a little better and with a much cleaner syntax:
HashMap dict;
dict = new HashMap(3);
dict.put("key", "Some data");
It still has those dumb semicolons, but this is still a major improvement. I know all this bitching and moaning doesn't accomplish much. Objective-C is the tool we have to work with on iPhone development. There is nothing you can do about it. Adapt and move on. And adapt I did. I tolerated Objective-C's quirks for months. But I always thought about how much easier and productive it would all be in another language. I couldn't let it go. Then I came up with an idea: What if I just used the syntax of Java, and not the Java run-time environment? What if I wrote a translator, one that translated Java code into Objective-C? How hard would it be? I think this is quite possible, as long as you lay down a few ground rules. I have accumulated a fair number of these ground rules and revelations from tinkering with prototypes. The above Objective-C code could look like this in Java syntax:
NSMutableDictionary dict;
dict = NSMutableDictionary.alloc().initWithCapacity(3);
dict.addObject("Some data", forKey="key");
Notice a few things different? But some things are the same. The most important aspect of this is how we pass parameters. The first parameter is passed like normal, but all subsequent parameters are passed as if they are keyword parameters (ala Python). Although this is parseable Java syntax, it wouldn't compile. But it can be translated to Objective-C very easily. The whole idea is boiled down to this: In Xcode, write your iPhone software using Java syntax. Calls to the Objective-C runtime and Cocoa Touch are pretty much the same. There are no separate .h and .m files, just .java files. Then run the Java code through a translator that generates the Objective-C .h and .m files, which then get compiled. Xcode provides the ability to run preprocess steps in a build operation. So you could set up your builds to translate your Java source to Objective-C, then the normal build process would take it from there. Another benefit is that Xcode will think you're typing in Java code (because you are, sort of), so you will get all the nice keyword highlighting and other editor shortcuts. This idea is not limited to Java. Although Python does not have static typing, the ShedSkin project proves that you can translate Python to C++, so it is likely possible to also translate Python to Objective C. But this situation is not perfect. For starters, any compile errors in the Objective-C source will have to be corrected in the original Java source. Unless you want to abandon your original source, you should never edit the generated Objective-C source code. Runtime debugging will have to be in Objective-C. For some, these problems may be enough to warrant this as an exercise in futility. I will reserve judgment until trying it in production software rather than just in tinkering. This introduction is just to whet your appetite of the possibilities. This project I call "Typhoon". Typhoon will comprise the set of language translators and any additional run-time support necessary. In future articles, I will describe some of the ideas of Typhoon. I invite readers to leave comments on what you think about this idea. Is it worth pursuing? Or is it an idiotic waste of time? Please let me know.

11 comments:

  1. i think it's futile - you hit on the debugging issue, which i think is a deal breaker. also xcode will helpfully fill in all the parameters on long method names, and it will tell you what the possible completions are so you can know ahead of time if the method you're looking for even exists.

    i really don't find objective-c as bad as you make it out. the java code looks only ever so slightly better. not a big enough improvement to warrant all the steps backward you'll be taking.

    good luck with it!

    ReplyDelete
  2. I am a former Java coder myself, but I stopped upgrading after the introduction of the typing system; up to 1.2 Java syntax was really neat.

    In my view, Objective-C isn't nearly as bad. True, some things need getting used to, but I actually prefer the square brackets to the dot notation for method calls. You lose a lot of round brackets as compensation. As for some of the syntax: it's a superset of C, hence the @"" for NSString constants. You can always do better when starting fresh without having to care for backwards compatibility. That's one reason why Java's syntax is now so bloated...

    The only thing that really gets me about Objective-C are the header files, really. I thought Java showed that we can do without them, and they're a pain.

    One solution might be to write your own run-time virtual machine (in Objective-C), and then use your own scripting language. Surely Apple can't object to that?

    ReplyDelete
  3. I realise that it is not exactly what you are aiming for, but an alternative way of writing apps in Java for the iPhone is GWT + PhoneGap.

    ReplyDelete
  4. Hm, PhoneGap looks interesting, but it's not my cup of tea. Thanks for the reference, though.

    ReplyDelete
  5. 1) Objective-C has pointers because it's meant to be used to develop native apps that often need to manage the memory in a more efficient way than a garbage collector. Java doesn't have that problem: it's GC all the way.

    2) Yes, the [object method] syntax is a bit weird at first but it has its advantages too: you can select the entire block between the brackets with a simple key-command (traditionally cmd-B) and copy it somewhere else. Besides, is it really more whacked than object->method() which contains 4 special characters instead of 2 for [object method]?

    3) Semi-colons allow you to split an instruction over several lines.

    4) Naming arguments is the first thing that makes C++ programmers (and apparently Java programmers too) develop an indigestion because they find Obj-C so verbose. I felt the same at first, but after working a few weeks on a large code-base that you aren't familiar with, trust me, you will learn to loooove this syntax and wonder why it has not been adopted in other languages.

    5) If you have a comma between arguments, do you also want one between the object and the method? The result would look like [object, method] or [object, method:param1, name2:param2]. Now, that's really verbose. It's best to learn to separate the arguments in a visually pleasant way, over several lines if necessary.

    6) Obj-C is often used in conjunction with C or C++ (source code, libraries, frameworks) and, of course, it is very useful to preserve the same syntax for static strings.

    Overall I think your irritation with the language comes from a lack of familiarity with it. I worked on very large code-bases in C++ and Obj-C. In my opinion, both have their benefits but when you are developing in the higher levels of the app, you quickly learn to appreciate Obj-C. It fits much better into the paradigm of "write once, read many".

    ReplyDelete
  6. @Pierre: Thanks for the comments. I think it really boils down to ascetics. I have been programming in Obj-C for 8 months and it still hasn't found a place in my heart. I tolerate only because Xcode adds many nice features for using the language. Without Xcode, Obj-C programming would be a tedious endeavor.

    Certainly there will people who love Obj-C and some who hate it. You can't please everyone, which is why I think it is rather short-sighted for Apple to expect everyone to program in one language. I wish there were more options.

    ReplyDelete
  7. I think apple will have to re-evaluate it's ObjC sour grapes offering as android (and other java dev enabled phones) becomes a stronger contender in the market place. It's plain stupid not to offer developers a common alternative now.

    ReplyDelete
  8. oh, and I would use the java-to-xcode pre-compiler in a heartbeat, regardless of the debugging challenges.

    ReplyDelete
  9. Your three lines can be easily replaced with one:

    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObject:@"data" forKey:@"key"];

    Unless you are planning on inserting a large (known) number of objects into the dictionary, there's no need to use "initWithCapacity" at all.

    You can also create an empty dictionary simply with:

    NSMutableDictionary *dict = [NSMutableDictionary dictionary];

    and add items as needed. Note both of these methods return autoreleased objects.

    ReplyDelete
  10. True, but who creates a dictionary and places only one element in it? The code snippet simply demonstrates the verbosity of typical operations.

    ReplyDelete
  11. you raised very good issues. seems you have something great in your mind, just hit that. java on iphone is a great thing to do

    ReplyDelete