Nov 2004

This screen shot illustrates something very cool about the Atom feed format. (If youâ€™ve written an RSS parser but havenâ€™t done Atom yet, you might find this interesting.)

What youâ€™re looking at is part of the Atom spec (leftmost), then part of the list of files of my XML-related classes, then the interface for a class named RSAtomPerson.

(Note to people who donâ€™t program in Cocoa: the â€œRSâ€ prefix is there because, in Cocoa, you typically prefix your class names with some initialsâ€”your own, your companyâ€™s, or the name of the project.)

Object-oriented thinking

Atom is more complex than RSS, yesâ€”but, at the same time, the Atom folks did a cool thing that mitigates this complexity: they defined certain â€œconstructsâ€ that are re-used in different places. If youâ€™re using an object-oriented language (such as Objective-C, Python, and C++) you can map these constructs to classes.

For example, a Person construct has three pieces of information: name, URL, and email address. Wherever a person is identified in an Atom feed, it uses a Person construct. You might have a whole bunch of Person constructs in a single feedâ€”but, each time a person is identified, itâ€™s done the same way.

There are other constructs too, for content, dates, and links. (The Content construct is probably the most complex, but you only need to do it once, and then you can handle titles, summaries, and content elements.)

What I like about this is that it practically tells you how to write an Atom feed parser: it suggests breaking up your code into a collection of small classes for each of the different constructs. Though an object-oriented language isnâ€™t required to parse Atom feeds, the Atom spec is a case of object-oriented thinking applied to feed formats, which is cool.

Going back to the screen shotâ€”you can see it, a direct line between the spec and its expression in object-oriented code. Nice.

It’s way too late to convince the folks working on the Atom weblog editing API that XML-RPC is good. (I argued in favor of XML-RPC—months ago? A year ago? And lost.)

But now and again I feel the need to explain why XML-RPC is good, since the issue will come up in other contexts. Even if we use other things, it’s worth remembering the virtues of XML-RPC, since nothing else comes close yet in terms of both ease-of-use and generality.

So my point here isn’t to convince anyone to use XML-RPC but to talk about why it’s good. It’s worth knowing.

Procedures

When you write software, you write lots of code that looks like this: someProcedure (thing, otherThing, somethingElse).

In other words, you call a procedure (or method or function) with some parameters.

The procedure does something. Maybe it stores things, maybe it converts them to something else, maybe it sends them somewhere else, maybe it adds them together. Something happens.

There’s often a return value that lets you know the result. (Maybe it’s the sum of the things, or true or false, or an error code, and so on.)

Programmers do this all day long. It’s at the very core of programming.

Normally, of course, they write code that calls a procedure that they wrote—it’s part of the same program. Or they call procedures in a library (in my case, I use Cocoa, so there are lots of Cocoa-supplied methods my code calls). The caller and the procedure are on the same machine.

But wouldn’t it be cool if the procedures didn’t have to be on the same machine? Wouldn’t it be cool if they worked across the internet?

That would open up a whole new world of programming. You could do things like call a procedure on your weblog server that posts a new entry to your weblog. (Which is exactly what ecto and MarsEdit do.)

XML-RPC is programmer-friendly

Here’s why:

1. You make procedure calls.

Even though your code may or may not look like the example someProcedure (thing, otherThing, somethingElse), you’re still thinking in terms of procedure calls, which is very natural for programmers.

2. It’s language-neutral.

It turns out—no surprise—that languages have common types of data: integers, strings, arrays, dictionaries, and so on. Sometimes they go by different names—XML-RPC uses the word “struct” instead of “dictionary”—but they’re the same types.

What XML-RPC does is give you an easy way to call procedures and translate your data to a format that other languages can use. In other words, my code might send a Cocoa string and the server gets a Python string.

So programmers continue to think not only in terms of procedures but in terms of the data types they already know.

(OS X programmers: think of property lists. Though XML-RPC’s format isn’t the same, it’s the same in spirit. It’s an XML formatting of various data types.)

3. Learning and using a new API is easy.

When you learn a new API for in-computer procedure calls, you just learn the different names of the procedures and what parameters they take.

It’s similar for XML-RPC. You don’t have to write a new parser for each new API. You just learn what the procedures are, what parameters to send, and what they return.

This makes getting up-to-speed on a new type of web service—as long as it’s XML-RPC—incredibly, ridiculously easy.

I can’t stress this enough, how easy it is. It’s crazy how easy it is. And I suspect it’s so easy that people assume there’s something wrong with it.

The knocks against XML-RPC

Some people will never like XML-RPC because, frankly, the spec is on a UserLand server, and some people don’t want to use a spec that Dave Winer had anything to do with.

To those people, there’s nothing anyone can say, since it’s not about considering XML-RPC on its merits.

But there are other people who don’t like XML-RPC because of a real or perceived drawback or a misunderstanding of how it works. So I’ll cover some of these.

Actually, as the spec says, the “body of the request is in XML.” For instance, my software uses UTF-8 as a matter of course. It does the standard XML things for specifying the encoding.

(An earlier version of the spec did say ASCII. The spec was updated.)

Knock #2: XML-RPC mandates using one endpoint, which can be a problem for server implementors

(By endpoint I mean the URL of the script on the server.)

The spec doesn’t mandate using one endpoint, but one endpoint is quite common. I argue that one endpoint is easier, because you don’t have to have scripts in a bunch of locations (or do mod_rewrite stuff). It’s more secure because you have just one endpoint to lock down in whatever way. It’s easier for clients because you only need to discover (or figure out) one endpoint, not separate endpoints for each thing you want to do.

In other words, one is simpler than many.

But the spec doesn’t mandate a single endpoint, anyway. So if you prefer multiple endpoints, you can use them.

Knock #3: XML-RPC doesn’t understand namespaces

The point of XML-RPC is not to send around XML documents. The point is to send around data. That it uses XML to serialize the data is an under-the-hood thing. The data can be any combinations of strings, arrays, dictionaries, and so on—the standard building blocks of data.

It’s all about making a procedure call with standard data types. It’s not about document-literal XML.

Knock #4: XML-RPC isn’t a document-literal system

Some people prefer a document-literal approach. I don’t, because it means that for each different service I have to write code that translates my data to and from that document format. XML-RPC makes it super-easy: there’s just one way to translate data into XML. Once you have an XML-RPC library, you don’t ever have to deal with this again.

I’ve had the argument many times with people that document-literal does things that XML-RPC can’t do. But I’ve never been convinced. Is there anything you can’t do by calling a procedure with some data?

Some possible reasons not to use XML-RPC

The spec doesn’t say anything about security, which means people do different things.

The spec doesn’t say specifically that https is okay to use (though many people just assume it is and use it all the time).

The spec doesn’t say anything about compression. (I assume, since the spec does say that it’s http, that compression is okay to use. It would be nice if the spec said something about this, though, since XML is by nature somewhat verbose compared to binary formats.)

The spec doesn’t talk about discovering methods on a server.

XML-RPC and its replacements

I’ll grant that it’s possible that the missing pieces in XML-RPC may be enough to say that, for many cases, something else should be used.

But what we don’t have—what we’re not even close to having—is something as general and as easy-to-use as XML-RPC.

Again, what could be easier for programmers than procedure calls with parameters and return values? What is more general?

While SOAP has its many good points, no one would argue that it’s easy to use.

And while REST satisfies my aesthetic sense as being wonderfully elegant, it doesn’t give you a single serialization format you can use. You have to do more work, you have to turn data into XML and back again. (And you have to turn everything into an http verb. What if you have a procedure that, given a graphic as a parameter, returns a black-and-white version? Is that really a GET request, or are we overloading http a bit here?)

XML-RPC represents a high-water mark in ease-of-use and flexibility. If we’re moving on to something else—and, at least in the Atom weblog editing world, we are—it would be nice if that something else recognized and built on the virtues of XML-RPC.

The Atom folks are working on a weblog editing API. I plan to support it in MarsEdit, of course. (Assuming it’s do-able and it’s adopted by weblog systems—safe bets, but I have to say it anyway.)

What follows is some notes—for the benefit of the Atom folks and anyone else—based on my experience writing external weblog editors.

My background

First, just to establish what my experience actually is...

I’ve been writing external weblog editors since early 2000. The first one I worked on was UserLand Pike, which was an external editor for Manila sites. It used Manila’s XML-RPC interface. (This may have been the first external weblog editor, though I’m not positive of that.)

I then continued to work on external editing at UserLand. Later on, at Ranchero Software, I wrote an external editor that was part of NetNewsWire 1.x. My most recent editor is MarsEdit, which works with a variety of systems (Movable-Type-compatible, MetaWeblog, Blogger API, and Blosxom systems).

I’ve also worked on the server side, both at UserLand and later for my home-grown weblog system.

What follows is some notes on things I’ve learned along the way, some things that make writing clients easier.

Fewer calls are better: one call is best

Say you want to get the ten most recent posts from a weblog. Ideally, you make a single call of some kind to the weblog server to get all the info you need about those posts.

(I think this should be self-evident—but, in case it’s not, I’ll just mention that it’s much easier to deal with state, updating the UI, and error handling when you can make a single call.)

This means that the data for each post should contain not just the various bits of text but information such as categories, what text filter is used, whether or not comments are enabled, what trackbacks have been sent, etc. All the various pieces of data that you might want to edit through the UI should be returned in this one call.

There are some systems today that require 11 calls to get the ten most recent posts. First you make a call that returns most of the information about those posts—but then you have to make a call for each post to get the categories for each post. That’s one initial call plus ten more calls. That’s ten calls too many.

Similarly, you’d like to be able send a new or edited post to the weblog with a single call. Again, there are some systems today that require multiple calls in order to send a new or edited post.

Here’s how that sequence goes:

1. Make a call to send the post to the server—but tell it not to publish.

2. Make a second call to set the category.

3. Make a third call to tell it to publish the post.

Obviously one call would be better. (What if the network goes down in the middle of this sequence of calls? It’s not like transactions are supported here.)

Clients need info from the server other than just posts

Downloading posts from the server is, obviously, very important. But there’s some other information you need to be able to get:

1. What are the names of the categories for this weblog?

2. What text filters are available?

3. What comments options are available?

(And so on.)

For instance, in order to present a list of categories in the UI, you need to know what they actually are. Same with text filters and everything else like that.

It would also be nice to be able to get the defaults for those things. For instance, a system may allow you to set the default text filter as Markdown. You might be able to say that comments should default to on. It would be great if the external editor could know the user’s settings. (Right now, they don’t.)

Drafts are a big deal

People who write for weblogs love drafts, but the situation with editing drafts is very bad right now.

For some systems, they just don’t tell external editors if a post is a draft or if it has been published. This is important! Not least because an external editor might end up publishing a draft that should have remained a draft.

Another issue is that an editor doesn’t have a way to ask for the ten (or whatever) most recent drafts that are stored on the server. This is a feature request I get all the time—people want to see and edit their server-stored drafts—but, right now, no can do.

(So I have local drafts instead, which is okay, but people would—quite rightly—like to be able create and edit server-stored drafts.)

Image and file uploading needs work

The MetaWeblog API has a great feature—you can upload images and files. The server returns the URL of the uploaded image, and the client software can then build an img tag and insert it into the body of the post.

As cool as this is, it’s limited, and I get feature requests about this all the time.

The current API allows uploading, but more things are needed:

1. A way to find out what images and files are already stored on the server.

2. A way to delete images and files. (Say you upload the wrong file by accident.)

3. A way to rename images and files. (I’ve seen people upload the same image again just so the filename will be what they want it to be.)

4. A way to replace images and files. (Yes, you could delete and upload, but one call is better.)

Of course, info like MIME type and size are needed along with the URLs.

Enclosures should be supported

I’m not sure what the current thinking is with Atom and enclosures. You’ve noticed the enthusiasm around podcasting, I’m sure.

This is related to image-and-file-uploading. A way to tell a server that a given file or image should be linked-to as the enclosure for an item is important.

(Imagine the UI in the client. A user clicks an Attach Enclosure button, chooses a file, and the file is uploaded. When the feed is read by an aggregator, that uploaded file is listed as the enclosure for that post.)

Multiple users should be supported

Some weblogs have multiple users. Some of those even prevent one user from editing another user’s posts.

But most systems don’t express that in their external editing interfaces. A client should be able to get the ten most recent posts for a given user.

Errors should be standardized

There are various types of errors a weblog system might report, but there’s no standardized way to report the errors. (I’m talking about the current APIs. This may or may not be true in the current Atom editing draft, I don’t know.)

Example: say there’s an authentication error. My software has to actually look at the error string for keywords like “login” and “username” and “password” and make a guess that the error is an authentication error. That’s just plain bad.

That’s the most common error, but other errors should be standardized too. Clients should not have to guess what an error means. Ideally error codes are used so that error messages can be localized.

Maybe some of this is just standard HTTP: that’s cool. But I can imagine error conditions that aren’t part of the HTTP spec. (Or that are in the spec but are insufficiently specific for weblog editing.)

Discovery is very important

Imagine you’re trying to configure an external editor to work with your weblog. Your hope is that you can just tell the app the URL of the weblog, your username, and your password—and that’s it.

If RSD is not used, then something just as good should be used. Configuring a client is difficult without it.

Discovery is something a client should do just once: it shouldn’t be constantly having to make calls to discover different URLs for different things. (The way RSD works is that you read the file once and you know everything you need to know.)

Duplicate pings should be avoided

Some servers send “pings”—update notices—to various sites when you publish a new or edited post. Many clients do the exact same thing.

So clients should have a way of knowing what URLs the server is pinging, in order to avoid duplicate pings. While duplicate pings aren’t the worst thing in the world, it’s still a situation that should be fixed.

Pie in the sky features can be ignored for now

There are so many more features my users would love to have. Editing pages, for instance, not just weblog entries. Editing all the various templates and settings. Editing the list of categories.

I’d still be happy even if all the pie-in-the-sky stuff is put on the back burner at first. The more important issues are things I’ve listed above.

Wired News: Newspapers Should Really Worry: “From the perspective of publishers, the 18- to 34-year-old demographic is highly prized by advertisers—the people who make writing, editing and working at a newspaper or magazine a vocation, not just an avocation (like it is for most bloggers). But there is trouble afoot. The seeds have been planted for a tremendous upheaval in the material world of publishing.”

Maybe because I’m just outside that demographic, I actually like printed newspapers. But no, I don’t subscribe to any: it’s more like I like them because I remember them fondly.

I remember the days when Sundays were actually days of rest, and I’d get up in the morning (or early afternoon), make some coffee, and dig into the Sunday New York Times. My favorite parts were the book reviews, the magazine (especially Safire’s On Language column), and the crossword puzzle. (Pencil or pen? I confess: I’m a pen guy. Felt tips, not ball-point. By the afternoon I’d have ink stains on my writing hand.)

That was before the web, of course. But, for me, it probably has less to do with the web than just the normal becoming-an-adult thing. Nowadays I have things to do, people to meet, places to go. (Or, at least, leaves to rake and bugs to fix.)

I like the physicality of newspapers, except when I’m finished. Then they just take up space somewhere.

I still read magazines and books, but just about the only time I read a newspaper these days is when I’m at the barbershop waiting for my turn in the big red chair.

First thing you should know is that I expect that pretty much no one will agree with me. That’s fine—but I still have to write this up, since I’ve been working with lots of different systems in the course of developing MarsEdit, and it would be wrong if I kept this experience and my thoughts to myself.

Writing should be easier

Weblogs are very important to the future of the web. Syndication standards have already revolutionized how people read weblogs.

But writing is another thing. We haven’t made that easy yet—and, I argue, it’s not for lack of good plumbing (XML-RPC, Atom, etc.) but because we don’t have a good common set of features.

A common set of features will make tools for writing better.

Lowest common denominator

Right now the common denominator is just the body of an entry. You could write a universal weblog editor that only supported that much. But people want to set categories, trackbacks, and so on too.

Better common denominator

What if, instead, there was an agreed-upon basic set of features that every system had beyond just the body text?

That’s not to say systems couldn’t have more features—and of course they could compete on support, performance, hosting, and a bunch of other things.

But I argue that there are some features where we actually know how they should be done, and there’s no reason for different systems to work differently. There’s no competitive value, no differentiation value.

Take categories as an example. Categories are supported in various ways—and each one requires a different user interface in the writing tool.

1. No categories.

2. Only one category.

3. Multiple categories.

4. Multiple categories plus a primary category.

Why not just go with #4 in all weblog systems? After all, we know a few things—we know that people like categories. They like multiple categories. They like primary categories. We also know that people who don’t care about categories can ignore them.

Another example might be text filters. We know that Markdown and Textile and similar are wildly popular. If your system doesn’t support these, it should, and it should do so on a per-post basis, since we know that people like that flexibility.

Or take trackbacks. Every system should be capable of sending trackbacks. People like the feature. It’s an idea that has already survived the Darwinian process and so it should be a no-brainer. (And, again, people who don’t like it can ignore it.)

There’s an entire list of features like this that are just, simply, things every system should have and should do the same way. There’s no value in not having them or doing them differently—and there’s a big value in agreeing to them.

To reiterate

I’m talking about a core set of features, a better common denominator than what we have now.

A bunch of features have already been tested in the marketplace, and we know which ones have stuck.

That’s not to say that systems couldn’t compete on additional features (and a bunch of other things), but that we can raise the common denominator so that better writing tools are possible.

And, later, we can raise it again, as new features stick and become, hopefully, widely adopted.

My own self-interest

I’m arguing against my own self-interest here, in a way. After all, I’ve already done the work in my software—I’ve written the code to generate different user interfaces for different systems.

The current situation means the barrier to entry is rather high for any developer that wants to create a desktop weblog editor that works for lots of different systems. And that high barrier protects my investment.

But that barrier to entry is against the interests of the weblog world as a whole, and I’d rather align myself with the interests of the entire community.

Question

Are weblog systems a central piece of web infrastructure, or just something off to the side?

Even though they’re applications built on top of other standards (HTTP, HTML, and XML), I argue that they have become central, and we should be talking about a standard core set of common features.

I knew I shouldn’t oughter-a-done-it, and I feel a little ashamed inside, but I went ahead and bit the apple used Cocoa bindings.

It was, I confess, a reaction to that terrible feeling you get when you’re faced with creating yet another NSTableView data source and delegate. I just couldn’t face another objectValueForTableColumn:blah:blah:whatever:.

How silly it seems now—what’s one more data source among so many?—but my emotions got the best of me, and I went ahead and created—yes, say it, admit it—an array controller in Interface Builder, and I bound that damn table.

And I liked it!

It was for the pings list in MarsEdit, the last tab in the weblog settings window. I had resisted Cocoa bindings because I had planned originally that MarsEdit would run on Jaguar.

And it almost did—except for some weird stuff that was going to be very difficult to work around. So I left open the possibility that a Jaguar version would not happen—and, by using Cocoa bindings (which don’t exist in 10.2) that decision was finally made.

But now I’m tempted—very, very tempted—to go through MarsEdit and delete a ton of code and switch to Cocoa bindings everywhere.

Ask any weblog editor author—Adriaan or Fraser, for instance—and I bet they’ll tell you that weblog editing is surprisingly complex.

Certainly I think it is, and I think we can and should do something about it.

Why weblog editing is complex

If you look at it from far away, it seems like writing a weblog entry and writing an email are about the same thing. You write some text—a few sentences, a few paragraphs, occasionally something longer—and send it somewhere, to another person or to a weblog.

But if you look closer you notice that there’s a major difference in the attributes you can set in email versus a weblog entry.

Email:

From (usually implicit)
Subject
To
CC
BCC

These are all text attributes which can be set in a text field. And all these attributes are supported everywhere: email apps don’t have to show and hide different attributes depending on what kind of SMTP server you use.

Here’s where complexity comes in—we’re a long way from typing some text, choosing a place to send it, and clicking a send button.

There are not only more attributes, but they’re of different types. Some are simple yes/no fields (allow trackbacks), some allow one of multiple choices (text formatting), some allow multiple of multiple choices (categories), and some are whole new text views (extended entry).

Not only are there more attributes, but different weblog systems support different attributes. And I think that’s a barrier to the growth of the weblog infrastructure.

Converge, please!

Wouldn’t it be cool if weblog systems supported a standard set of attributes? Forget the API for a moment (though that’s important too)—I’m talking about the features different systems support.

The problem with that idea is that systems compete (in part) based on those features. Does system x support trackbacks? Does system y support keywords?

Nevertheless, I believe the following points are true:

1. We know what the superset of attributes is, and it’s been fairly stable for a while.

2. A standard set of attributes is a standard that could evolve. Think of any other standard that has succeeding versions.

3. Standards are a key to building infrastructure. Imagine if email had the same mess of competing attributes as weblogs. It wouldn’t be good.

4. Weblog systems could still compete based on price, performance, license, extendability, support, hosting, extras (like photo galleries), support, usability of their browser-based UI, coolness of their templates, and so on.

Some good news

Some informal convergence appears to be happening around Movable Type. Recent versions of WordPress and Drupal, for instance, are working toward Movable-Type-compatibility, where they support the same attributes. (They’re not quite there yet, but they’re getting there.)

However, lots of systems aren’t heading in that direction. Radio UserLand, for instance, has multiple categories like Movable Type but doesn’t have the concept of a primary category. (At least, this was true last time I looked.) And it has a post-to-home-page attribute that is, as far as I know, unique among systems.

(Nothing against Radio, it’s just a convenient counter-example.)

(And hey, my own home-grown system doesn’t even have categories at all.)

Well, so...

For real convergence to happen, something more than just an informal move on the part of some systems toward one implementation needs to happen.

(To repeat: this isn’t about the various XML-RPC APIs versus the Atom editing API—this is about what you’re editing when you use those APIs.)

I think it’s self-evident that infrastructure growth depends on standards. I think the next step in the maturity of weblog systems is to develop a standard set of attributes, so that writing software that works with weblog systems isn’t purely the province of crazy people who are willing to put up with this. (Why are there so few “universal” weblog editors and none that are truly universal?)

We’ve seen the success of syndication. Just about every weblog system creates RSS and/or Atom files which are readable in every aggregator. (Imagine if aggregators only worked with certain publishing systems!)

Doing the same thing for writing requires more than just agreeing on an API, it also means agreeing on the standard features of weblog systems and implementing them.

It boils down to the difficulty of user interface: it’s more difficult than the plumbing. Having to generate different interfaces for different systems should not be a permanent situation.

User interfaces cost money, in other words. And the more expensive it is to create the software infrastructure, the less of it there is.

It used to be that choosing Help from the Help menu was something you wanted to avoid at all costs. In 10.2 and earlier, the Help viewer application took forever to launch.

But, starting with OS X 10.3 (Panther), the Help viewer app launches much more quickly and is all-around a pretty cool application. The user interface is simple—and that’s exactly how it should be. (You don’t want to have to get help to learn how to use the Help viewer, after all.)

In other words—don’t be afraid of looking in the Help! I think you’ll find that many developers work pretty hard on their Help books and they’re actually quite useful.

One of the cool things about Help is that it’s searchable and the searching is fast.

MarsEdit 1.0b8—see the change notes—adds the last new features to go in before 1.0 ships.

New features include preview support for text filters such as Markdown, an editable pings list, and an Edit with TextMate command. You can download it via the MarsEdit home page—or, well, just click here.

We get enough support requests to have some idea of the things people often don’t know about Mac OS X.

So here are a couple things I wish every Mac OS X user knew.

Toolbars are (frequently) customizable

In many applications you can reorganize the toolbar and add and remove buttons.

Often there’s a Customize Toolbar command in the View menu. If not, often you can ctrl-click on the toolbar and choose Customize Toolbar.

If an application doesn’t have a toolbar button that you wish it had, it might actually have it—if you choose Customize Toolbar you can see all the buttons.

There is nothing magical about the default set of buttons for any given app. There’s every expectation (and hope!) that you’ll customize the toolbar to your liking.

Drag and drop is your friend

In theory, drag and drop is great because it’s an intuitive, easy way to do certain types of things. It makes sense to directly manipulate objects that appear on the screen.

In practice—at least in my experience—drag and drop is used mostly by power users. My provisional explanation for this is that drag and drop is outside the select-object/click-verb model which is the first thing you learn when you learn computers.

Me, I do drag and drop all the time: I tend to assume there will be support for it when I need it, and I’m usually right.

An example: the other day I was helping upgrade a family member’s Mac to OS X. We wanted to import his photos into iPhoto. I hadn’t used iPhoto myself—but I assumed you could drag a folder from the Finder into the albums list in the upper-left corner and it would create an album. It worked!

An important point about drag and drop—a point that people often miss—is that it often works between two different applications. If you use Mail, I think it’s fairly obvious that you can drag a message from your inbox to another mailbox. What is less obvious is that can drag a link to your desktop, drag text into a text editor, and so on.

(First off: best wishes to the Konfabulator folks! I hope their app is a huge hit on Windows.)

I’m quoted in the article. Just for the sake of completeness, here’s the full text of what I wrote:

It’s always in the back of my mind that Apple might compete more directly with my applications. But I don’t see that the situation is any better on Windows—in fact, I think it’s much worse. So I stick with developing for OS X, since I like OS X.

I think this situation gets far more attention than it warrants, actually. If you go to MacUpdate or VersionTracker you’ll see tons of applications by many small developers. Only a miniscule percentage of those apps end up with competition from Apple. Smart developers concentrate on writing and marketing high-quality software rather than worrying about what Apple may or may not do.

If Apple did create an iNews app that competed directly with NetNewsWire, I wouldn’t be tempted to do a Windows version. That Arlo Rose brought Konfabulator to Windows is cool—but every developer is different, and what’s right for him isn’t necessarily right for me. What I would do is continue to improve NetNewsWire and continue to develop new OS X applications.

This is my last post about politics for now... I’ve already unsubscribed from a bunch of political weblogs.

The last thing I wanted to say was that I’ve seen liberals hating conservatives and conservatives hating liberals. There are jerks—some really, truly awful people—on both sides. But most people are trying hard to do what they think is right.

Me, I voted the way I did because I thought my candidate would do the better job at national security and at bringing peace, democracy, and stability to Iraq. I thought my candidate was stronger.

Of course, there are millions of people who could have written that last paragraph, and roughly half voted for the other guy. That just means that it’s a democracy and we disagreed.

This election is over, but the future of America is still decided day-by-day, person-by-person.

Well, that was a disappointing election result. But some of the reaction has been a bit over-the-top. It’s not actually armageddon. Buck up! There’s more work to do.

If I had to pin the loss on one thing, I’d say it was the continuing success of the culture war. It was God, gays, and guns—with particular emphasis this time on gays.

At a deeper level, though, it reminds me of something that irks me personally: many Democrats reserve the word “evil” for their Republican opponents. Republicans are not evil, by the way. Terrorists are evil.

All those voters who said that “moral values” were important might be more willing to vote for a party that isn’t afraid of the idea of good and evil. That’s where moral values start.

Now, I voted for Kerry for moral reasons as well as practical. Freedom and civil rights are moral issues. The differences between Kerry’s and Bush’s foreign and economic policies are, in many cases, moral differences.

(And I think that winning an election by scaring people with gays is immoral. It’s cynical, manipulative, pandering—and it’s highly effective.)

I was a teenager when Reagan called the Soviet Union the “evil empire.” Like everyone else living in what are now called blue states, I gasped and said, “He can’t say that!”

But I kept thinking about it. It stuck in my head. And I thought to myself: if a nation that murders and sends to the gulag millions of its own citizens, that controls so utterly the minds of its people, isn’t evil, what is?

You might say this is a religious point of view. For me, it wasn’t—I kept thinking of the old quote “man is the measure of all things.” And, by that humanist measure, the Soviet Union was an evil empire.

That didn’t make me a Republican, and it didn’t mean that I thought the people of Russia were evil people. (They were victims of evil.) I could still see shades of gray—and degrees of evil.

But, I remember to this day, the blue-state orthodoxy was wrong and Reagan was right.

My pitch to Democrats: let’s go back to the beginning, to the intellectual foundation. Let’s talk about good and evil. Let’s not be afraid to use those words.

The idea is to stand for something, a real morality, rather than use fear-disguised-as-morality as a wedge issue.