Code by Kevin
   


About
Code by Kevin: Programming, code, business, and other pursuits

Your Host
Kevin Walzer, software developer.

Home

Subscribe to RSS Feed
Get a syndicated feed of my weblog.

Archives
2010
2009
2008
2007
2006

Categories
Business
Software
General

        home
Sun, 31 Jan 2010

The perfect is the enemy of revenue

Even though I've made a great deal of progress over the past year in enhancing the native integration of my programs on the Mac, I'm not entirely satisfied. My programs can now support text and files dragged to them, but you can't drag text from them to other applications. They can now be called from AppleScript, and they support the Services menu, but you can't access the Services menu from within my programs. And while my programs can now print with nice, "sheet"-style dialogs, they don't print using Cocoa API's.

The question before me: is it better to release software that doesn't support these nice features in their entirety, or would it have been better for me to wait until the features worked perfectly?

This is a actually a dilemma that all software developers wrestle with. Marissa Mayer, Google's vice president of search and user experience, favors an incremental release process and continuous improvement. Apple, by contrast, favors "insanely great" products that are little gems of perfection. Many indie developers in the Mac community tend to embrace the Apple view of things. In the words of Brent Simmons, "You make beautiful hardware and software--you create an experience so new and compelling that people lust for these things."

In practice, and also in philosophy, I tend to come down more on the other side--releasing even if it ain't perfect. This doesn't mean I ship programs that fail to work as advertised, that are glaringly buggy, or that lack any useful features. Some proponents of "release early, release often" see no problem with releasing stuff that crashes--hey, it's a chance to identify bugs!

However, I do embrace Voltaire's maxim that "the perfect is the enemy of the good." In software terms, this translates to, "the perfect is the enemy of the released product." There's no opportunity for a perfect product to make money if it's not in released form. In terms of my products, this means that I'd rather partially implement the easy part of a useful feature than delay release indefinitely for a complete, perfect implementation.

This has been my approach with drag-and-drop, AppleScript support, Services, and printing. The parts that I implemented were the relatively easy parts--and even those aren't easy. Drag-and-drop took several weeks, and a good deal of collaboration with the original creator of the TkDND extension, to implement dragging to a Tk window. Dragging text out of a Tk window is much, much harder because of technical conflicts between Tk and the underlying Cocoa foundation. I had no idea how long it might take to work through these conflicts, or even if I had the skill to do so. So I decided to move ahead with what I had.

AppleScript support is another incomplete, difficult feature to implement. My Python programs actually have the hooks in place to provide extensive AppleScript support--implementing AppleScript commands that other applications can call--through the excellent appscript Python library. However, my Tcl applications can't provide the same level of support because the standard Tcl library for AppleScript support, TclAE, will need an extensive rewrite to support 64-bit--a rewrite I currently lack the skills to undertake. Instead, if I want to offer AppleScript support, I'll have to use Tcl's built-in "do script" AppleScript command--which means I'll have to implement raw Tcl commands that other applications can call via AppleScript. Functional, but hardly perfect.

Services is yet another feature where the implementation isn't as perfect as I'd like. For technical reasons similar to the issues with drag-and-drop, my Tcl and Python programs can't access the Services menu from within the application itself. And they can only export Services functionality because I discovered a handy tool called ThisService, which allows you to create Services from scripting languages. I'm using the AppleScript support my programs are implementing to add the Services functionality as well. (I tried to create a Cocoa extension that would hook into the Mac's Services functionality, but was not successful--again, technical conflicts between Cocoa and Tcl that I could not work through.) While I feel my solution using the ThisService tool and AppleScript was elegant and actually quite clever, it's certainly not perfect.

Finally, printing. It would be nice to support native printing. Yet the Mac's built-in command-line interface to printing is so adequate for my needs that it's hard to muster too much worry about the lack of Cocoa-native printing in my programs.

My thinking about these issues is guided by more than just my desire to earn revenue by shipping products. It's also guided by the Unix philosophy of programming, which I've written about before. The key idea I'm taking away from the Unix philosophy is "keep it simple, stupid." If I can adequately implement a feature that is effective if imperfect, it's better to go that route than wait indefinitely for perfection. It's hard to say, at this point, if I'll ever perfectly implement drag-and-drop, AppleScript, Services, or printing in my programs. In 2010, my goal is to release commercial products, not open-source libraries. That means building on what I have; it's good enough. Waiting for perfection means waiting for revenue.

[/business] permanent link