Monday, September 26
All, right, I'm sick of people reporting that Mac OS X is 'mostly' virus-free. It is, as far has been proven, ENTIRELY virus-free. Macs are not magical, and one day there will be virus that infects them. However, I don't think it's happened yet, and I think it's time we, the Mac community, started saying, "No, we don't have any viruses."
Seriously, if a reporter asked you, "Hey, do you have herpes?" and you replied, "Nope, I've been tested, no herpes, never," and then they wrote an article with the headline, "Bob Smith: Mostly Herpes-Free," you would, no doubt, flip (assuming your name was Bob Smith). You'd probably sue, even. But we put up with this crap every day, mainly because it's nigh-impossible to prove the negative. We'd need to inspect every hard drive of every Mac owner in the world. So we settle with "mostly virus-free" even though, compared to Windows, we're
Mother Theresa and they're
Pamela Anderson.
Let me be clear: not having had a virus is NOT the same as being immune to viruses. I think part of the reason almost nobody has been willing to stand up on this crusade has been that we get shouted down with cries of, "Well, no OS is perfect; Mac OS X will get its virus!" And I have no doubt we will. But Windows gets a virus every freaking week, and we've never had ONE. I think that's also relevant. Much more so than "Well, someday you won't be so perfect!" (Again, imagine you're about to share a fork with someone who you find out has rabies, scabies, rashes, a cold, the flu, lice, and scurvy, and that person says, "Well, everybody
is susceptible to the same diseases." Yes, true, however, you'd still probably prefer to share with someone healthy
at this moment.)
I'll admit, this crusade didn't start with me. It started on
MacSlash where the news editor
has TIRELESSLY pointed out every time some journalist or company implies that we're infectious.
And, I'll admit, others have come up with the idea of offering a
bounty for Mac OS X viruses before, but I think those plans failed due to the way the challenge was structured. I don't want to
incite someone to create the first Mac OS X virus.
So, here's my plan.
I'm not putting it into effect yet, but I'm soliciting comments, and if nobody can prove it's a bone-headed idea, I'll go ahead with it.
I'm going to offer a bounty of $500 to the first person who can
prove that a Mac running Mac OS X (version 10.0 or greater, and patched to the latest security level available at the time from Apple) was accidentally and detrimentally infected with a virus that exploited a flaw in the base Mac OS X installation (not, say, Microsoft Word) before September 20, 2005. The definition of "virus" will for this contest will be either a virus or worm as described by the
wikipedia. The challenge ends at 23:59:00, October 16, 2005 (which happens to also be my birthday, and by the way I have a thing for nice shirts).
I will only offer this bounty once, and as you can see, the deadline for the viruses to have done their dirty work is in the past. So, if you're planning to write a new virus just to win the challenge, well... that won't work unless you also make a time machine. (Which, frankly, I'd be willing to fund for $500.) This is a
research project, not a programming project: find one of us who has been infected at some time, and tell the world about it.
And, if you can't, then we should declare ourselves "virus-free," and write letters-to-the-editor anytime someone compares us with
Christina Aguilera.
Because we don't roll that way.Labels: mac community
Sunday, September 25
Ok, apparently I wasn't clear enough in my last post, and
some people think I'm completely loopy and/or amazingly arrogant.
That was self-parody. I don't
really think
everyone should quit school. Or
set things of fire.
See, I intentionally tried to pick a obviously completely indefensible position and then defend it, so I picked two things you classically shouldn't advise kids to do. Like "start fires." Which isn't a good idea, in general, see. It wasn't a metaphor. I wasn't saying "Quit school and set the world on fire," it was "Quit School" and "Set Things on Fire." Two
different pieces of advice.
The point wasn't that I'm making shit up to yank everyone's chains. The point was that, although
I quit school, and although
I enjoy setting things on fire, this isn't the path for everyone, and I know it.
To be clear, I'm not trying to make fun of people who
do think it's a good idea to quit school, either.
I'm making fun of the perception, which I saw in some recent responses to my posts, that I think there's a single piece of life advice that applies to all people. Because this blog is just supposed to be about how
I did things. (Yes, it's a very self-centered blog. Shocking, I know, because that's not what you expect in a blog. Sorry about that.) But, you know, my life is the only one I know really well. And I keep saying, this is just, like, a travelogue. And just because I decided to go through, say, Wisconsin on my way to Seattle doesn't mean I think everyone else has to. But I am going to write, "Man, if you want some gooda gouda, try Wisconsin!"
Which is why it's ironic that STILL some people flamed me. I guess it wasn't clear enough. For the record, I think college is a pretty neat way to learn some stuff, but some college experiences are less-than-fun. I actually don't think kids should go to college to learn a trade, because most colleges fail at teaching this, and it's a waste of money. I do think learning the collected wisdom of our society is a worthwhile goal for anyone, and in fact I'm hoping to one day take some more classes at the UW, but in general education instead of just computer science. (Also, I dropped out one language course short of graduating with honors and distinction.) For the record, I think unit testing is a waste of time on GUI apps written by one or two people (which was the question I was asked), but I'd believe it can be a decent tool (when used correctly) for libraries or logic-intensive programs, with which I don't really have much experience. Also for the record, I think fire is a lot of fun. And I really do love nature, and all that stuff I said about it is the absolute truth to me, and I put my money where my mouth is on that one.
I had thought the sarcasm in my post would be obvious from the liberal cussing, the fact that I make crazy jokes every other sentence, the structural homage to Steve Martin's
Grandmother's Song, the fact that I take such an extreme position and assert it applies to 100% of the people (
"there are no possible dissenting opinions to this advice"), and that I act so incredibly arrogant throughout (
"admit that I am, in fact, the most clever person in the world, and every word I say is like pure gold"). Also, I say,
"if there were some way to disable the posting comments on this essay, I would," which is supposed to introduce cognitive dissonance, because there
is a way, a completely trivial way - there's a little radio switch RIGHT under the words I'm typing right now.

Also
I advise kids to set things on fire. Fire! FIRE!
FIRE! Hello! This is bad advice!
However, apparently a lot of people just assumed I'm an arrogant crazy person. Which, you know, is flattering, and probably true in general, but in this case I'm slightly less arrogant and crazy than you thought.
PS: Don't be oblong and do leave your knees on.
Saturday, September 24
A lot of college students, or at least humanoids of college age who purport to be going to school, ask me, "Hey, Wil, how can I be even half the pimp you are? Or at least .473x?"
"Good question!" I'll respond, because I like to pretend I give a shit. But usually I'll just mumble something about staying off of drugs and not picking your nose too much. Or too little.
The truth is, I've always worried about telling them what I really think, but no more. Not now that I have a blog and can type any old crap I want with no repurcussions. The real answer is simple: "Quit school and set things on fire."
Look, there are some things that are inescapable. One is that school is REALLY, REALLY boring. They lock you in a classroom for like, five or six years, and they drone on and on about some damn thing, and the amazing thing is, YOU PAY THEM. Then, at the end, they're all, "Good luck, sucker, and remember to keep those loan payments coming," and that's that.
In the REAL world, if you have to put up with being bored for someone, YOU GET PAID FOR IT. Also, you get "real-world" experience, which as well all know from watching reality TV trumps "book smurts" every time.
Seriously, if you want to be a student so badly, why not just come to Seattle and watch me eat hot dogs for three or four hours a day? Oh, and you aren't allowed to talk or eat or smoke. (Unless you're smoking hot dogs, on a grill, for me.) And you have to pay me.
So the quitting school part is a no-brainer. But what about fire?
Look, fire is an essential part of man. It's the crucial element that brought us from being animals to being civilized. We learned to cook our meat, so we could make our kills last longer (cooking away the bacteria that built up), and we didn't have to wander around as much. We became an agrarian species, growing tubers that are nasty when raw, then cooking them to make God's personal gift to humanity: french fries. (Back then, of course, we didn't have the french, so we just called them "oonga-mooongas.") Fire gave us warmth in the winter, it gave us protection from predators, it gave us a thing around which we could get lucky ("My god, your skin is so beautiful in the firelight..."), it gave us steam power and thus the entire industrial revolution.
Yet most of us barely see fire any more. You remember when you were a kid, how magical fire seemed? You'd have a candle at your table in the pseudo-Italian restaurant with the red and white checkered plastic tablecloth with the little burn marks in it that your parents would take you to before you were old enough to realize that chef-boy-ardee style ravioli from a can isn't
truly Italian, and you'd mess with it all night until you finally put it out and your parents would act like you'd committed a sin against nature, on the order of sleeping with a turtle. "See what happens! We told you to stop that!" "Now you're to have half-turtle babies, and your mother and I sure as hell aren't going to raise them!"
Your parents had to tell you, "Don't play with matches," which, right there, is a clue to how great fire is, because nobody ever warns you away from doing something that's not totally fun. Nobody's ever, "Don't go to a Billy Ray Cyrus concert, it causes sterility," because, well, duh!
But now where is fire in our lives? Most of us cook on electric stoves now. Electricity heats our houses; if you even have a fireplace in your dorm room (and many don't!) it probably goes unused most of the time. Stupid "light bulbs" replaced candles and sconces for most applications except getting some. (Some people even try to use a dimmer switch instead of a candle for this: "Oh, baby, your skin looks so pretty when I dim the lights slightly... plus the high-pitched whining of the bulb when I do this covers up your high-pitched whining..." Good luck!)
Sure, some of us have BBQs, although even there most people have switched to safe, wimpy gas models, where the flame can never get more than an inch high, nowhere close to your eyebrows. THIS ISN'T FIRE! You have neutered it, watered it down, taken the flavor from it: this is the fire equivalent of the "buttery-like topping" at the theater -- it's worse for you and it sucks. The only upside is it was cheap and easy for them to give you.
In short, we've pushed fire out of our lives in the name of "convenience" and "safety." But in doing so, we've lost an essential part of ourselves. Like the encroachment of our cities on the forests in the most recent stage of man, where we pave and destroy everything natural in the name of progress, and then go and visit national parks and exclaim, "How beautiful is this!" without any awareness of the irony that WE are the ones who banished it from our lives, piece by piece. We complained every time the animals "encroached" on our cities, we killed their habitats as we packed ourselves so densely only squirrels could squeeze between us, and we locked ourselves inside a grid of fast-moving cars that effectively kills all but the most fecund of species.
Then we wonder what's missing from our lives. It's nature. Think about the peace you feel when you're in a forest, under a canopy of trees. Think about how nice it smells. Now imagine you've got a campfire going, and there's that wonderful smokey smell in the air, mixed with the steam from charring meats. (Or, if you're some kind of damn vegetarian, the steam from some kind of vegetable thing that you people eat.) That's home to us. In the name of making our lives simpler, and more convenient, and safer, we've forgotten to include anything that we care about. Anything that stirs our souls. We get into our cars and we choke our way through traffic and we lock ourselves in a room for eight hours numbing our brains and we go out after the sun has set and we never see or smell or experience anything that we, as a species, grew up loving.
We need to remember what beauty is, in every act. We need to plant trees, we need to make our cities safe for animals besides rats, and we need to set things on fire.
--
So: Quit school and set things on fire. This is the best advice I can give you. If there were some way to disable the posting comments on this essay, I would, because there are no possible dissenting opinions to this advice, which applies equally well to everyone in every situation. I just hope posters will be respectful here and admit that I am, in fact, the most clever person in the world, and every word I say is like pure gold.
Thursday, September 22
Recently an innocent reader inquired the following of me:
I'm curious to know how you approach product testing in such a small company. Do you have an established process? Do you use unit testing? Other structured testing? [...] Do you have suggestions specific to solo testing and debugging?
My answer, perhaps more politely phrased, was, like another famous Wil(l), "AW HELL NAW!"
I've certainly known companies that do "unit testing" and other crap they've read in books. Now, you can argue this point if you'd like, because I don't have hard data; all I have is my general intuition built up over my paltry 21 years of being a professional programmer.
But, seriously, unit testing is
teh suck. System testing is teh suck. Structured testing in general is, let's sing it together, TEH SUCK.
"What?!!" you may ask, incredulously, even though you're reading this on an LCD screen and it can't possibly respond to you? "How can I possibly ship a bug-free program and thus make enough money to feed my tribe if I don't test my shiznit?"
The answer is, you can't. You should test. Test and test and test. But I've NEVER, EVER seen a structured test program that (a) didn't take like 100 man-hours of setup time, (b) didn't suck down a ton of engineering resources, and (c) actually found any particularly relevant bugs. Unit testing is a great way to pay a bunch of engineers to be bored out of their minds and find not much of anything. [I know -- one of my first jobs was writing unit test code for Lighthouse Design, for the now-president of Sun Microsystems.] You'd be MUCH, MUCH better offer hiring beta testers (or, better yet, offering bug bounties to the general public).
Let me be blunt: YOU NEED TO TEST YOUR DAMN PROGRAM. Run it. Use it. Try odd things. Whack keys. Add too many items. Paste in a 2MB text file. FIND OUT HOW IT FAILS. I'M YELLING BECAUSE THIS SHIT IS IMPORTANT.
Most programmers don't know how to test their own stuff, and so when they approach testing they approach it using their programming minds: "Oh, if I just write a program to do the testing for me, it'll save me tons of time and effort."
There's only three major flaws with this: (1) Essentially, to write a program that fully tests your program, you need to encapsulate all of your functionality in the test program, which means you're writing ALL THE CODE you wrote for the original program plus some more test stuff, (2) YOUR PROGRAM IS NOT GOING TO BE USED BY OTHER PROGRAMS, it's going to be used by people, and (3) It's actually provably impossible to test your program with every conceivable type of input programmatically, but if you test by hand you can change the input in ways that you, the programmer, know might be prone to error.
So, listen closely, because this is the method I've used since the dawn of time, and it works great:
1) When you modify your program, test it yourself. Your goal should be to break it, NOT to verify your code. That is, you should turn your huge intellect to "if I hated this code, how could I break it" as SOON as you get a working build, and you should document all the ways you break it. [Sure, maybe you don't want to bother fixing the bug where if you enter 20,000 lines of text into the "item description" your program gets slow. But you should test it, document that there is a problem, and then move on.] You KNOW that if you hated someone and it was your job to break their program, you could find some way to do it. Do it to every change you make.
When I test Delicious Library, I'm like, "Hey, to make sure my new queue works, I'm going to take a Library of 2,000 items and tell them all to reload themselves simultaneously." Now, honestly, in version 1.x, this is really slow. But, dang it, it works. And since our goal for version 1.x was to have it work with between 1K-2K items, I'm OK with this.
Too often I see engineers make a change, run the program quickly, try a single test case, see it not crash, and decide they are done. THAT IS TEH SUCK! You've got to TRY to break that shit! What happens when you add 10 more points to that line?
2) When you get the program working to the point where it does something and loads and saves data, find some people who love it and DO A BETA TEST. The beta test is often maligned, but the most stable programs I've ever written are stable because of beta testing. Essentially, beta testing is Nature's Way (TM) of making systems stable. You think nature creates unit tests and system tests every time it mutates a gene? Aw hell nah. It puts it out in the wild, and if it seems better it sticks around. If not, it's dead.
Now, if you're a pure-CS kind of person, you're thinking, "But, with beta testing, I might miss some really deep, conceptual bugs that unit testing would find, because there's only certain pathways people will test..." Well, there's really only one rational response to this:
WHO CARES!
Like in nature, any system is going to have bugs. And, again like nature, most of the time, in most situations, you want your system to work. But occasionally, under some circumstances, it could fail. This isn't great, but it is acceptable. The nice thing about beta testing is it lets you focus YOUR precious time as a programmer on the pathways that fail most often under normal use patterns, instead of just finding bugs at random that may or may not ever be triggered, and sucking up your time fixing them. (Hey, if you want to try to fix every bug in your program before you ship, be my guest, but at least fix them in order of how often they are reported, OK?) Unit testing doesn't give you information on how common a bug is, which is the single-most important piece of information about a bug, followed very closely by its severity.
Look, I know it's heretical to say "software is going to have flaws." But
everything is going to have flaws. Pilots screw up. Surgeons screw up. People die. Denying this doesn't make it go away, it makes it worse. We need to say not "never screw up," but "make sure when you screw up, you recover nicely."
Make sure that the flaws your program ships with are the least-common ones possible, given the time you have to fix bugs. Honestly, crashers are more important than, say, drawing bugs, but if 1,000 users report a drawing glitch, and one reports a crasher, which one should you fix? THE DRAWING BUG. DO THE MOST GOOD WITH THE TIME YOU HAVE. It's your duty on this earth, and it's also the fast route to success.
Now, all this is NOT an excuse to write crappy subroutines and say, "Well, it'll got caught in the beta test." You, as a programmer, should be programming EVERY LINE as defensively as possible. You should assume that every other method in the program is out to kill you, and they are intentionally passing you corrupted buffers and pointers, and it's your job to handle all that crap and make the best of it. (And, if you can repair it, do so, and if not, raise an exception so you can catch it in beta testing, instead of silently failing and/or corrupting data.)
Let's sum up: Write good code to start with. Write every routine assuming that it'll be called by chuckle-heads. When you modify your program, test it yourself, and TRY to get it to fail, don't try to get it to pass. Then set up a real beta program, with a good pathway for sending in feedback and categorizing it, and let the beta-testers do the rest.
Testing is hugely important. Much too important to trust to machines. Test your program with actual users who have actual data, and you'll get actual results.
--
November 20, 2005 followup: My comments here have been widely reported, and sometimes misconstrued because of my own failure to disclose the boundaries of when and why I don't use Unit Tests. I was thinking of writing a follow-up, but
bbum has done it for me, and I agree completely with what he says. So, please consider his post as the continuation of mine, only, you know, written by him.
Labels: code
Monday, September 19
Drunkenbatman, whose real name shall forever be shrouded in semi-mystery unless you read
MacTech magazine, has invited me to join a
roundtable he's throwing together, of various and sundry developers and software types. I don't think it's literally a "round table"; I mean, I suspect it'll be one of those cheap folding long tables you always see at these kind of events, maybe with a white tablecloth thrown over it if they're being really fancy.
Frankly, an
actual roundtable wouldn't work in this case, because the idea is that we're up on some sort of dias and there's an audience and we're talking with them. So, if we were just staring at each other around a round table, backs to the audience, it'd probably be a lot less fun.
Leaving aside the geometry of the table itself, I'm excited to have been asked to participate. It's in Chicago on the evening of October 21, at the
Adler Planetarium, which is pretty swank. Admission is free! I'll be bringing the latest build of
Delicious Library 2 to show after-hours! And my best shirts! And we'll have singing frogs!
I'm
flying out special for this event, which is something I almost never do, so if you're in the Chicago area (or you like driving) please come up and join our little chat, or I'll feel pretty stupid. But, then again, maybe that's your plan. Oh yah, I'm onto
you.
Labels: mac community, stories
Sunday, September 18
[October 29, 2007 - Note this post was written for 10.4. Under 10.5, our tests indicate JPEG2000 is now actually faster than JPEG to decode at any size; sometimes a TON faster. This is awesome news. Most of the following post is now just plain wrong, but I'm leaving it for posterity.]
--
As research for a project (-cough-
Delicious Library 2 -cough-) on which I'm slaving away, night and day, I did some timing tests to see how Apple's implementation of JPEG2000 performed, especially when creating a thumbnail image from a larger image (as compared to JPEG, which I've used a lot).
As background, I should mention that
Delicious Library (1.x) currently stores three separate JPEGs each cover image it downloads from Amazon, pre-rendered (with gloss) and downsampled into three different sizes (small, medium, large). (I store the downsampled images because anti-aliased downsampling turned out to be very expensive.) Every time we draw a cover, we actually draw directly from its appropriately-sized JPEG data, instead of keeping a cached image around, because caching the unpacked images was blowing up memory. (A library of 2,000 items with uncompressed covers would easily take up more than a 1GB of RAM, and we'd start thrashing like mad.) The real beauty to this scheme was that since the images on-disk were JPEGs and we were drawing directly from the data on disk (without changing it in any way), if we ran out of physical memory and some of our textures got paged out, they didn't have to be written to the swap space on the disk; Mach is smart enough to realize that if it has a page that it's mapped directly from a file on disk, there's no point in writing that page out to the swapfile; it can always read the page from the original file again when it needs to. Since writing to disk is the single-slowest thing a program can do, this is a HUGE speed win (if you've got more textures than you have memory).
However, keeping all those fiddly images (small, medium, and large) also increase our memory footprint, not to mention taking up a fair extra chunk of disk space. Wouldn't it be nice if we could just store ONE, full-size image, and then just decompress the first part of it for small images, and more for medium, and the whole thing for large images? (Progressive refinement, as it were.)
Well, as it happens, this is part of what
JPEG2000 was born to do (much like Kris and
"warming it up"). Not only is JPEG2000 more efficient than JPEG (eg, prettier files are smaller), but you can also create a beautiful low-res version of a JPEG2000 file by reading only its first few bytes, and as you read more you can construct larger and larger images, until, when you've read the last byte, you can reconstruct the full-size image. This would be really convenient with Mac OS X's mapped files ([NSData dataWithContentsOfMappedFile:]), because you can map in the entire JPEG2000 file safe with the knowledge that only the first couple of pages are going to be physically read off the disk if you just want a thumbnail (because mapped files lazily demand-page themselves into memory as they are accessed). (And, remember, disk access is the slowest thing your program can do, so less disk access is better.)
And, conveniently, Mac OS X 10.4 ("Tiger") has a new framework for reading and writing images, and it understands JPEG2000 natively (based on the commercial, C++
Kakadu library). And, in this new Apple framework, there's a function CGImageSourceCreateThumbnailAtIndex() where you can create a thumbnail of an image you haven't read in yet, by specifying a maximum side length (kCGImageSourceThumbnailMaxPixelSize). This would be EXACTLY the kind of call in which one would implement the partial-reading of JPEG2000s in order to quickly read in a low-rez versions of high-rez files.
At least, that's the theory. Because I'm a skeptic, I ran timing tests, and it turns out JPEG2000 is, well... you've already read the title of this post. It's slow. 10x slower than JPEG for a standard decode.
But, that's not all. It turns out that exactly the OPPOSITE of the optimization I thought would happen is happening; with JPEG files smaller thumbnails are actually MUCH faster to create than large ones, whereas with JPEG2000 files creating a thumbnail takes about the same amount of time no matter what size it is. That is, Apple has optimized their JPEG decoder to create thumbnails (and done a GREAT job), but they haven't done so with their JPEG2000 decoder (or they did, but did a REALLY poor job; I prefer to think they just haven't tried yet).
The timing tests below were done with a 1292x1319 RGB image. JPEG2000 and JPEG files were created at full resolution with varying levels of compression to try to be comparable in file size (final file sizes given below). Images were unpacked using CGImageSourceCreateThumbnailAtIndex() with the specified maximum side length (kCGImageSourceThumbnailMaxPixelSize) and then CFReleas()ed 100 times for each test.So, good news, bad news. The good news is, with the new 10.4 image reading framework (CGImageSource...), I can read JPEGs and make beautiful, anti-aliased smaller versions of them EXTREMELY quickly compared to 10.3. Under 10.3, I had to read in the whole JPEG, decompress the whole thing into a full-size buffer, create a small thumbnail buffer, and downsample the whole thing. Obviously, there are a lot of slow parts in that. 10.4's CGImageSourceCreateThumbnailAtIndex() is a godsend in this case -- I can store one large JPEG per book/DVD/whatever and use only the bit of the JPEG that I need for a given size.
The bad news is, right now, JPEG2000 is just not fast enough to use in real time. I've heard that, in general, it's just a slow format, so I'm not bashing Apple here; their implementation may be 40x faster than anyone else's, for all I know. But it's still 10-20x as slow as their JPEG decompression for thumbnails, and that's what matters to me in this case. (But, for example, if I were distributing an online game and were going to decompress my graphic assets only once, I'd use JPEG2000, since it's higher quality and smaller and has full alpha.)

I ran some various tests on JPEG2000s to see if the data I got was anomalous, but apparently it is not. One interesting note for me was that more compressed JPEG2000s don't decompress faster than less compressed JPEG2000s at the same image size. Who knew? Now
you do.
--
Followup (9/19): The news gets even better, as it turns out 10.4's CGImageSourceCreateThumbnailAtIndex() is 3-7x
faster at creating JPEG thumbnails than the method I had to use under 10.3: creating a CGImageRef using CGImageCreateWithJPEGDataProvider() and then drawing it (with antialiasing turned on) into a smaller window.
How often do you get to speed up your most time-critical portion of code by 3-7x? Go Apple!
Labels: code
Saturday, September 3
Today, I complain about something that I really
wanted to like, but cannot any more. My Palm Treo 650 phone. It is a cautionary tale, one from which we can all learn a lesson. Maybe not a lesson on the level of "don't stuff the government with your idiot cronies and then be surprised when it doesn't function when disaster strikes," but those kinds of lessons apparently need to be learned the hard way, again and again. (While I'm on the subject, Delicious Monster is donating our 2005 Q1 Amazon revenue to disaster relief, since, you know, the richest federal government in the world is congenitally incapable of doing anything that might be mistaken as "good," since all our money is busy being spent toppling nations.)
What was I talking about again? Oh, yes, phone. I used to really wuv my Treo, but now I've taken to hating this device, because I've spent a small fortune on it and countless hours, and it has progressively become less and less functional.
When I first bought it, I spent extra to get the "unlocked" version, thinking that I would surely own this lovely Palm longer than I would stay with any particular carrier. I should mention that I haven't owned a Palm in years, because I used to have a beautiful Palm V, made of shiny Titanium or some such. It was a small, gorgeous work of art, made when Palm was at its apex. But it didn't function as a cell phone, and I found I really got tired of having my pockets stuffed with pagers, cell phones, and Palms, so I stopped using the Palm V. And after it Palm released the almost-useless Palm VII, which was ugly, weighed about 700 pounds, and had sort of network access, sort of, but not a phone.
Then they started releasing all these plastic pieces of crap, and licensing their operating system to others so they could release ugly pieces of crap. The amazing thing was that I'd hold up my Palm V and say, "Ok, has anything this beautiful come from Palm or Handspring or Sony in the last seven years?" and the answer would always be, "Oh, no, not really, although we have this ugly piece of crap..."
So I used the calendar and contacts in my cell phones, which synced perfectly with my Mac, and made do with their tiny screens and their no-keyboards.
But, lo, a friend showed me his Palm Treo 650, and it had a beautiful screen, and I saw that it was good. So I bought one.
And the keyboard is surprisingly easy to use.
Unfortunately:
• It turns out that the built-in e-mail reader, VersaMail, actually doesn't really delete your mail from your IMAP mail servers. Now, I'm not an idiot when it comes to protocols and stuff, and I've tried it with two separate services, and it simply does not work. Oh, sure, there's a PREFERENCE you can set to delete mail from the server when you delete it locally (also: DUH!), and there's a PROMPT, and then it'll go ahead and merrily ignore you and download the same mail and spam you just deleted, over and over. HEY, it turns out THAT IS NOT USEFUL. In fact, it's completely useless for the way I read mail if I can't delete the junk and transfer the good messages to other mailboxes when I've read them. Apparently this mail reader is for people who literally want to only read their mail, and not actually, you know, DO anything with it.
So, I never use that.
• The web browser, although a truly amazing piece of engineering (with JavaScript and images and all kinds of things), is freaking slow. The 650 has, like, no memory, an anemic processor, and a tiny little capillary to the internet, and so every time you load a page it takes like 30 seconds or so. It can't cache pages, so going back and forth from a google list takes literal minutes.
I have, honestly, tried to use it several times when I was out, and each time everyone around me has lost patience and gone on with their lives before I found any useful info. It'd be like, "Hey, where's the bar?" "Oh, I'll look it up on the internet..." [5 minutes pass] "Uh, I'm just gonna call 611..." "No, really, the page is coming up! I swear."
None of this is really Palm's fault (unlike the mail-reader that can't delete), but it's still a case of, nice try, but I don't use that.
• The messaging system is really nice, but unlike the Danger, you can't talk to people on AIM, you (and they) have to pay 5 cents a page to talk to each other. So, I do use messaging, and I love the keyboard on the Palm, but it really could stand some improvement.
• Syncing with the Mac was an exercise in arduousness. Certainly, it was possible, with enough time and know-how and installations, to install the Palm Desktop software which I'd never use, and set up a fake Bluetooth to serial line, and install the iSync -> Palm Desktop conduits, and enable them in Palm HotSync Preferences, and disable the Palm Desktop conduits, and get the damn phone to sync, once I'd discovered that the group I was syncing to my phone in Address Book had to contain at least one person, not just other groups, otherwise NONE of the people would sync (unlike with my Motorola and Sony-Ericsson phones). And certainly a lot of this was Apple's fault, but, honestly, Palm should have just said, "Damn, every Mac ships with a built-in, shared calendar program and an address book -- let's chuck this crappy custom stuff we've been making and get our software to work well with what Apple's doing!"
• The phone sound quality was always bad (there was ALWAYS a hiss on the line) and it would periodically just hang up in the middle of a call. It was pretty annoying.
I'd like to mention at this point that Palm just spent a gazillion dollars buying the name "Palm" back from PalmSource (who they just spun off) so they can use the name "Palm" all over. This is one of those Dilbert-style management things, where they're all, "We should spin off our hardware and software! No, wait, buy back the name! No, sell! License the fromjub! Re-org! Capitalize our key assets!"
This is always a bad sign for a company. I'm like: Hey, here's an idea... spend your time and money making your products not suck. Nobody gives a crap if you're called Palm or PalmOne or Pam or Spam. Your asset isn't your name, you dickweeds, it's your reputation for having a cool device, which you are destroying by having the device not be cool any more.
So, now Palm comes out with a firmware update they recommend to everyone. Now, here's where the story really takes a tragic turn. First off, it's not just one firmware update, it's like four of them, and you use a different revision depending on what carrier you use. Confidence-inspiring! Because I'm SURE that there aren't going to be 4x the bugs in four different revisions.
But they recommend everyone upgrade, and say that the sound quality gets better, and mumble about other improvements in mail. Sign me up.
Let's talk about how not to do an upgrade, shall we?
• Don't come out with an upgrade that simply cannot be loaded into the anemic memory you provide for your device without the user deleting the programs that come with the device. That sucks!
• If you go ahead and do the above, then for gosh sakes write a nice custom program on the computer that will unload everything from the device, upgrade it, and then put everything back. Don't just provide instructions on your website on how to create a second, dummy account on your computer to do the syncing with a minimal system install. If you ever find yourself writing an upgrade where EVERY user is going to have to create AN ENTIRE SECOND ACCOUNT JUST TO UPGRADE THEIR STINKING PHONE, you are PROBABLY MAKING A MISTAKE. TAKE SOME OF THE FUCKING MONEY YOU SPENT BUYING THE WORD "PALM" AND SPEND IT ON WRITING AN UPGRADER.
Ok, so after an ENTIRE evening and part of the next afternoon trying, I got my phone upgraded and working again. It had lost all its settings and no longer knew about my computer, which meant I had to set up syncing again. Palm warned me to use the newer version of Palm Desktop with this newer firmware, so I downloaded it, as well, and after dancing the magic dance for about six hours, I had my Palm syncing once again.
Here's the worst part, though: syncing ONLY worked because the computer already knew about the Palm, and was still happy to talk to it, even though the Palm had forgotten about the computer. (If only ex-girlfriends were so forgiving!)
The next week I have a computer crash. I get my drive replaced entirely. Here's where the REAL FUN starts. Obviously, I need Palm Desktop to sync with the Palm again. So I got to palmone.com. Except, wait a minute... the software that they said was REQUIRED to sync with the new version of the Palm is gone. Replaced with a page that says, "Mac users: Sorry, we took the new version down. Just use the version on your CD. Except we told you not to. Good luck!" For the last two weeks, it hasn't been on their web site. TODAY, they've added it back.
Now, again, I'm going to make a short list of things you can do with your money instead of spend it buying the word "Palm":
1) YOU COULD MAKE YOUR SOFTWARE WORK WHEN YOU REQUIRE EVERYONE TO UPGRADE.
2) FOR REAL.
Hmm. Well, problem is solved now, right? Because now I've finally got the new Palm Desktop from Palm, so I can dance the magic dance again (install Palm Desktop, and, under Tiger, just click button to install Apple conduits) and maybe sync.
Except, here's the panel from when I paired my phone with my new Mac:

Hey, be sure to zoom in on that photo. That's right, after the firmware upgrade, there are NO SUPPORTED SERVICES on my Palm. I can't use it as a dial-up modem any more, even though I'm paying extra to get all-you-can-eat data from Cingular. No point in that! And I can't sync with my phone, nor dial with it!
Heck, I'm not even sure why I bothered pairing it with my computer, because it sure as hell can't do shit! What an idiot I am!
Now, this may be Apple's fault. Who knows? Except, here's my logic:
• All these things worked with my Palm and my Mac.
• Palm upgraded the Firmware
• Now none of these things work.
∴ It's Palm's fault.
But, wait, I can still go into iSync on the Mac and tell it to look for devices. Maybe it'll pair up with the phone anyways?

Hah! Denial! It's not just a river in Egypt, that has overflowed for thousands of years and yet still our leader can't grasp the concept of rivers overflowing.
But, hmm. Maybe I can hack around a bit. I run Palm Hotsync Manager, enable the Bluetooth connection, and check the conduit settings. The iSync conduit isn't enabled, since iSync couldn't find the Palm. However, when I enable the conduit, SUCCESS. The Palm shows up in iSync, and I can finally, finally, update my address book and calendar on the Palm. Sure, I still can't use it as a modem, but even getting back basic functionality seems like a godsend after all this time using the Palm as a dumb phone.
And, a dumb phone it is. Because, see, the upgrade woes are not the only problem with the Treo. Sure, with the upgrade, the sound got better, but here are some other fun fone features:
• If you don't disable the touchscreen when you're on a call (using preferences), you'll press the "hold" soft-button with your cheek. A LOT. A WHOLE LOT. EVERY SINGLE CALL, EVEN. There's no way to know you've done this if you're talking, so you'll just talk and talk for a while and then finally notice the person isn't responding, and then when you look at your phone you notice they've been on hold this whole time, and since they don't know why it suddenly went silent, they'll have hung up. But if you DO disable the touchscreen, well, you can't touch the buttons and put people on hold and the like.
• About half of the time now, my phone rings once and then instantly sends the person calling me to voicemail, with no record that anyone called. Not in the logs or anything. Which is amazing to me, because I'm like, "Hey, didn't you just ring? How come there's no log of an incoming call?" And the phone is all, "Ring? I'm not sure what you're talking about?" And I'm all, "Well, it seems awfully suspicious that I THOUGHT I heard a ring just now, and now, 20 seconds later, you're telling me I have new voicemail, but you never told me I had an incoming call, and it's not in the log." And the phone is all, "¿Que? No habla englais."
Now, admittedly, this happens a lot when the phone is in my pocket, so possibly my pocket is magically always pressing whatever button is set to "send this to voicemail and also forget you ever received it." And if it's my pocket doing it, you might call this user error, except, you know, I'd would ALMOST THINK that a phone would be DESIGNED to come out of a pocket while ringing and NOT HANG UP on the person calling. Because, see, this is amazingly annoying. I've had entire days where no calls get through, and I have to check voicemail every couple minutes. EXCEPT...
• The touch-tone keypad often sends double digits when you press a single digit key, on either the touch screen or the keypad. So, if your voicemail password is, say, "1234" (mine is
not, nice try), you'll send "122344". Now, you may think this sounds like user error, but it happens about half the time for me. And, here's the rub, the PALM ITSELF says that you typed "1234". I mean, there's a record of what you typed right there on the screen, and it's clearly been typed correctly. Except, no, it's sending doubled digits. SO I CAN'T GET INTO MY VOICEMAIL.
I only found this out because I called my pharmacy's refill service, and when I typed in my refill number the computer repeated it back to me, only with half the digits doubled. I was like Ellen Feiss, all "duhhhh?", and I typed it again, and they repeated it back doubled again, and I typed it again, and the computer is all, "Please hold while we transfer you to a real person, IDIOT..."
Oh, and when you press the "#" key on the keyboard it sends the "#" keytone FOREVER, although "#" works on the soft-screen. I'm not saying "FOREVER" as in, "amazing long," I mean, IT ACTUALLY WILL NEVER STOP. IT JUST KEEPS SENDING #.
Is this a feature? Because I don't find it useful. I think this is pretty stunning, because, you know, it's not that uncommon for a computer to be all, "Give me such-and-such a number, followed by the # key," and yet NOBODY at Palm has EVER hit that key on their keyboard, and noticed IT GOES ON FOREVER? It's really obvious, on account of the not-stopping.
--
Let's talk about the philosophy of complaining a bit. I didn't sit here for an hour typing this in because I hate Palm and want them to die. I honestly don't have that kind of free time. I'm complaining because I want them to do better. I want them to create a device I can love again, the way I loved my Palm V. It was, for its time, a truly beautiful piece of work, inside and out.
Now, the Treo does a lot more than the V, but at every step there's a little gotcha. A little rough edge that nicks you. To me, it's too much like using Windows; sure, the features are there, SORT OF, if you fight enough for them. But after a while, you get worn down, and you stop trying.
For $600 (unlocked), this should be an amazing phone. It should knock my socks off. I can buy a Motorola flip-phone for like $120 that is half the size and has all the features I can use on the Treo right now, and it'll work without all the gotchas and magic dances. (I know; I've owned a couple before, as well as two models of the execrable Sony-Ericsson line (Motto: We put the "slow" in "Damn this crappy phone is slow!").)
I like my keyboard. I like my big, bright screen. I like having a general-use computer with other software. But somebody at Palm needs to start thinking like Steve Jobs. Someone needs to make it her job to say, "This detail sucks, and if the details suck the whole thing sucks, and if our product sucks we suck, so we're going to stay here and we're going to fix this and we're not going to ship until the phone doesn't suck."
Good luck, that person.
Labels: interface design, stories