Archive for December 2003

Thursday, December 18, 2003


There’s a new round of spams that can be hard for SpamSieve to catch if it hasn’t seen many of them before. They have subjects like:

Re: GSF, despite the promise
Re: IOWRGW, the magician disappeared

and, when the spam-generating software doesn’t work properly:

Re: %RND_UC_CHAR[2-8], rimsky suddenly reached

Generally, my approach with SpamSieve is to make it better at learning from tactics used in spam messages, rather than try to match transient characteristics with a countless number of rules. Sometimes, however, rules work great, and if you add the ones below to your copy of SpamSieve 2.1, it should be easy to catch these new spams.

SpamSieve Blocklist

If you want to copy and paste, the rule text is:

(?:(?-i)^(Re: )?[A-Z]{2,8}, [ a-z]*$)

Monday, December 15, 2003


Joel Spolsky reviews The Art of UNIX Programming and discusses Windows/Mac vs. Unix culture differences.

Jamie Zawinski fisks Wired’s story on RFID.

Jan Erik Moström pointed me to Natural Docs, a clean, JavaDoc-like utility that supports several languages.

Keyboard Shortcuts

John Gruber and Christopher Clark discuss keyboard shortcuts. I’m more optimistic than Gruber in that I think Apple can come up with a good system for user-customizable keyboard shortcuts, without applications having to explicitly register them. Instead of having a preferences panel, there should be a more direct interface, like Menu Master’s. Apple writes the menu manager, after all. Also, Joshua Dady pointed me to /Library/Scripts/Mail Scripts/Scripts Menu, which has instructions for adding keyboard shortcuts to menu scripts.

I must admit that my own applications are currently guilty of not supporting Close All Windows and Minimize All Windows. I’m working to correct that. For Cocoa developers, here is a category that will help:

@implementation NSApplication (yourPrefix)
- (NSArray *)yourPrefixVisibleRegularWindows
    NSMutableArray *result = [NSMutableArray array];
    foreach ( window, [self orderedWindows] )
        if ( [window isVisible] && [window canBecomeMainWindow] )
            [result addObject:window];
    return result;

Don’t forget to implement -validateMenuItem: so that the commands are disabled when there are no windows. OmniOutliner currently supports the commands, but gets the validation wrong.

Friday, December 12, 2003


Buzz Andersen:

The problem with Project Looking Glass is that it falls for a common fallacy in UI design: the idea that the more literally a user interface apes the real world, the easier it will be to use.

Thursday, December 11, 2003

PowerBook G4 at Amazon

Amazon is selling the low-end 12" PowerBook for $500 off.

$500 of PowerBook G4

Wednesday, December 10, 2003


Goombah is an intriguing new application/service that examines your iTunes music library and compares it with other users’ libraries. It then recommends tracks that you might like and lets you listen to them using the iTunes Music Store.

Tuesday, December 9, 2003

SpamSieve 2.1

SpamSieve IconSpamSieve 2.1 includes the following enhancements:

Monday, December 8, 2003

Cocoa Enumeration

Jonathan Rentzsch is back with a post about the macros he uses to tame Cocoa’s enumeration idiom. Here’s the macro I’ve been using:

#define foreach(object, enumerator) 
    id mjtForeachEnumerator ## object = (enumerator); 
    if ( [mjtForeachEnumerator ## object respondsToSelector:@selector(objectEnumerator)] ) 
        mjtForeachEnumerator ## object = [mjtForeachEnumerator ## object objectEnumerator]; 
    SEL mjtNextObjectSEL ## object = @selector(nextObject); 
    IMP mjtNextObjectIMP ## object = [mjtForeachEnumerator ## object methodForSelector:mjtNextObjectSEL ## object]; 
    id object; 
    while ( (mjtForeachEnumerator ## object) && 
            object = mjtNextObjectIMP ## object(mjtForeachEnumerator ## object, mjtNextObjectSEL ## object) )

Sunday, December 7, 2003

A Balanced and Fair Look at Objective-C

Jonathan Rentzsch has written a great article about what he loves and hates about Objective-C. [Update (2015-05-09): Here’s an link since the original site is down.] I’ve wanted to write this article for a long time, but now Rentzsch has saved me the time and also done a better job than I probably would have. Now I can just cover the places where I disagree or have something to add.

Love 7: Key Value Coding
I like Key Value Coding, too, but I think it’s really part of the framework, not the language. It’s made possible by Love 3: (Fairly Good) Runtime Object Model.
Hate 1: Method-call Syntax
I think the Smalltalk-style interspersing of the method name and the parameters (contra keyed parameters) is a big win. This is probably my favorite part of Objective-C. The square braces, though by no means bad once you get used to them, are kind of ugly and annoying for editing. (It helps to use a BBEdit glossary item such as #inline#[#select##insertion#], coupled with the Balance command.) Smalltalk uses parens instead of braces, and you can omit them in certain circumstances. I don’t know whether this would be possible with Objective-C, given that it has to be compatible with C’s grammar.
Hate 6: Initialization Idiom
This is kind of a restatement of Hate 2: Lightweight. I agree that assigning to self is disturbing, even if it affords a little extra power. However, I don’t think it’s fair to blast Objective-C because many of its users like to put assignments in conditions. This is a feature inherited from C, and you could say that deficiencies in Objective-C encourage the use of this idiom. But it doesn’t bother me. I’ve read about how people accidentally use = instead of ==, and how some experienced programmers like to contort the order of their equality operands to help catch this error, but I don’t think this has ever bitten me—so I vote for the extra expressiveness.
Hate 7: No Stack Objects
This is on the right track, but I’m not convinced that stack objects are the right solution.
Hate 10: Messaging nil
I’ve got mixed feelings on this one. I really like the expressiveness of being able to message nil, for instance with locks, broadcasters, and releasing. Wacky idea: perhaps there should be a way to tell the compiler (via a type modifier, perhaps) in which cases you want to be able to message nil silently.
Hate 14: id should be id*
I think this is historical. Originally, all Objective-C objects had type id, and you were supposed to treat them like primitives, not pointers. It was only later that static typing, such as NSString *foo, was added. So it might be more appropriate to ask why we have to write NSString * instead of NSString.
Indifferent 2: Memory Management
Conceptually, this doesn’t bother me, but my intuition is that the hybrid scheme is the worst of both worlds, performancewise.

And the conclusion:

ObjC is a mediocre language propped-up by a great framework.

The framework is certainly the gem. Whether the language is mediocre depends on what you compare it to. It’s no Dylan, but I generally like it better than C++ and Java.

Further reading: the discussion on Erik Barzeski’s blog.


Friday, December 5, 2003

Without Confirmation

SpamSieve users can delete rules and words from table views by pressing Delete. I’d like to add an option to delete without confirmation by holding down a modifier key. Which should it be?

In many applications, such as the Finder and BBEdit, holding down Option removes the ellipsis from a menu command, so that you can use the command without confirming it or specifying any additional options. This is definitely the right behavior for menu commands, however even though SpamSieve aliases the Clear command in the Edit menu to the Delete key, I doubt most users think of pressing Delete as a menu command.

Internet Explorer’s Favorites window is more similar to the situation in SpamSieve. It’s a list/table that uses Delete to delete with confirmation and Command-Delete to delete without confirmation. However, I can’t think of any other programs that work this way.

Thursday, December 4, 2003


I’ve long shied away from LCD font smoothing because the colored artifacts bothered me. However, after some convincing I decided to give it a try. After a few weeks, the colors are still there but I no longer really notice them (except when using Exposé) unless I’m trying to see them. When I switch back to CRT font smoothing to take screenshots, the text seems noticeably less black.

Similarly, now that I’m used to Panther, when I switch back to Jaguar to do some testing the window striping looks much more pronounced than I remember.

Open and Save in Panther

Eric Blair mentions that there’s a hidden Go To Folder command in Panther’s file choosing dialogs. It’s activated with Command-Shift-G, just like in the Finder. This came in handy a few weeks ago when I was explaining to a customer how to open a file in an invisible folder.

Panther’s incarnations of these dialogs are the best since Mac OS 9, but I still make mistakes when I try to navigate them with the keyboard. Either the key commands aren’t consistent, or my brain is too hard-wired to the old keys that I don’t even know what I’m doing wrong. For instance, a few days ago I was trying to syntax check a folder in BBEdit, and I kept accidentally choosing a folder instead of drilling down a level.

Mac Community

Mike Wendland, who switched to the Mac one year ago, lists five reasons why he won’t switch back, including:

The Mac community—I used to think they were fanatical nuts mesmerized by the cult of Apple. Now, I find them to be the most friendly, creative, caring, sharing, connected, informed and intelligent group of computer enthusiasts I have ever encountered.

Wednesday, December 3, 2003

Macworld Editors’ Choice Awards 2003

Congratulations to the winners of the 2003 Macworld Eddy awards, particularly Bare Bones, Ranchero, and the Safari team—makers of great software that I use every day. Thanks also to Macworld for honoring SpamSieve with an Eddy and to everyone who has supported SpamSieve, in one way or another.

Tuesday, December 2, 2003

ATPM 9.12

The December issue of ATPM is out.