Read the latest news on the Cappuccino reddit.

Cappuccino 0.8

April 7th, 2010

Cappuccino 0.8 is now available on the downloads page. This release has a ton of new features and fixes, and I’d like to thank everyone in the community that meticulously checked their existing software against the Release Candidates in the last few weeks.

10,000 Foot View

Cappuccino 0.8 includes close to 100,000 lines of changes from our last formal release, 0.7.1 (check out the Github compare view for this release). This ranges from new tests to brand new features to optimizing existing ones. And yet, despite this tremendous amount of change, we have almost no API differences (aside from API additions of course). The very few changes we do have are simply deprecated, not removed. This means that it will be incredibly easy to drop in the new version of Cappuccino and get all the benefits without spending a ridiculous amount of time changing your own code. This is of course the benefit of implementing an existing and proven spec. In fact, most the public Cappuccino projects are already running this code.

Now that that’s out of the way, lets get to the good stuff: what’s new?

CPTableView and CPOutlineView

Table views have been one of our most requested features since we launched Cappuccino about a year ago, and I’m happy to say that I think we have one of the best table view implementations out there with 0.8. Randy, our latest committer, has spearheaded this feature for his own TimeTable project and with help from a number other folks in the community it has become a truly awesome component, supporting immense amounts of rows, column sorting, drag and drop, and much more while still remaining incredibly performant. But don’t take my word for it, check it out yourself:

Automagic Image Spriting

We alluded to this feature a little while ago when we first announced it at JSConf EU, and now you can finally take it for a spin: automatic image spriting. Yes you read correctly, no more having to manually decide which images to sprite, or how to sprite. The brand new Cappuccino build tools are smart enough to sprite all your images together into one file (not several based on orientation), and of course works in all browsers including IE. You can find out more about the thinking behind this feature here.

nib2cib Updates

Along with all the new components we’ve added to Cappuccino, we’ve been keeping nib2cib up to date to allow you to use them in the easiest way possible. Most importantly, table views can now be created with simple drag and drop!

The Whole Stack with CommonJS and Jake

Although this isn’t necessarily a feature in Cappuccino itself, a lot of our users will be thrilled to know that getting and building Cappuccino from the repo (or building and optimizing your own Cappuccino apps) no longer has any external dependencies. In previous releases we relied on a combination of our own tools and a few Ruby tools like Rake. However, with the advent of the CommonJS standard (which our own team member Tom has been working on diligently), we’ve been able to move our entire development stack to JavaScript and Objective-J. That means that our community members will have an easier time writing tests, fixing bugs in the build process, and writing server side JS and Objective-J. Making this change has also allowed us to put a greater focus on the tools side of things and provide a host of improved applications like press and flatten to better optimize deploying your Cappuccino applications. We’ll be posting soon with more details about these.

And there’s way more in there as well. We are incredibly proud of this release and think it makes Cappuccino more compelling than ever. We’ll be at JSConf showing some of this stuff off too, so if you’re attending, stop by and say hi!

- Francisco

Solving the JavaScript Memory Management Problem

April 1st, 2010

JavaScript has some real problems. Anyone who has programmed for the web can attest to that. And anyone familiar with what we’re doing with Cappuccino will recognize that we’re not afraid to tackle those problems head on. When we created Objective-J we set out to create a set of true enhancements to the JavaScript language that would add powerful new dynamic features to the language, like advanced automatic dependency resolution, truly dynamic message passing, and familiar classical inheritance. By all accounts it has been a tremendous success.

Lately, though, we’re beginning to realize that we didn’t quite go far enough. Memory issues have long plagued JavaScript developers. Because the garbage collector is opaque to the developer, and nothing like “finalize” is provided by the language, programmers often find themselves in situations where they are forced to hold on to an object reference for too long (or forever) creating a memory leak.

Just as we’ve done before, when we tackled this problem we decided to look at what has worked in the past. Finding inspiration in the elegant simplicity of C, we knew we’d found the right solution. And so, we’re pleased to announce the immediate availability of a manual memory management system in Cappuccino.

A lot of Cocoa developers disparaged garbage collection when it came to Objective-C, and we’ve come to realize they were absolutely right! Why rely on machines to solve problems for us when we can do it by hand. So, we’ve taken the Cocoa reference counting system and implemented it in JavaScript. We’ve replaced the existing no-op -retain, -release, and -autorelease methods with fully working implementations. When an object’s release count reaches 0, the object’s dealloc method will be called, and the memory will be able to be reclaimed. Now you have a clear way to clean up unwanted references when an object is no longer being used. Just make sure you do your reference counting correctly!

To do this right, we’ve created a global object table. These objects aren’t going anywhere on their own! If you don’t release an object, it will stick around forever, ensuring you’ll always have it when you need it. This global table acts as a lookup table for any object, allowing us to finally implement pointers in JavaScript. Since $ has become the coolest way to do completely non-standard lookups in an almost indecipherable way, we thought we’d jump on the bandwagon. Pass any pointer to $ and you’ll get the associated object! How do you get a pointer you ask? $$ of course! For example:


var o = [CPobject new]; // +new returns with a retain count of 1!
var p = $$(o); // returns a pointer to o

o === $(p); // we dereference the pointer and get the right object!

Zombies come standard, too! Just set OBJJ_ZOMBIE_DETECTION to true and objj_msgSend will throw an exception if you ever message an object that’s been dealloc’d.

We’ve even take the time to properly -autorelease all objects returned from class methods in Foundation, but we’ve made absolutely no effort to properly retain those objects in Cappuccino code that uses them yet. So we need your help. Every line must be scrutinized (but we shouldn’t to automate this process, as it would surely be too error prone). Rather than focus on developing new features or fixing bugs in the issue tracker, we hope that all Cappuccino contributors will spend their time writing memory management code so that we can fully realize this web development revolution!

We’ll be including these exciting new features in a future release, so you should get started adding manual memory management code to every single line of Cappuccino you’ve ever written! In the meantime, check out the working code on Github.

Please note this is an April Fools joke!

New Cappuccino App: TimeTable

March 24th, 2010

After many months of development Randy Luecke has finally released version 1.0 of his new Cappuccino project, TimeTable! We’re proud to share in the excitement as yet another Cappuccino application is made commercially available. TimeTable is an application designed for freelancers to keep track of their projects and clients. TimeTable boasts a plethora of features including integration with web services like Google Maps, Gmail, Google Voice, and Skype.

Randy’s commitment to Cappuccino is obvious when you look at the development he has done on the new CPTableView component, which was developed in parallel with TimeTable. In addition to the work he has done on CPTableView, Randy has also open sourced different components used throughout TimeTable, the most notable of which is the date picker component. Randy has been no stranger to the community as he continues to lend a helping hand in the mailing list and IRC channel. We look forward to the things Randy has in the pipeline for Cappuccino!

We’d like to share in Randy’s success by sponsoring a give away of 25 TimeTable accounts. To enter simply tweet: “I would like to enter to win a @timetableapp account http://timetableapp.com/”! On March 30th, 25 twitter users will be chosen at random to receive their free TimeTable account! If you don’t win TimeTable is still more than affordable at its incredible introductory price of $34.99 a year!

Find out more about the TimeTable launch.

Community Highlights: Using Cappuccino to build the MemoryMiner Web Viewer

March 17th, 2010

We’re starting a new series here on the Cappuccino blog, featuring interesting posts by community members. The first such post is by John Fox, creator of MemoryMiner, a digital storytelling application for Mac OS X, now with a web viewer built with Cappuccino:

If you’ve got an interesting blog post up your sleeves write it down and post it to CappuccinoFlow. We might feature it in Community Highlights!

Randy Luecke Becomes a Committer

March 12th, 2010

A little late to post this, but everyone in the Cappuccino has loved the work Randy (Me1000) has been doing on CPTableView. Thanks to his hard work and significant contributions, the table view component in Cappuccino is now a force to be reckoned with. So we’re proud to have Randy as our latest Cappuccino committer, and we’re looking forward to the table view features still to come.

Randy also has his own Cappuccino app he’s been developing called TimeTable. It’s a time tracking app thats set to launch soon, so keep an eye out!

Internet Explorer: Global Variables, and Stack Overflows

March 1st, 2010

Stack overflow at line: 0

Every once in a while, you stumble upon a particularly strange bug. A bug that seems to defy the rules of space-time. A bug that makes you pull your hair out for days. A bug that almost certainly includes Internet Explorer. This was one of those bugs for me, and since I haven’t found a lot of information out there even now that I know what the problem was, I wanted to write it up for posterity.

It starts with what looks like a relatively benign function, that we’ll call recurse:


window.recurse = function(times)
{
    if (times !== 0)
        recurse(times - 1);
}

recurse(13);

If you pass in the magic number 13 (or anything higher), this recursion is going to fail with our stack overflow pop up. No problem, you say? You’ve fought Internet Explorer before, and you know how to get down to business. Fire up the trusty IE 8 debugger and get to work! Unfortunately for you, the debugger won’t be triggered. Just a pop up for you. If you’re feeling extra ambitious, maybe you’ll try installing Visual Studio and hooking up the advanced debugger directly to IE; I did. No such luck.

I should mention that the code above wasn’t what forced me to investigate this bug. I’m not usually in the habit of writing recursive functions that don’t actually do anything. And when your code base is tens of thousands of lines long, and your coworker has pushed a
couple thousand new lines of code (which radically alter the load process), tracking down any problem without a debugger starts to get hairy. At one point in the process, I actually stepped line by line through every single new line of code, certain I’d track down the bug. I didn’t, because not only does IE not trigger the normal exception mechanism, it doesn’t even report the error until after any waiting script executions are finished. Fun.

Thankfully, my neighbor works at Microsoft, so I was able to get an inside look into the issue. That’s where our test function comes in (thanks Microsoft). Let’s get back to it:


var recurse = function(times)
{
    if (times !== 0)
        recurse(times - 1);
}

recurse(13);
recurse(10000);

Our new version works. Can you spot the difference? We’re using a “local” (but really global considering our current scope) variable here, instead of assigning the function to a property on the window object. This tells us that it has something to do with the window “host” object, but it isn’t the whole piece of the puzzle just yet.


(function(){
    var recurse = function(times)
    {
        if (times !== 0)
            recurse(times - 1);
    }

    //we won't have access outside to recurse, so add a global ref
    window.recurse = recurse;
})();

recurse(13);

This test also works, and is pretty much the last piece of the puzzle. From this we can see that simply assigning a variable through the window object isn’t the problem, the problem is actually recursing through that variable.

In the block above, the recursion is happening through the local var, not the global reference, and so it isn’t triggering the bug. To prove that this is the case, let’s try the opposite test:


(function(){
    var r = function(times)
    {
        if (times !== 0)
            recurse(times - 1);
    }

    //we won't have access outside to recurse, so add a global ref
    window.recurse = r;
})();

recurse(13);

Here, we’re doing the recursion through the global reference, and as we expected it fails. So, the lesson to learn here is that any recursion that happens through the window object is limited to a stack depth of 12. If there was a tl;dr; to this post, it would be that.

To dig just a little bit deeper into some of the oddities of what’s going on here (and how it impacted Cappuccino), you’ll want to see this unbelievably strange (but not technically incorrect) behavior:


window === window;           //true
window.window === window;    //false

function global(){
    return (function(){return this;})();
}

global() === window;         //true
global().window === window;  //false

Technically, the behavior of the window object isn’t defined by ECMAScript or any browser standard; it’s a native object provided by the browser to the runtime environment. As a result, even though IE’s behavior here is strange, and the opposite of all other major browsers, it isn’t technically wrong. It’s absolutely terrible, though.

Why did we have this problem in the first place? To answer that, you need to know a bit about CommonJS modules. In the CommonJS “spec” modules have their own scope, and don’t export their vars as globals to the outside world. Instead, the module loader passes in an “exports” object, and the module author assigns properties to that object. Another way to put it would be to say that the public API of any module has to be explicitly created by assigning methods to the exports object.

In addition to Cappuccino, we’re also the authors of Narwhal, the most popular implementation of the CommonJS spec. We’ve already migrated most of our tools to run on top of Narwhal, and we’re continuing to improve the integration between Objective-J and Narwhal. Part of that means changing some of our code to use the exports technique, and using that same code in the browser.

What we ended up with was something like this:


var exports = {};
(function(global, exports){

    //lots of methods...

    function objj_msgSend(){
        //do some stuff;
    }

    //lots of exports...
    exports.objj_msgSend = objj_msgSend;

    // make exports global
    for (var export in exports)
        if (exports.hasOwnProperty(export))
            global[export] = exports[export];

})(window, exports)

The final loop assigns the exports to the global scope, since that’s how Objective-J code is expected to run. This last step was the cause of all of our problems, because as you can see, we’re creating all global methods on the window object, which means all calls to them are going to go through the host object, and be subject to our exceptionally low recursion limit.

Our first fix looked like this:


    for (var export in exports)
        if (exports.hasOwnProperty(export))
            eval(export +" = global[""+export+""];");

The eval creates a global implicitly, rather than explicitly, which doesn’t trigger the trip through the host object. We explored a few different ways to get around the bug, including working with Microsoft, but found no other viable solution.

Rather than ship this code in Cappuccino 0.8, though, we decided to take a step back and re-examine our initial requirements. The desire to strictly adhere to the CommonJS proposal was requiring that our code become more complex and harder to maintain, so we dropped that requirement.

The final version of the code is almost exactly the same, except rather than doing things like global.foo = function(){}, we’re simply using implicit global creation directly. This is more in line with the way all existing JavaScript runtimes actually work. It’s also the way Narwhal works, and probably the way CommonJS should work.

I want to give another thank you to all the folks at Microsoft who helped us track down the problem and provided us with a simple test case that reproduced the problem. They were quite helpful, and we (along with all of our users) appreciate it. Now hopefully we’ll see this issue addressed in IE9, along with a faster JavaScript engine :) .

Download

Cappuccino and Objective-J are licensed under the LGPL. For more information, see our licensing page.

Copyright © 2009 - 280 North, Inc. Cappuccino and Objective-J are registered Trademarks of 280 North. Logo by Sofa. Hosting by Slicehost.