Introduction to Objective-J and Cappuccino with Tom Robinson
This morning, I attended Tom Robinson's talk on Objective-J and Cappuccino. Tom is one of the founders of 280 North and creators of the Cappuccino framework and Objective-J language, so I was very interested in hearing about Cappuccino from the source. The text below are my notes, but they're also mostly Tom's words, not mine. I've added a "Thoughts" section at the end that are my words.
Tom's Team was Cocoa programmers before they started building Cappuccino. They wanted to focus on building Desktop Class Web Applications (for example, Google Maps, Meebo and 280 Slides). Tom showed a demo of 280 Slides and how it can rotate and scale images very easily, something you don't often see in web applications.
To build desktop class web applications, you can use Flash or Silverlight, but they're controlled by Adobe and Microsoft. Also, they have no iPhone support and poor Mac and Linux performance. The other option is JavaScript + DOM. They're open standards, available almost everywhere (including mobile devices) and its a very rich ecosystem with lots of competition. The downside to JavaScript is standards bodies, many incompatibilities, technical limitations (e.g. can't access web cam) and the DOM is very document-centric.
The bottom line is we can't fix Flash, but we can fix JavaScript.
This is what 280 North is trying to do with Objective-J. It's a proper superset of JavaScript, has a few syntax additions, has a powerful runtime and is implemented in JavaScript. Objective-J is analogous to Objective-C. It adds to JavaScript like Objective-C adds to C.
One of the first things Objective-J adds is Dependency Management. You can import from search paths:
@import <Foundation/CPObject.j>
Or from relative paths:
@import "ApplicationController.j"
@import prevents duplicate loads has asynchronous downloading and synchronous execution. That means all files are downloaded before evaluation begins, but to the programmer, it seems to happen synchronously.
The thing that sets Cappuccino apart from other libraries is its inheritance model. It uses classical OO inheritance (using Objective-C syntax).
@implementation Person : CPObject { String firstName @accessors; String lastName @accessors; } - (String) fullName { return firstName + lastName; } @end
The type definitions (String) are ignored for now and primarily used for documentation. In the future, they plan to add optional static typing, hence the reason for having them. Tom is unsure if you can leave off the String type or if the compiler requires it.
@implementation has proper support for super
and language syntax support. One of the reasons they chose Objective-C is because classical inheritance works great for UI Frameworks.
Objective-J uses "send a message" syntax instead of "call a method" syntax. In the code snippets below, the first line is JavaScript, the second is Objective-J:
object.method() [object method] object.methodWithFoot(arg1) [object methodWithFoo:arg1] object.methodWithFooBar(arg1, arg2) [object methodWithFoo:arg1 bar:arg2]
Dynamic Dispatch is one of the most interesting parts of Objective-J. forwardInvocation in Objective-C is like method_missing in Ruby. Methods can be used as references, for example:
var action = @selector(someMethod:);
Runtime mutability is important for KeyValueCoding (KVC) and KeyValueObserving (KVO). KVC allows you to swap classes at runtime and KVO allows you to listen for when property values change. At runtime, a $KVO_ClassName is generated. This class notifies any registered observers when values are changed and then calls the original class to change the property.
Cappuccino
Cappuccino is an application framework, not a library. It uses the Hollywood Principle: "Don't call us, we'll call you".
The Framework handles document management (open, save, revert), content editing (undo, redo, copy, paste) and graphics manipulation. The DOM is designed for documents (same is true for HTML and CSS). Tom doesn't like the DOM as its not a good API for building applications. Proof is all the JavaScript libraries built to make the DOM better.
Cappuccino has an MVC framework and CPView is its View. It's analogous to a <div> and represents a rectangle on the screen. Everything visible is a CPView or one of its subclasses. It defines resizing and layout behavior. CoreGraphics is Cappuccino's canvas-like drawing API. It uses VML on IE, canvas on everything else.
Very little of the code in Cappuccino talks to the DOM (less than 2%). It's not just about providing widgets that work in all browsers, it's a way to write platform independent display code.
Events are done very differently than most JavaScript libraries. Browser's dispatching is not used. A single event listener is registered for each type of event on the window. These events are captured and sent to the objects that need to know about them. This allows for consistent events across all browsers, even keyboard events. It also allows for creating custom event flows and easily creating custom events. Cappuccino events allow you to get around a common problem with DOM Events where you can't click on overlapping rectangles.
Notifications can be registered and sent very easily. Both "scoped" and private notifications can be created.
Undo Management is included in Cappuccino. It manages a stack of undos for you. Redos are "free" and undo functionality is part of the document architecture. This makes it easy to integrate with auto-save functionality.
Run loops (also called event loops) are an advanced feature of Cappuccino. They allow you to perform actions on every run loop. This enables complex optimizations for DOM/Graphic operations and undo grouping.
The final part of Cappuccino is Keyed Archiving. Keyed Archiving stores a graph of Objective-J objects. It handles reference cycles, conditional inclusions, has an efficient data format and works on the client and server (Objective-J can be run on the server). The data format is similar like binary, but it's UTF-8. Keyed Archiving is used for archiving views and used heavily in 280 Slides for storing, retrieving, and exporting presentations.
Other applications implemented with Cappuccino include almost.at and Mockingbird. EnStore uses it too, but only for its admin interface.
An interesting extension for Rails developers is CPActiveRecord, a reimplementation of Rails' ActiveRecord in Cappuccino.
There are several tools included with Cappuccino:
- objj: command line Objective-J
- objcc: "compile" ahead of time
- press: optimize code and resources
- nib2cib: convert Mac OS X nibs
- capp: project creation
All these tools are built on Narwhal (which conforms to the CommonJS standard).
CommonJS
CommonJS is an effort among server-side JavaScript projects to standardize non-browser JavaScript APIs. There's numerous API specifications (so far):
- Binary, File, IO
- stdin, stdout, stderr, args, env
- Web server gateway (JSGI) - similar to WSGI and Rack for Python and Ruby
To learn more about CommonJS, see CommonJS effort sets JavaScript on path for world domination.
Narwhal is 280 North's implementation of CommonJS APIs. It works with multiple JavaScript engines, including Rhino, JavaScriptCore (SquirrelFish) and XUL Runner. According to Tom, Rhino is an order of magnitude slower than JavaScriptCore and V8. Of course, Narwhal supports Objective-J too.
Aristo
Aristo is the new default theme in Cappuccino and was created by the Sofa design firm. It includes windows, tabs and menus and is open source so you can modify.
Atlas
Atlas is an IDE for Cappuccino, focused on building user interfaces graphically. Atlas is a downloadable application for OS X. It's written almost entirely in Cappuccino. The desktop version bridges Cappuccino windows to native windows. Tom did a demo of Atlas and showed how its layout feature allows you pin, center and align very easily. It's all done with JavaScript because doing layouts with CSS is often very painful. After that, he showed us how can you Atlas to very easily build a Web Application and then export it as a native OS X application without changing a line of code. Atlas includes Mozilla's Bespin for code editing.
To learn more about Aristo and Atlas, you might want to checkout Ajaxian's Big News from Cappuccino: Aristo and Atlas from earlier this year.
Atlas has a $20 Beta Program if you're interested in trying it out.
My Thoughts
Cappuccino looks like a very cool web framework. It reminds me of GWT in that you have to learn a new language to use it. However, Atlas takes a lot of that pain away. I particularly like how it has document and undo/redo support built-in. On my current GWT project, this would be very useful as we've had to build this functionality by hand.