Writing Mahou; a Cappuccino Image Search
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.
Developing with Cappuccino
I have spent a considerable amount of time developing in both Objective-C and in JavaScript, and Cappuccino's feel leans very strongly towards the former. It's not just the syntax, but Cappuccino has captured the feeling of Cocoa development as well.
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.
Ah well.
Advantages of Cappuccino Development
Developing an application with Cappuccino won't always be faster than developing a comparable application in another JavaScript framework, but it'll be hard to beat Cappuccino's unit-of-quality-per-unit-of-time ratio. Because the framework makes so many choices for you, and provides high quality widgets to grow familiarity with, many vectors of failure fade away. Particularly the perils of cross-browser development are largely erased with Cappuccino. That is a big win.
You write web applications in a single unified language, instead of a medley of html/css/JavaScript/a-server-side-language. This decreases the minutiae to memorize. In particular, the pointless difficulty of writing cross-browser CSS is removed. Now, I tend to enjoy getting to write in four (three and a quarter, really, since we're discussing html) languages, but I think there is merit to this approach. Regardless of which most developers decide upon, having both options is better than having only one or the other.
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 subclassedCPTextField
to allow specifying a URL to open when clicked. I also subclassedCPTextField
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. Although you can subclass and extend in other JavaScript libraries, Cappuccino's being modeled after Cocoa puts it in rarified air as far as the versatility and ease of subclassing to customize behavior. 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?
Problems with Cappuccino Development
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 toNSAttributedString
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.
There is a limited amount of documentation and tutorials thus far. It was released a day ago, so that isn't particularly surprising, but you have to be willing to browse through the docs. The overall patterns and documentation style of Cappuccino is sufficiently Cocoa-like that Cocoa developers will be ready to dive right in, but someone more from the JavaScript side of things might have a bit of trouble getting started right away.
Ending Thoughts
Although I was occasionally stymied along the way, I tremendously enjoyed developing my first Cappuccino application today. I really got into the flow of it, and the overlap with Cocoa programming is remarkably high. There were a few places where JavaScript knowledge was helpful, but my personal impression was that an experienced Cocoa programmer would be more at home than an experienced JQuery programmer. Both would certainly pick it up with a bit of effort.
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.