September 7, 2008.
I spent most of the day getting to know Cappuccino and developing a simple but slightly interesting application with it. First I'll quickly skim over the application I developed, and then I'll discuss my experience developing with Cappuccino. I put together Mahou, using Vik Singh's adaptation of the Yahoo! Boss Mashup Framework to Google App Engine and Cappuccino to create a somewhat featureful image search.
There are two particularly interesting features in Mahou:
If you scroll down (using the mouse wheel), as you get near the end of the results, additional results will be retrieved and appended to the existing results.
If you click on an image it will open up a small window (not a browser window, but a virtual window within the frame) with the image's meta data. If you click on the image's title (the white text), it will open the fullsize image in the browser.
Although it has a few rough spots, its a fairly useful image search, and the automatic loading of additional images (while retaining the previous images as well) makes it quicker to browse (and backtrack between pages of) images than in conventional search engines.
Anyway, on to the content.
You rarely hack in Cocoa development. Instead, you software develop like the good little software developer you are. This same sense of grinding out code can be felt in Objective-J development.
That isn't to say that its a bad experience, but programming in Objective-? rarely feels like a matter of ingenuity, instead it is a matter of correctly matching premade patterns to problems. Sometimes you jiggle the pattern a bit to make it fit correctly, but its rare to get particularly meta or to pull new tricks out of your bag/
At the same time, there are a few places in Cocoa--and in Cappuccino as well--where there is no premade solution, and improvising new solutions tends to involve all manner of trickery and disregard for propriety. Essentially, you meticulously design the first 97% of the application, and then beat the hell out of it for the final three percent until it works exactly how you want.
Another similarity in the Objective-? languages is the long but not-particularly steep learning curve. Early on, after every Cocoa program I would write I would figure out how I had poorly designed it to take advantage of all the Cocoa goodness. Then you throw your application out and redesign it, and the code is half as long, cleaner, and more intuitive.
After finishing Mahou, I had the same damn feeling: I could rewrite it in half the time, with a more extensible design, and less hackery. This is the frustration of using a heavy framework, which are inherently heavily opinionated, and will subtly punish you for making the wrong choices until you learn the framework well enough to anticipate its quirks.
Cappuccino supports well segmented and reusable code with support for code importing, and also its ease of subclassing widgets and classes. While writing Mahou I put together a
WLURLLabel class which subclassed
CPTextField to allow specifying a URL to open when clicked.
I also subclassed
CPTextField to support displaying placeholder text when there isn't any content in a textfield and it isn't selected. Both of these things are easy enough to do, but once you get into the habit you can save a considerable amount of time by making the extra five minute effort to create reusable classes.
In Cocoa, subclassing and delegates are the two solutions to all customized logic. The first step of every solution is figuring out the class to subclass--not the function to write or library to create--and you end up reusing a tremendous amount of code with that mentality.
Its fun. Learning new things is always fun, right?
The most difficult issue I ran into with Cappuccino development is that it explicitly doesn't play well with html and css. This is one of its purported strengths, but is also quite awkward when trying to--for example--display html retrieved from another web service.
Even displaying a small attribution link at the bottom of the screen involved subclassing a
CPTextField to open a window with a specific URL when clicked.
That said, this issue can be alleviated by developing a handful of new UI widgets. Specifically a textfield that rendered html and css would be excellent. Something akin to
NSAttributedString in Cocoa development. Actually, I suppose it's most similar to the WebKit view, which would be a slightly ironic addition.
A limited debugging toolkit. I developed with WebKit, and had my fair share of generic error messages from Cappuccino. Particularly ones letting me know that it can't parse something somewhere, or that there was a syntax error. Somewhere. I imagine some people will get pretty caustic while complaining about this, and I agree that it's fair from perfect. But it's workable as is, and some automated acceptance testing (something like what Peter Burns discussed in this blog post a while back) would make it much easier to detect problems as they arise.
In all fairness, the current iteration of my app is not an application that plays particularly well to Cappuccino's strengths, but Cappuccino helped facilitate some fun functionality, and when I have time to implement the entire Mahou vision, I believe it'll be a slightly more worthy project.