Friday, July 3, 2009

An Exercise in Blatant Bias

I came across an interesting blog post today that purports to be a comparison of Android and iPhone development. And it is a comparison. While the author makes absolutely no claim that he is unbiased, a more fitting and less misleading title would have been A Comparison of iPhone and Android Development by Somebody Who Really, Really, Really, Really Loves Java and Doesn't Want To Be Bothered Actually Learning How to Use the Language and Tools Used in iPhone Development. Okay, I admit that that would be kind of an unwieldy title, but I can imagine a lot of people coming to this blog entry and getting a skewed view of things, so I want to provide a counter-opinion. I don't want to get into a pissing match, but some of the accusations in this posting are indefensibly wrong and tell us more about the author than the things he is comparing.

Let me put up front that I know some people will interpret my response as an attempt to say that Xcode is "better" than other IDEs. That's absolutely not what I'm trying to say. "Better" is a subjective matter. My goal is simply to counter the notion put forward in this blog post that Xcode is "shockingly bad" or that Xcode "takes away from the flow of a developer". It does take away from the flow of a developer who insists on trying to use it as if it was Eclipse or Visual Studio, but that's a flaw in the developer, not the in IDE.

But just like the original posting, this is a biased post based on my own tastes and likes, but unlike the original author, I actually have a comparable amount of experience with both of the things I'm comparing.

I think it was Jeff Atwood who said "the only intuitive interface is the nipple", and that couldn't be more true. Everything we're used to doing in computer programs - the entire paradigm is learned. That's completely true for IDEs and programming languages as well. We learn to use them, and many of us coders spend so much time in our IDE that they become second nature for us to the point where we see the way we work as natural.

One of the most common complaints I see from new iPhone and Mac developers , especially those coming from Visual Studio or Eclipse (like the author of the post linked above), is that they hate Xcode because it's missing this or that feature or it "feels dated". Only the most obstinate and stuck-in-their-ways developers continue to make those claims after working with it full-time for a year or more, however, because the problem isn't with Xcode, the problem is they were trying to do things in Xcode the way they were used to doing them in some other IDE. They were trying to bring to bear all their learned knowledge about how to program in Java or C# or Visual Basic in another IDE with different conventions than are used in coding Objective-C using Xcode.

Now, I'm not trying to say that Xcode is perfect. No IDE is perfect, and they are constantly borrowing ideas from each other. One of Xcode's virtues, in my mind, is that they haven't adopted the kitchen sink approach of trying to implement any feature that anybody thinks up. They've historically had relatively a small, focused user base, and the Xcode team has created a scalpel, not a chainsaw. Xcode is written by some really smart engineers who have to use it every day for writing C, Objective-C, and C++. They aren't using it to write VB or C# and only rarely to write Java. They have different needs and different priorities than the Eclipse team or the Visual Studio team. But to claim that Xcode is "lacking" or "bad" does those developers a grave disservice. It does not try to be everything to everyone, that is true, but it is nonetheless a great IDE for the types of development that its user base does on a daily basis.

Here's the thing. If you are constantly missing some feature from Eclipse of Visual Studio, there's a really, really good chance you are working against the grain, trying to do something based on things you think you know from another language or application framework, or that you simply haven't discovered some piece of functionality in Xcode.

David Green, the author of this blog post, make the claim that Xcode (which he has been working with for "a few months") impedes developer productivity and that it is therefore "inferior" to Eclipse, a program he's worked with day-in and day-out for twelve years. Yes, that sounds like a fair basis for comparison. "This thing I just started using isn't anywhere near as good as this thing I've been using for years and know inside and out."

You can get some insight into the thought process behind this claim from this quote:

Java is a no-brainer. I have to say that it’s nice not to have to learn a new language to target mobile. Existing skillsets don’t come easy — so reuse of expertise is worth a lot.

Now let me put out there that I have worked with Java since about 1997, which would be, what, say... twelve years? It was my bread and butter for close to ten of those years. I've also got about ten years experience with Cocoa, Objective-C and Xcode(if you include its predecessor Project Builder). So, I have some basis for comparison and let me state that my opinion of the languages and the IDE is almost exactly the opposite of Mr. Green's when it comes to mobile development of GUI applications.

For starters, Java is absolutely not a no-brainer. In fact, Java is a really, really poor choice for embedded development. Oh, I know Java has been pushed as a great choice for embedded devices for years, but it's just not.

Mobile devices are constrained resource devices. The overhead for Java runtime's memory and processor overhead is non-trivial on such a device. And "existing skillsets" may not come easy, but reuse of expertise is no good if the cost for doing so is to make poor choices. You've certainly heard the cliché "if your only tool is a hammer, every problem looks like a nail"? Well, re-read the quote above and tell me that it's not simply a restatement of that cliché as an axiom. He's stating "Java is better because I know it better", nothing more. I know both languages, and Java is a better choice for many tasks, but there's really no way you can claim that it's better for writing a GUI application on an embedded device. Or, for that matter, for writing any GUI application period.

On the other hand, Objective-C is a great choice for writing GUI applications for an embedded device. It has a runtime that provides a lot of dynamic functionality with considerably less overhead. Objective-C has far better introspection than Java and greater flexibility in terms of passing objects of different types through a responder chain without filling up your code with typecasts or constant use of godawful generics (a much-lauded hack to get around a fundamental flaw with strongly-typed static languages like Java when it comes to designing GUI applications).

Some other gems from this blog post:

One thing that really became clear to me is that Objective-C, though it may have been visionary for its time, is really a language of the '80s. Certain issues such as split header and implementation files and violation of DRY are really time-wasters, and not small ones at that.

I honestly had the opposite complaint about Java. I hated that there was only a single file per class. I hated that Java deprived me of the ability to do lots of cool things by separating out the implementation from what is advertised to other classes. I hated, for example, having to use static final variables and hated having to incur the overhead of a method call for tiny bits of functionality that could have been expressed in a precompiler macro or static inline function in another language. That's not to say that Java's approach is bad, just to say that just because it was thought of later doesn't make it inherently better. Its saves a little typing and a small amount of project clutter, but it comes at a price. Personally, I prefer having more flexibility and a few more files in my project.

Split header and implementation files provide extra functionality and the cost is relatively trivial. Navigating between header and implementation files can be accomplished with a configurable key binding. I switch back and forth regularly between header and implementation files. The key command becomes second nature after a little while and it becomes completely a non-issue. I can't even see how this would be an issue worth mentioning if you had spent a few minutes reading about Xcode's key bindings.

As far as DRY, must I really do 5 things to declare a property??

ZOMG! I have to release memory! And type in more than one place! Run for the hills!

For the record, I can implement a single property in about 20 seconds using Xcode codesense and key bindings to navigate between the header and implementation files. For those who don't type as fast, check out the excellent Accessorizer. Personally, I can't create Java getters and setters in Java using Eclipse noticeably faster.

Another thing to realize is that Objective-C has a garbage collector, and it's quite a good one at this point, but Apple has intentionally chosen not to support it on the iPhone. This isn't about a shortcoming in the language, it's about a conscious decision made to provide a better user experience. Forcing developers to take responsibility for memory means that well-written applications will be more efficient and use less memory. Sure, there's a risk of memory leaks, but there are ways to track those down, and garbage collection comes with a price. On a device like a mobile phone, that is a non-trivial price even if the garbage collector is pristine and doesn't have any memory leaks itself.

Java has a similar problem with properties, though not quite so bad — and the IDE helps you write your getter/setter.

Gosh, it's too bad we don't have anything like that in Xcode. It'd be nice if we had maybe a Design menu, or maybe some text macros for Objective-C. Or at very least, an extensible scripting architecture with provided scripts to help us write our accessors and mutators. It would be even better if we had a persistence framework that completely obviated the need for data model classes at all.

And for those who didn't catch on to my sarcasm in that last paragraph, we do have all of those with Xcode. There is a design menu with tools that help you design data model classes. Under the edit menu, there is menu item called "Insert Text Macro", with several common macros for all the languages Xcode supports, and there's also an Applescript menu with such gems as "Place Accessor Defs on Clipboard".

But, in the vast majority of situations, you don't need to actually write your setters and getters. I don't care if your IDE creates them for you, 95% of the time, those are still code clutter. I'd much rather have a property with a synthesize statement and possibly a release call than tons of cruft in my code.

We also have Core Data, which lets you design data model classes visually without ever creating an Objective-C class. Or you can create a custom subclass, but you only need to put in your custom functionality - no setters or getters unless they do something non-standard.

Another annoyance of Objective-C is the patterns that must be followed: implementing correct init and dealloc methods is non-trivial. @synthesized getters and setters for properties with retain should not be called in these methods. So many conventions and rules to remember!

Let me translate this: "Objective-C annoys me because it doesn't use the same patterns that Java uses and it is therefore bad". Implementing correct init and dealloc methods is non-trivial? How in the world could you possibly say that? If you understand the memory management contract (a whopping four whole rules), it's both trivial and intuitive. It only seems confusing if you haven't bothered to learn one of the fundamental aspects of the language you're using, and if you haven't, well, that's really not Xcode's fault, it's yours.

Objective-C’s imports and forward-declarations (@class) are a pain

What he calls a "pain", I call "more flexible". Forward declarations and header imports are more powerful and flexible than java's import mechanism, and if you understand what they are doing, they're really not difficult or time consuming.

With iPhone on the other hand, finding the functionality that I needed was painful. Classes and methods are poorly organized

Another translation: I kept looking for functionality as if I was working in Java and didn't find things where I expected them. Personally, I find Xcode's documentation browser (especially the new one coming in Xcode 3.2 under Snow Leopard) to be more intuitive and feel like it's designed perfectly for the needs of a knowledgeable Cocoa Touch programmer. It's not surprising that it's not designed to meet the expectations of a programmer learned from using another language, other frameworks, and a different IDE.

And here are some more complaints about the "shockingly bad" Xcode:

A decent window/editor management system. XCode and it’s associated tools (debugger) like to open lots of windows. Want to open a file? How about a new window for you! Very quickly I found myself in open-window-hell. The operating system’s window management is designed for managing multiple applications, not multiple editors within an IDE. It’s simply not capable of providing management of editors in an environment as sophisticated as an IDE.

Good point. It's just too bad there's no preference for changing to a single-window, or limited-window layout, huh? Oh, wait… there is, isn't there?

A project tree view that sorts files alphabetically. Really!

Oh, god, no. Please no. You're trying to use the project tree to do the detail panel's job. Just click the node of the tree you want, then in the detail panel, sort the part of the tree you've selected however you want, alphabetically, by code size, whatever. This gives you all the power of Eclipse's horrible project tree, but let's you only work with the section of the hierarchy you are currently interested in. Believe me, this is not a shortcoming in Xcode, this is a shortcoming in the way you're working.

iPhone app developers are given a pretty good UI builder. It does a great job of showing the UI as it will actually appear. It’s flexible and can model some pretty sophisticated UIs, so I was impressed. I found that using it was a little tricky — I had to read the documentation two or three times before I could really figure out how to use it properly.

Oh no - he had to read the documentation! No developer should ever have to do that. Anyone who damns Interface Builder with faint praise like this doesn't fully understand it and thinks it's just a form builder like they've used in Eclipse or VS.

Okay, I'm done. Now I'm being a little rough on the guy. He's giving an honest opinion thinking he's helping others, and that should be lauded. The problem is he's making claims that are not just a little biased, they're outright unsupportable. Calling Xcode "shockingly bad" because you haven't taken the time to learn how it works is just ignorant.

Okay, maybe a few more quotes, because there are so many good ones.

We may see a shake-up in the mobile market, with at least 18 new Android handsets being released this year. Until that happens, iPhone will remain a market leader and developers will have to put up with XCode and Objective-C.

The iPhone "will remain a market leader" until "18 new Android handsets" are released? Did you seriously write that with a straight face? You honestly think it's the number of handsets that is holding Android back? Seriously?

But at least he finished off with a great quote:

Sure, the iPhone is great — but can you install a new Linux kernel?

And the answer is, actually, yes. But who in their right mind would want to? Linux zealotry notwithstanding, the Mach kernel is better, and truth be told, most people - even most developers - don't want to waste time having to compile and install new kernels anyway.

No comments:

Post a Comment