Archive for July, 2011

Social Algorithm

if( message.length <= 140 && message.isPublic ) {
    Twitter.tweet( message.text );
} else if( message.isPublic ) {
    if( !intersection( message.recipients, Contacts.facebookOnlyUsers ).isEmpty ) {
        FaceBook.setStatus( message.text );
    } else {
        GooglePlus.share( message.text, GooglePlus.PUBLIC );
} else {
    circles = GooglePlusUtilities.computeRelevantCircles( message.recipients );
    GooglePlus.share( message.text, circles );

Using a Cross-Platform Runtime to Build Better Apps

The inherent advantage of using a cross-platform runtime, such as AIR, to develop applications is typically understood to be the boost in productivity that’s achieved by reducing the amount of per-platform work that’s required. While it’s true this is a potential advantage, it’s generally discussed with an implicit assumption that the developer is interested in reducing the development cost.

Suppose, for moment, that this is not the case. If you spend just as much on development as you did before and use a cross-platform runtime, then what happens? You build better apps.

The key is to take all the time you saving writing code once and apply the savings elsewhere in your application. That could be to additional features. Or it could be a better experience: improved responsiveness, more intuitive UI, lower memory use. No matter how you spend this savings, you build a better app.

Device Proliferation and the Cost of Software

I purchased my first application from the Mac OS App Store this week; it cost $99. Before I hit the purchase button, though, I wondered: Was I going to have to spend that $99 three times? Unlike my phone, of which I have only one, I have a Mac at work, one at home, and a laptop. Multiplying every purchase by three was going to make this a much more expensive proposition.

Being in the business of writing software for a living, I try to be conscientious regarding software license terms. To do that, I actually read the license agreements. Or at least, the part of them that deals with how many computers the software can be installed on.

In my experience with such terms, there has been a gradual evolution away from licenses tied to specific computers to accommodating the desktop/laptop combination that’s common these days. But, that still left the typical number of machines per license at two, and one of them had to be a laptop.

The Mac App Store licensing terms are much more generous: Each purchase can be used on any Mac that you own or control. From the Mac App Store FAQ:

Can I use apps from the Mac App Store on more than on computer?

Apps from the Mac App Store may be used on any Macs that you own or control for your personal use.

Re-assured that I’d only have to spend my $99 once, I proceeded with the purchase.

Does this represent a shift towards lower software costs for consumers? That $99 license from the Mac App Store cost the same as buying the software directly from its publisher, but the publisher’s license was more restrictive: I would have had to purchase two copies for twice the price.

Yes and no. The kicker is that the Mac App Store works only for my Mac. Want the same app for your iPad? That’s another $40. And for your iPhone? That’s another $20. So yes, this change in licensing terms brings down the cost of software for desktop and laptop computers. But at the same time, I’m spending more on software than ever before because I’m also buying it for different types of device. Device proliferation is driving costs right back up.


Application Structure and Composition

Recent mobile application models impose some surprising straightjackets that defeat the ability to compose applications from constituent parts.

On the desktop, composition support is de rigeur. On Windows it’s possible because there simply aren’t many rules. Want to use a DLL that uses another DLL that loads some external resources? There’s an API for that. Well, APIs, anyway. You can string them together by solving for units, which by the way also works wonders in high school physics.

On Mac OS composition is by design. Which is fortunate, since otherwise it probably wouldn’t be allowed. Depend on a framework? There’s a place to put it. Framework depends on another framework? Yes, there’s a place for that, too. All places rationally named, everything is a bundle, layout standardized.

iOS? Not so much. Mostly because dynamic code loading isn’t allowed, at least not outside of OS frameworks. We have to revert to linking everything together into one big blob. And then all linker symbols appear in a common namespace, so we’re denied the pleasure of embedding multiple copies of the PNG library into the same application without modifying any of them to use unique prefixes.

The real surprise for me, though, was Android. Surely an open platform would support composition? But alas, resources on Android get compiled into one big block of unique IDs. No way to use this mechanism to create a library beforehand with its own set, because there’s only one file to rule them all.

No doubt there’s a method to the madness that I just can’t see. Maybe they can break it down into pieces for me.

Class Declarations as a Transformation of Closures

In JavaScript, one can go about creating objects with private state by hiding it in a closure made at object creation time. Something along the lines of:

var myObject = (function() {

    var privateVariable = ...;

    return {
        publicGetter:function() { return privateVariable; }

Here, shielding the private state occurs at execution time; that is, it’s a result of the execution of the program.

Here’s the equivalent in using class declarations in ActionScript:

class MyClass {
    private var privateVariable = ...;
    public function publicGetter():* { return privateVariable; }

Here we can take the “declarations” part of “class declaration” literally: The private state is now private because it’s declared that way, rather than as a side effect of program execution.

Thus, class declarations provide a declarative transform of one particular thing that can be achieved via closures. As a mechanism, closures are of course more powerful and widely applicable. For purposes of writing and reading maintainable code, it’s preferable to have declarative support for common patterns like this.