The Magic Beans

“Whenever possible, if you have the opportunity, trade the cow for the magic beans.” — Anon.

I don’t know where I heard this but it struck me as a whimsical way of saying what sages have been saying since the dawn of time — it’s better to take a chance on something great than accept mediocrity with safety. You may have heard it put one of these more creative ways:

“Fortune favors the bold.” – Latin Proverb

“The only thing we have to fear is fear itself.” – Franklin D. Roosevelt

“A ship in harbor is safe, but that is not what ships are built for.” – John A. Shedd

“You miss 100% of the shots you don’t take.” – Wayne Gretzky

“In the end, we only regret the chances we didn’t take.” – Lewis Carroll

“Twenty years from now you will be more disappointed by the things that you didn’t do than by the ones you did do.” – Mark Twain

I’ve long thought this idea shaped my professional life and came here to talk about it. I needed an appropriate picture for the article, so I asked ChatGPT 4 Omni (aka 4o) to create an image. I gave it the quote about the magic beans and it gave me this image:

That’s pretty good for not really giving it much to work with, but the 10-foot-tall smiling cow and the colorful beans all over the ground didn’t seem right.

I asked ChatGPT to “try again” and got this even more terrifying image:

Now the ground is covered with a rainbow of grapefruit-sized magic beans. In the background, a furry elephant looks on, as does a 4-foot-tall house cat.

Pointing out to ChatGPT that it is obsessing over the beans, I gave it this more direct prompt: “Let’s try a picture in landscape format where a farmer walking a cow along a road has encountered an old man, and is trading the cow for a handful of beans.”

OK, now somehow the farmer has ended up with both the cow and the magic beans and the old wizard is nowhere to be found.

I told ChatGPT, “You left out the old man, so the picture is a farmer with a handful of beans and a cow, which doesn’t depict the story at all. Also, I think we should say ‘five or six beans’ instead of a handful.” That caused this image to be generated:

We now have fewer beans in the farmer’s hand, but now he has a basket of them and he’s offering them to the cow? Thinking perhaps I’m giving ChatGPT too much freedom to improvise, I give it a very specific prompt: “Two men are on a country road in a pastoral landscape. One man is leading a cow on a leash. The man is middle-aged and appears impoverished. The other man is old and has a long beard. He has the appearance of a wizard, with a hat and a robe. In one hand he leans on a staff. He is holding his other hand out toward the first man, and we can see it contains 4 or 5 ordinary beans. The men are apparently negotiating a trade — the beans for the cow. The first man is intrigued, but hesitant.”

This is OK, except:

  • The cow has 3 legs.
  • The old man has 3 staffs.
  • The old man is holding a leash attached to the farmer.
  • The old man has spilled the beans on the ground and nobody has any in their hand.

Not wanting to give up, I re-wrote the prompt: “Two men meet on a country road in a pastoral landscape. The first man is middle-aged and dressed poorly. He is leading a cow on a leash. The second man is old and has a long beard. He wears a hat and a robe. In one hand he leans on a staff. He is holding his other hand out toward the first man. In his extended hand are 4 or 5 ordinary beans. He is offering the first man the beans as the purchase price of the cow.”

Now we’re getting somewhere. The cow is the right size. He’s on a leash held by the farmer. Unfortunately, the old man with the staff has spilled all the beans on the ground.

Undaunted, I use the selection feature in ChatGPT to highlight the old man’s empty hand and the pile of beans and write: “You have placed a pile of beans on the ground and none in the man’s hand, where they belong. In all other ways, this is perfect. Can you modify the image so there are no beans on the ground and 4-5 beans in the second man’s hand?”

Finally, I got this image:

The old man has more beans than he should, but I’m calling this a win.

The good news is that this is the best I’ve ever gotten ChatGPT to eventually produce a good image.

Anyway, I came here to tell you to always trade the cow for the magic beans. Years ago I did that when I took my little Bible program to Parsons Technology and built the QuickVerse empire. I left a very secure job as a software developer for the company that let us talk to astronauts on the Moon and which built space shuttles, and traded it for the idea that I might be able to feed my family by writing Bible study software. It worked out well. Then 10 years later I traded the security of that job and started my own company. The two experiences have been very different, but I can’t say I’m not happy with my choices.

Who needs a cow? Take the beans.

Working Without a Net

In 1988 we took our kids to Circus World in Baraboo, WI. We had the good fortune to see Enrico and Debbie Wallenda performing on the high wire. The crowd was small, so we had a chance to chat with them after the show.

I noticed that, while they performed without a safety net, they had laid out some tumbling mats under the wire, which was some 20-30 feet in the air. “Why bother with the mats?” I asked Debbie. “Our insurance company won’t let us perform without safety equipment,” she said.

2015-06-04 07.57.00Enrico and Debbie come from a family of circus performers that goes back to the 17th century. They grew up on the wire. They know what they’re doing. The safety net is unnecessary. It would just slow down their set-up and be one more thing they’d have to carry from show to show. And it would be an insult to them. Amateurs need and use safety nets. The Wallendas just don’t fall.

Well, they do, but no more than once each.

I’ve been programming since about 1974 and doing it professionally since 1982. I remember my ham radio buddies talking about these cool new things called “microprocessors” in 1972, and was actively programming for them through the entire history of the “personal computer revolution”. I wrote a machine language debugger for the Motorola 6502 just for fun back in the early 80’s. I was working with touch screens in 1982 while the company that would eventually put one on an iPhone was just beginning to experiment with mice and graphical user interfaces.  I wrote drivers that allowed CP/M systems to store data on “magnetic bubbles” that raced along a track driven by an electromagnet. I was writing code to calculate position using GPS when there were only about 8 GPS satellites in orbit and we had to calculate what ridiculous time of the morning we’d have to come in when we would be able to see the required minimum of three of them at the same time for testing our software.

Over the years I’ve programmed in assembly language, Pascal, PL/I, Modula 2, FORTRAN, COBOL, SNOBOL, LISP, BASIC, RATFOR, C, Forth, JOVIAL, Ada, C++, NewtonScript, PHP, Objective-C/C++, Perl, Java, JavaScript, C#, and VBScript. I’ve written a number of compilers and interpreters for lesser-known and proprietary languages. I’ve written programs for Atari, CP/M, MS-DOS, VMS, Windows (desktop and server), Mac OS and OS X, Newton OS, various flavors of Unix, Windows CE, Palm OS, Android, and iOS.

When I’m making updates to the scripts and pages on our Laridian website, I operate directly on the live server. From time to time that means if you happen to be on the page I’m on when I make a mistake, you’ll see an error message when you load the page. But that happens only rarely. When working on a critical part of e-commerce code, I might test on a private page before going public, but often that isn’t practical.

Running a beta testing program with outside testers, especially for a platform like iOS (which requires encrypting the app in a particular way that allows only selected devices to run the program), is difficult and time-consuming. So most of the updates I do for Mac and iOS programs are just tested by me before they are shipped. Often, I’m a better tester than real customers, because I know the scope of the changes I’ve made to the code, and I know where it is susceptible to error. For example, all the testing of synchronization of user data was done in-house. I was able to set up both common and unusual situations to verify how the system would handle the data without putting any real customer data at risk. When the time came to put that system online, it just went online without any beta testing.

So I sympathize with the Wallendas. That safety net takes a lot of time to set up. We know we’re not going to fall. And it takes away from the perception of professionalism — anybody can walk a tightrope when there is no harm in falling.

But when we fall, we fall hard.

Last weekend I shipped an update to PocketBible for iOS that was not tested by outside testers. The majority of the changes were to accommodate the larger screen of the iPhone 6 and 6 Plus. I have an iPhone 6, and I can emulate the 6 Plus in the development environment. Those changes were well-tested.

The other type of changes were related to what happens when you change the password on your Laridian account. Previous versions of the program assumed you were logging into a new account when you entered a different password, so they blocked you from sync’ing your notes, highlights, and bookmarks with the server (so as not to corrupt the “other” account’s existing data, nor corrupt the data on the device with data from the “other” user). Furthermore, they would delete all your books (assuming, again, that you are a different user with a different library of books). The new version of the program records the Laridian customer ID you’re using while sync’ing your database with the server, and only complains about your user data if, when changing your password, you log into a different customer account. Furthermore, it doesn’t delete your books. (I plan to handle that a different way in future releases.)

So while testing the screen-size changes on the iPhone 6, I also tested the new way of determining if you had logged into a different account. It worked great. What I didn’t count on was that Apple had completely changed the way certain user interface objects worked on the iPad sometime in the year since I had issued the last PocketBible revision. As a result, iPad users couldn’t update their data to support the new customer ID tracking method. My testing on the iPad consisted of bringing the program up and trying a few things to make sure it wasn’t completely broken. Since the bulk of my changes were related to laying out the user interface on the larger iPhones, my testing focussed on making sure I didn’t break any layout code on the iPad. I already knew the customer ID tracking worked from my tests on the iPhone.

I joked with one long-time PocketBible customer that I didn’t want to take time to do a beta because I knew he would find problems that I would have to fix. So I shipped version 3.2.0 without the benefit of his help.

Once Apple approved the new version and I installed it on my iPad and saw what was happening, I knew I was in trouble. I began thinking about how those tumbling mats were going to feel when struck from this height.

When Karl Wallenda fell to his death from 120 feet, the family went ahead with their show the following weekend. That’s what professionals do. In my case, I admitted to the mistake immediately, pulled the app from the App Store, posted prominent notices on our blog and on Facebook, and went to work to find the problem. By 2 AM I had the first round of fixes made to the code. After a short nap, I found and fixed the rest of the problems (which required examining about 300 places in the code) and was ready for beta testing by mid-afternoon. We went through three beta versions in 24 hours, and I didn’t upload the final build to Apple until I had a clean bill of health from the testers.

Apple cooperated by approving my request for expedited review, and accomplishing that review within an hour.

In the end I was able to stand up and walk off the mats under my own power. The fans were great; they encouraged me by applauding through the whole thing. I was concerned that some would want their money back, but I got not a single complaint.

While I probably won’t be shopping for a safety net, I may consider doubling the mats.

Advancing Technology by Lying to Developers

Mobile devices have been increasing in screen size, screen resolution, memory, and other capabilities on a continuous basis from the time I got my first Apple Newton MessagePad in 1993. Back then screens were about 336×240 pixels, and each pixel was either on or off — no color. There was a total of 4.625 MB (that’s MEGA bytes) of memory. My first Windows CE device was probably my HP 620 LX in 1998. It was a “clamshell” design with a 640×240 screen and 16 MB of memory.

The thing we knew intuitively from being involved in personal computing since there was such a thing as personal computing was that “change is the status quo”. Our programs never assumed how big the screen was, because we knew our program would need to run next week on a bigger screen, so we wrote our code so that it queried the operating system to ask how big the screen was before dynamically laying out its user interface to fill all available pixels. We never assumed that devices would always be monochromatic, so we wrote our compressed file format to accommodate “words of Christ in red” before they could even be displayed in anything but black on a greenish screen. And even though the entire Bible wouldn’t fit in memory of those first devices, we plowed ahead with the best compression we could manage and a user interface that supported displaying two Bibles simultaneously, knowing that very soon you’d be able to get not just one of our Bibles but two whole Bibles onto the device at the same time.

Fast forward to the iPhone in 2007. When you work for Apple you apparently get big-headed and begin to think you’re among the smartest programmers in the world. Nobody can match your brilliance. Each generation of device you work on is “magical”. It has capabilities and features that nobody could have imagined even six months ago. Features like a more memory and a bigger screen.

Since you couldn’t imagine those features last year, and since you’re God’s gift to technology, you’re positive that nobody else could have imagined those features. So what’s going to happen to all those apps written by people “too dumb to work at Apple” when your new device with a bigger screen comes out? Why, they’ll crash, of course.

Not PocketBible.

You only have to be in this business a week to realize that you can’t hard-code your program to assume a particular screen size. But Apple does this with every single device. Up until iOS 8, we had to prepare a “splash image” to display when the program launched in every possible size and resolution. Currently, that means we have to create launch images in 13 different sizes, one for each iPhone screen size that has ever been shipped, in both portrait and landscape orientation.

Current iOS launch image requirements

Current iOS launch image requirements


If instead they allowed us to manipulate a single image at run-time, we could do all of these with one PNG. But they require us to know every size of every screen we might ever run on (by the way, the image above omits devices prior to the iPhone 4, which would add another half-dozen sizes if they hadn’t already been abandoned by Apple).

This isn’t about managing lots of images. It’s about a philosophy that can’t think past yesterday.

Because of this philosophy, when a bigger screen comes out, Apple either “letterboxes” old apps (putting black bars in the empty space that the program couldn’t possibly imagine would ever be there) or scales them (allowing them to believe the screen is no bigger than last year’s device, then scaling up everything they draw to fill the bigger screen). They believe they are saving developers from having to re-release their apps every time a new device comes out. But in reality, they are requiring every developer to re-release their app to jump through whatever hoop is required to get Apple to stop letterboxing or scaling their apps.

iPhone 6 scaling

Pre-iPhone 6 version of PocketBible on the left gets scaled up. Adding a “launch screen” (which is unrelated to drawing text) tells iOS not to lie to us about the screen size, producing the sharper image on the left with absolutely no changes to PocketBible code!


With iOS 7, there was a special checkbox we had to check to tell the OS that we understood their new semi-transparent user interface elements. With iOS 8, in order to convince iOS not to scale your app (producing blurry text), you have to provide a special, scalable launch image that works on any screen size. (Gee whiz, 2015 and we’re finally recognizing that screens might get bigger in the future! Thanks, Apple!) Until you do that (which requires re-releasing your app), iOS will lie to you about the size of the screen then scale your user interface up to the bigger physical size of the screen, producing blurry text.

Oh, and you still have to provide those 13 launch images for older devices.

The result of this policy of “technical advancement by lying to developers” is that instead of one guy at Apple having to write zero lines of new code, hundreds of thousands of developers have to update and re-release their apps. There would not have been a personal computing revolution in the 80’s and 90’s if Microsoft would have taken this approach. Back then, Microsoft would collect commercial software products and use them for regression testing of new versions of DOS and Windows. After all, you wouldn’t want to do something stupid and break every single app the way Apple does with every release of the iPhone.

This industry used to be exciting. I was like a kid in a candy shop. Technology was changing and we were riding the “bleeding edge”. Now I feel like the only grown up in the room. I want to slap some of these Apple and Google kids around and tell them to shape up.

Why I Don’t Care About Swift

Swift is a new programming language created by Apple for use on OS X and iOS devices. The programming world is agog. Apple’s fantastic new language apparently solves all their problems, as evidenced, they say, by the fact that some programmer ported Flappy Birds to it in a few hours.

I’ve been around long enough to see languages come and go. Each claimed to solve all the problems introduced by its predecessors, yet each was replaced by a language that solved all its problems. In some cases, the new language surpassed the success of the language it replaced (C++ and Java); in other cases, the new language faded into obscurity (Modula-2 and Ada).

Lately the motivations for new languages have been dubious. There is a big emphasis on making a language easy to learn and having it hide nasty issues related to memory management and type safety. One review of Swift I read stated, “Apple hopes to make the language more approachable, and hence encourage a new group of self-taught programmers”. While that sounds great, it means that those of us who have mastered our craft after 30 years or more of practice are saddled with the training wheels and water wings that are written into these languages for the noobs.

A classic example is the lack of unsigned integers in Java. The motivation for this was to simplify the language for “new and self-taught programmers” by avoiding errors caused by a lack of understanding of sign-extension. However, for those of us who showed up for class the day that sign extension was taught (that would be day two), we’re left with a language that unnecessarily limits the range of positive integers and requires us to actually have mastered sign extension in order to understand what is happening when we directly manipulate the bits in our integer variables.

Explicit vs. Implicit Typing

One of the simplifications Swift makes is that it infers the types of variables from the values assigned to them rather than requiring the programmer to explicitly type variables. If this was true “weak typing” like I’m familiar with in VBScript, it would be great (though it would come with its own set of problems). But all Swift does is infer the type of the variable from the first value you assign to it.

This actually introduces problems, because it’s not always possible to unequivocally determine the type of a literal value. So Swift gives you ways to force it to interpret a literal value as a given type. Rather than removing the necessity of the programmer understanding types, Swift thus requires “new and self-taught” programmers to have a mastery of types so that they can understand how Swift is working behind the scenes and make sure that their variables have the desired type.

Strings

Swift is said to improve string-handling over Objective-C (the current language used on OS X and iOS). There is certainly room for improvement there. When I first started programming in Objective-C, one of the first things I did was bring over my own C++ string class, as I found NSString to be overly complicated and muddled. Over the years I’ve gotten better with NSString.

I would argue, however, that some of the so-called “improvements” in Swift with respect to strings are differences without a distinction. So instead of this in Objective-C:

[NSString stringWithFormat:@"The value of num is %d", num]

you say this in Swift:

"The value of num is \(num)"

The Swift version is obviously more concise, but it is also less powerful. To add more complex format specifications to Swift you actually have to invoke the functionality of the underlying NSString class, which means the “new and self-taught” programmer, again, needs to understand the details of the implementation in order to do anything beyond the simplest strings.

One of the stated benefits of string handling in Swift is that “all strings are mutable”. One need not worry about whether the string is declared as an NSString (immutable) or NSMutableString (mutable). Well, you don’t have to worry unless you do have to worry — strings assigned to constants are immutable in Swift. So:

var myString1 = "Mutable string"
let myString2 = "Immutable string"
myString1 += myString2    // perfectly legal
myString2 += myString1    // compile-time error

Switch Statements

Swift eliminates the “fall-through” behavior of switch statements, which is said to eliminate bugs caused by omitting the break at the end of each case block. But, oops, sometimes the fall-through behavior is exactly what you want. So Swift adds the fallthrough keyword. It could be argued that Swift eliminates a line of code (the break) while giving the behavior one normally desires. But at the same time, it adds a keyword (fallthrough) that does the opposite. This requires “new and self-taught” programmers to have the same thorough understanding of switch behavior that Objective-C and C++ programmers do.

Single-line Blocks

The Swift compiler will warn you if you omit the braces in any block (such as after an if) and does not allow single-line blocks, thus avoiding this error:

if (x < 0)
    goto fail;
    goto fail;

The code above will always execute one or the other of the goto statements in Objective-C or C++. Even though the second goto is indented, it is not part of the if-block and will be executed if the condition is false.

Swift will warn you about the missing braces and force you to write this:

if (x < 0)
    {
    goto fail;
    }
goto fail;

Or, for those of you who don’t do your braces the right way, this…

if (x < 0) {
   goto fail;
}
goto fail;

This is fine, and hard to argue with. The supposition is that the programmer will immediately recognize the flaw or won’t make the mistake in the first place. On the other hand, I would argue that the same C++ programmer who wrote the erroneous code will write this in Swift:

if (x < 0) {
    goto fail; }
    goto fail;

I always put braces around my blocks, even if they are one-line, so this doesn’t affect me. It’s ironic, however, that while Swift prides itself in eliminating the unnecessary break statement at the end of a case block, it requires two to four additional lines (braces) in if, for, and while statements, which are more numerous.

PocketBible and Swift

I will be more than happy to learn and use Swift for programming on iOS and OS X. I just don’t believe the hype and won’t convert just for the sake of doing something new.

I am a strong proponent of platform-independent languages like C, C++, Java, and, to a lesser extent, Objective-C (the latter is primarily an Apple language, though it has its origins outside of Apple). Such languages allow me to develop code on one platform and re-use it on another. One of the promises of C++ and Java was that you could develop the code for one platform and use it on many others. Swift is an Apple language (the same way C# is a Microsoft language). It only works on Apple devices. While those are numerous, they’re not the only devices out there. So rather than moving toward the “write once, read everywhere” model promised by Java, we’re back to “write everywhere” as each platform requires its own language.

I don’t mind learning a new language. I already jump from C++ to C# to Java to VBScript to Javascript to MS-SQL on a daily basis. For those of us who write code for a living, being multilingual is a job requirement. This is precisely why I care so very little about the supposed advantages of Swift; this isn’t a religious war for me, it’s just a tool. When someone comes out with a new kind of screwdriver, I may or may not buy it until I need it. And then I’ll just buy one and use it — I won’t try to convert all my screwdriver-toting friends.

So will PocketBible for OS X and/or iOS be re-written in Swift? Probably not today, and probably not until Apple requires it. But Swift depends on Objective-C under the hood, so my guess is that Apple will continue to support Objective-C apps for a long time.

Craig 1, Hacker 0

When you purchase a product from our website, you click on a link to download it. The link appears to be legit — just a regular link to a file on our server. But it’s not. The file does not actually exist. We intercept the link and parse it to determine what to download to you.

When geeks like me see something like this, they poke around to see what they can find. When our server sees someone like me poking around, it sends me emails so I can watch them do it, because that’s what geeks like me like to do. No, we don’t tell the customer who’s doing the poking that we’re watching them. In fact, the error message they get tells them to forward the message to tech support. In reality we already know. 🙂

So here’s a customer from Australia doing some late-night hacking. He’s trying to download MyBible 5 for Palm OS without paying for it. Ironically, it’s free so if he really wants it, he can just go through the steps of ordering it and we’ll add it to his legitimate download account. But it’s more fun to try to get a free thing for free without not paying for it.

Two things you need to know: The product code for MyBible 5 is 3MBPGM005, and MyBible 3 is 3MBPGM002. The file name he’s trying to accidentally discover is “mb5setup.exe”. So this is the real link he’s trying to find: http://www.laridian.com/files/1158044/3MBPGM005/mybible5/program/mb5setup.exe

From the log:


http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/MyBibleSetup.exe
The filename requested (\mybible5\program\MyBibleSetup.exe) does not match the product (3MBPGM005). http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/MyBible5Setup.exe
The filename requested (\mybible5\program\MyBible5Setup.exe) does not match the product (3MBPGM005). http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/
The filename requested (\mybible5\program\) does not match the product (3MBPGM005). http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/MyBible51.exe
The filename requested (\mybible5\program\MyBible51.exe) does not match the product (3MBPGM005).

Next he tries to get an older version:


http://www.laridian.com:80/files/1158044/3MBPG3002/mybible3/program/MyBible3.exe
The filename requested (\mybible3\program\MyBible3.exe) does not match the product (3MBPG3002).

Back to looking for MyBible 5:


http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/MyBible5.exe
The filename requested (\mybible5\program\MyBible5.exe) does not match the product (3MBPGM005).

And back to MyBible 3:


http://www.laridian.com:80/files/1158044/3MBPG3002/mybible3/program/mb3setup.exe
The filename requested (\mybible3\program\mb3setup.exe) does not match the product (3MBPG3002). http://www.laridian.com:80/files/1158044/3MBPG3002/mybible3/program/MB3Setup.exe
The filename requested (\mybible3\program\MB3Setup.exe) does not match the product (3MBPG3002).

Here he gets it right! But he can’t download it because he doesn’t own it:


http://www.laridian.com:80/files/1158044/3MBPGM002/mybible3/program/mb3setup.exe
Customer 1158044 is not authorized to download product 3MBPGM002.

Now he switches his customer number to see if he can find a customer who *IS* authorized to download it. But he’s not going to get it without logging in as that customer first:


http://www.laridian.com:80/files/1158045/3MBPGM002/mybible3/program/mb3setup.exe
You are requesting files for customer 1158045 but customer 1158044 is logged in. You must access files through your download account. Exit your browser, then re-launch and go to our Login page to log in again.

Not sure what he’s doing here:


http://www.laridian.com:80/files/1158044/3MBPG3002/mybible3/program/mb3setup.exe
The filename requested (\mybible3\program\mb3setup.exe) does not match the product (3MBPG3002).

And at this point he admits defeat. Craig 1, hacker 0.

An eCommerce Company Wants to Know: Do I Want to Double My Sales?

While searching for something else in my email archives, I ran into this exchange with a sales rep from Digital River who spammed me a few years back asking if I wanted to double our online sales. It’s rather humorous.

Subject: Online Sales @ Laridian

Hi Craig,

How are sales from laridian.com? If we could double online revenue, would you be willing to outsource your web store to Digital River? We have done this for most of our 3,000 software clients and would welcome the opportunity to discuss how we may be able to do the same for Laridian. Please reply if your willing to consider outsourcing your online store.

Sincerely,
John S
Regional Sales Manager
Digital River, Inc.
www.digitalriver.com

Wow. That sounds great. I’m always up for doubling my revenue. Here’s my respose:

From: Craig Rairdin [mailto:[email protected]]
To: ‘John S’
Subject: RE: Online Sales @ Laridian

Hi John!

Sales are great! No reason to make any changes. But you sound like an honest man so I’m willing to simply take you at your word — if you are willing to stand behind it.

Write back if you’re willing to sign a written guarantee that you’ll double our net revenue from Web sales as you’ve claimed you can do in your email.

Of course once we move to Digital River it will be difficult to say what our sales would have been had we not moved, so what we’ll do is take the last three years of sales and find a best-fit line based on monthly net revenue (i.e. revenue less cost of sales). We’ll project that line over the next three years and you will guarantee to send us a check for twice that amount regardless of your actual revenue from our products. At the end of three years we both can decide whether or not we want to continue the relationship.

One-half of each month’s guaranteed payment will be due on the first of the month. The remainder (either the other half of the guaranteed amount or the actual net revenue from sales) will be due within 10 days of the end of the month. If you don’t pay the full amount due in a particular month within 10 days of the end of the month, then we revert back to selling ourselves and the remainder of the 3-year contract becomes due immediately.

I don’t expect to have any expenses associated with the conversion from doing this at our site to doing it at yours. I anticipate that the way the changeover would work is that you would get everything set up on your end at no expense to us, then on the first of some particular month I’d find a check from you equal to that month’s projected net revenue and I’d edit a few lines of code on our site to send customers to your site for ordering, or we’d make a DNS change that would redirect our entire site to your servers.

I don’t expect to have any marketing expenses associated with driving traffic to the site. You’ll handle our online and print advertising as it relates to direct sales. Of course we’ll continue to handle marketing and sales through other channels.

John, I assume you’ve done your homework and you have a rough idea how much money you’re committing your company to, or you wouldn’t have made such claims in an unsolicited commercial email. Of course I trust you implicitly and know that you wouldn’t say something like this if you weren’t fully willing and able to deliver. It must be great to work for a company that can deliver these kind of results! Frankly, I’ve been looking for a Magic Bullet that would double net revenue from our Web site. If you’re willing to stand behind your marketing claims with real money (and I have no reason to doubt that you are), this could be a match made in heaven!

Craig

I assumed that if John was bold enough to claim he could double our online sales that he actually believed he could triple or quadruple them. Otherwise, he’d risk not being able to hold up his end of the deal. So my plan to hold him to his (outrageous) claims should’ve been a no-brainer for him. Apparently not. Here’s his response:

From: John S
To: Craig Rairdin
Subject: RE: Online Sales @ Laridian

Hi Craig,
You sound like a smart business man, so I’m sure you already realize their are no guarantees in business. It is true we have been able to double online revenue for most of our clients, but I’m sorry you misunderstood my email.
Regards,
John

What? I misunderstood that when he said he could double our sales, he meant that he couldn’t double our sales?

From: Craig Rairdin [mailto:[email protected]]
To: ‘John S’
Subject: RE: Online Sales @ Laridian

Hmmm… So when you said “If we could double online revenue, would you be willing to outsource your web store to Digital River?” you never intended to demonstrate your ability to do that in any concrete way? You asked if we’d outsource our store in exchange for double our current revenue, but you had no intention of proving you could do it or standing behind your promises with guarantees.

So what are your potential customers supposed to do? Just believe a guy who spams them and turn over their life-blood to his company with the hope that the spammer knows what he’s talking about? You may have found 3000 other nut-cases with this pitch but you didn’t find one here.

Even though my message was tongue-in-cheek, I’d be willing to actually follow through on the promises made therein. By contrast, your message was a serious invitation to do business together, but you had no intention of standing behind your words with any kind of concrete action. Your willingness to spam me and spew nonsensical marketingspeak with no intention of delivering tells me more about Digital River than you could possibly imagine.

Please remove us from your spam list.

Craig

To his credit, he removed me from his spam list.

I think a business that makes a clear claim in a solicitation for business should be willing to stand behind it. I think my proposal was more than fair, even though I knew he would never go for it. It irritates me when a business makes claims like this and thinks they shouldn’t be held responsible for them.

From the Archives: Managing Craig’s Way

Something recently reminded me of this article I wrote back in September 1994. For you historians, that would have been the month that the Intuit purchase of Parsons technology was finalized. It was revised in 2001. So if any of it sounds dated, it’s because it is.

I assume this would’ve appeared on my original blog back before they were called blogs, but that sounds too early. So I’m not sure why I wrote this.

Management Principles

September 24, 1994

I’ve always been struck by the fact that great people seem to operate on a small set of principles which they consider inviolable. These principles, right or wrong, guide them in all of their decisions. Their decisions, though sometimes wrong because of the wrongness of their principles, are quickly made and internally consistent. Collectively they form the “conscience” or “personality” of the organizations these people inhabit.

I believe it was Ross Perot (or perhaps it was Tom Watson — it was one of those IBM guys) whose management style was described by an employee as “Management by Hanging a Sign.” Mr. Perot would hang signs around the office declaring some axiom of life as only Mr. Perot could have imagined it, and he expected the employees to follow.

Within the religious community, great men of faith are often known by their basic principles. A church I used to go to counted Dr. Bob Jones Sr. as one of their heroes. I can’t count the number of “as Dr. Bob always said…” illustrations I’ve heard in sermons.

And then there’s the Ferengi Rules of Acquisition.

You get the point. I’m not claiming that what follows is anything special, or that I’m the next Bob Jones, Ross Perot, or Grand Nagus Gint. But it seems that there is some value in setting these things down and trying to follow them.

While these principles are not strictly taken from the Bible, I hope they’re at least biblical. I’m a little concerned about “It’s easier to get forgiveness than permission” though I would contend that statement is at least true from a biblical point of view. It may not be the best policy, but it’s true.

This is just a list of those aphorisms I’ve found that I live by in business. Names in parenthesis are the source when I remember where these came from. While the ones I’m claiming as mine are things I really think I came up with on my own, many are pretty simple, and they’re undoubtedly based on principles I’ve heard or read about. When I’m pretty sure I read it somewhere but can’t remember where, I’ve left it unattributed.

Decision Making

It’s better to make a decision than to make a right decision.

Making a decision permits you to move forward. Waiting for all possible information to come in so that the right decision can be made often results in no decisions happening for a long, long time.

This is a good principle to teach to those who report to you, and for you to keep in mind as you report to your boss. A manager doesn’t have time to consider the implications of every decision that has to be made in the organization. That’s why he or she hires people. Those people need to be willing to make decisions and not continuously bring them to the boss. The quickest way to prove you’re dispensable is to be good at gathering facts but slow at applying those facts to daily decisions without the boss’s OK.

Our failures form the basis for our success.

(Russ Novotny)

There’s no such thing as bad decisions and failures. All “wrong paths” taken in the course of getting something done contribute to the overall success of the project. If you hadn’t gone down that “wrong” path, you wouldn’t have learned all those lessons.

Programs which have suffered no false starts nor setbacks tend to be fragile. Making a mistake helps us to identify where the weaknesses are in a plan or design. Once we’ve seen how we can fail, we can take steps to make sure we don’t fall into the same trap again. Not only will the current project benefit, but future ones will as well when we have learned from experience what to avoid.

It’s easier to get forgiveness than permission.

This is an old standby. It basically says that when you’ve got something to do that is risky, it’s better to do it (perhaps hoping you won’t get caught) than to try to get permission. Getting permission involves someone else (usually higher up in the organization) in the risks. It’s likely they will be reluctant to go along, and you won’t be able to get permission to do something you know needs to be done. If you simply do it, you might not get caught. If you do get caught, and the project was even somewhat successful, you come off well by looking like a person willing to take risks to do the right thing. If you get caught and the project failed you’ll probably get by with a reprimand. Worst case is you’ll get a chance for a change of scenery.

Note that this isn’t a license to do all manner of evil. But rather, it’s a way of saying that sometimes you just have to do what’s right even though nobody would agree with you if you tried to explain it to them.

People Management

The three-sided manager: Planner/Cheerleader, Bridge-builder, Wall-builder.

(Craig)

I’ve come to believe that managers (at least of software projects — you’ll have to decide if this applies to you) have three roles in their organizations:

  • As a planner/cheerleader you’re responsible for looking to the future, bringing in new work, getting people excited about what’s coming up, and keeping them excited about what they’re doing.
  • As a bridge-builder you’re responsible for connecting your people to the resources they need to get their jobs done — whether it’s equipment, furniture, training, assistance from others, books, or whatever.
  • As a wall-builder you’re responsible for protecting your people from interference from upper management, policy police, fellow employees, etc.

Interestingly enough, none of these roles is the traditional authoritarian “boss”. People who spend their time telling their people what to do are limiting the possibilities of what their group can do. By making all the decisions for them and enforcing your will on your employees you destroy morale and run the risk of making poor choices because you haven’t considered the opinions of the people who really know the job — your employees.

Deal with problems as they’re encountered.

(Craig)

We all prefer to ignore problems, especially people problems. As a manager I’ve had to deal with an incredible range of really nasty situations, from people using their business computers for “inappropriate Web browsing” to people I had to recommend for counseling. It would have been much easier to ignore these problems and hope that they went away. But doing so would only let the problem get worse.

A simple application of this principle is this: There should be no surprises at an employee’s annual performance review. An employee shouldn’t learn of significant deficiencies for the first time at his or her review. If it’s serious enough to merit mention in the review, then it must be important enough that you should have dealt with it when it happened.

Any eight hours will do. Any forty hours will do.

(Craig)

If at all possible, implement “flextime” within your organization. Flextime says that an employee can come in at anytime in the morning and leave at anytime in the afternoon as long as they’ve put in their eight hours. It permits an employee to take a half-hour lunch or a one-hour lunch. It should also permit occasional afternoons off if the time can be made up within a reasonable period of time.

This is especially important in engineering and creative disciplines. (It’s not very functional in sales or customer service organizations.) Flextime recognizes the employee’s ability to manage himself. It creates a very stimulating environment in which people will be free to leave the facilities even, if that’s what it takes to do their job. It’s not unusual in my group for a couple guys to head out to the software store to see what the competition is up to or to evaluate a new idea by looking at what’s already available.

Flextime also permits an employee to arrange his family time and work time in a way that meets his needs. Some employees like to spend time in the morning with their kids. Others prefer to get home right away so they can pick up kids from school or get a head start on the evening’s activities. By implementing flextime, you earn the respect and appreciation not only of the employee, but of his or her family.

Vacation time is a right, not a privilege.

(Neil Ennis)

Many employers make vacation time something you have to beg for. As long as you’re not in an organization that requires a certain staffing level each day (telemarketing, restaurants, etc.) you should always honor every vacation request. The employee has earned it.

Many managers fear employees will take time off right at the critical phase of a project. But no responsible employee will ask for vacation at a bad time. Even if they do it’s better to let them take it. Adding to the stress at work by adding stress at home isn’t going to get the project out the door any faster.

Promote employee ownership of the product.

(Dave Theilen)

Tell them everything we know about the competitor and the marketplace, let them make decisions about implementation, and believe their schedules. As a result, they turn out a better product and do it on time without forced overtime.

Let them work it out

Take the time to help an employee who is having difficulty with an assignment to get the resources he needs to accomplish the task. Let people make mistakes, then help them figure out what they did wrong and how to avoid the mistake in the future. You don’t need to give them the answers. They can figure it out if you give them the opportunity.

Don’t answer the phone when you’re in a meeting with an employee.

(DeMarco and Lister?)

There’s no better way to tell someone you don’t care than to take a phone call in the middle of a meeting with them. This goes for retail sales people who answer the phone while you’re checking out, too. Just ignore the phone or forward it to voice mail. If it’s important they’ll call back.

Project Management

Your employees know more than you do.

Let them do their jobs.

There’s no such thing as overtime.

(DeMarco and Lister)

Overtime hours are less productive. Employees make them up after the project is over through decreased enthusiasm and burnout. Overtime robs employees of their families and makes you the enemy.

Our programmers are our first customers.

(Craig)

Our programmers should be familiar enough with the application domain that they’re using our products to solve their own problems in that area. As a result, they know what users want because they are themselves users.

WDYR? (What do you recommend?)

(Gus Pagonis)

Don’t tell me about a problem unless you have a solution. Similarly, don’t tell your boss about a problem unless you can offer a solution.

Software Development

This program works.

(Craig)

Programs should be implemented incrementally. Each increment should be proven to be correct. At every stage, the program should work.

Debuggers don’t.

(Craig)

Debuggers give you a micro-view into your code. Most coding problems are logic problems which are macro-problems. If you think about your code while you’re implementing you don’t need a debugger.

There’s no such thing as too many comments.

(Craig)

The quality of internal documentation is the mark of a great programmer.

There’s no such thing as reusable software.

(Craig)

It is possible to create small utility functions that can be reused in many projects, even over a long period of time. I had a collection of BIOS display functions that I used for about six years when I was writing DOS programs. It was a very simple set of functions but it performed some very useful tasks and saved me a lot of time.

But when people refer to software reusability they usually mean creating large scale libraries of functions or classes which can be used on many projects. They seek to standardize on these common functions with the idea that once this code is written they’ll never need to do it again.

I’ve found that none of these efforts produce anything that’s usable for longer than a year. Technology changes, and the solutions that seemed right a year ago are useless now. Instead of trying to constantly position for the future, it’s best to follow the next axiom.

Implement today’s programs with today’s tools to today’s standards.

(Craig)

It seems there’s always some Great New Thing coming out in three to six months that’s going to revolutionize the way you write software. But three to six months from now there will be some other Great New Thing coming three to six months from then.

I’ve found that it’s best to use the most promising tools available today to solve today’s problems. Half-way through the project you’ll be tempted to change your implementation plan to take advantage of some new technology. It’s almost always better to continue with your original plan. Let someone else debug this new stuff while you get your product out the door. Then come back and take advantage of the new stuff on version 2.0.

Working with Other Companies

Ask for more than you need.

Buy yourself some negotiating room. You can always give some back. Applies to a lot of areas; similar to “under-promise and over-deliver”.

Use voice mail.

Leave detailed messages. Don’t just say “call me back.” If you leave a message it should convey new information.

Let 1000 flowers bloom.

(Guy Kawasaki)

The little guy you’re not interested in today could save your company tomorrow. Don’t burn your bridges. Leave your options open.

Customer Service

Under-promise and over-deliver.

(Guy Kawasaki)

Don’t make a promise you can’t keep. In fact, if you make a promise, keep it sooner and better than you promised.

Hiring

Interviews take at least four hours and often eight.

(Craig)

It takes about an hour to and hour and a half to get to know the candidate’s capabilities. It takes a half hour to an hour to tell about our company. The rest of the time is for the candidate to ask questions.

Hiring a new employee is a bigger decision for him or her than it is for you.

(Craig)

You’re asking the applicant to completely change his life. All you’re doing is choosing one person from a list of several potential candidates. As a result, give the candidate adequate time to become familiar with you, the job, the company and the city.

Let the candidate talk to his potential co-workers.

Involve other members of the team in the interview process. Then believe what they tell you about their impressions.

Life Principles

Think about it overnight.

(Bob Parsons)

Before sending a scathing e-mail or letter, let it sit overnight at least. The recipient will still be there tomorrow. I wish I could remember to do this more often.

Pray for your competitors.

(The Bible)

For several years I used a competitor’s mouse pad as a constant reminder to pray for them. I’ve never felt bad about steering a customer to a competitor’s product when they have something we don’t. I think in the long run it builds goodwill with customers and your industry peers.

Say you’re sorry.

(The Bible)

Admit your mistakes. It disarms people.

Send your wife flowers half way through a week-long trip.

(Craig)

I reserve this for really long trips but it really helps.

Always be reading a good book.

(Kurt Hansen)

It keeps your brain from decomposing.

Read about people whose lives you admire and want to emulate.

(Rush Limbaugh)

Have you noticed that squirrels seem to never learn from their friends’ experiences while crossing the road? Humans have the benefit of being able to learn from other peoples’ mistakes so they won’t have to make them themselves. They also learn from others’ successes. Don’t be a squirrel: Read a book.

Tip well.

(Craig)

Be loyal to businesses that treat you well. They’ll treat you better each time you come in.

Keep a to-do list.

Craig: Fill in this paragraph.

If you didn’t write it down, it didn’t happen.

(Cliff Stoll)

I’ve always wanted to keep a diary, but I’ve never managed to muster the discipline. But at work I try to keep a phone log and a brief diary. It makes it a lot easier to remember what happened when and to remind you of your accomplishments.

During the development of one of our software products we wanted to make use of some data, the copyright status of which was in question. I contacted the owner and was told that I didn’t need to ask their permission to use this data — my usage was not inflicting on their copyrights or trademarks. I made a note in my log of the date and time, along with the name of the person I talked to.

About four years later, the president of the company which owned the copyright on this data contacted me and wanted to collect back-royalties on our usage of the data. When I told him I had verbal permission from one of his employees, he didn’t believe me. But when I produced a copy of my dated phone log, there wasn’t much he could say. While he probably could have challenged us in court, he chose to honor his employee’s decision and let us off (he would have lost in court anyway).

If you have a legitimate complaint, mention it when you check out.

(Craig)

Mention one or two things you had trouble with every time you check out of a hotel. More often than not you’ll get a free night.

People don’t expect enough from hotels. Remember that the purpose of a hotel is to provide a comfortable place for people to sleep. Anything they do that undermines that purpose shows that they don’t understand the needs of their customers.

A classic mistake seems to be renting out large public areas for private events. We were staying in one of those large hotels with the big central atrium one time when they had scheduled a rock concert in the atrium. While it was great fun for those who attended, it wasn’t much fun for our family. On another occasion, we discovered the hotel rented its pool to a water aerobics group each evening during prime guest pool usage time. Needless to say, I mentioned both of these incidents to the respective managers and received credit for at least one night’s stay in each case.

Always leave the bathroom cleaner than when you entered it.

(Craig)

While the principle applies well at home, it’s also very suitable for public restrooms. Imagine if everyone just cleaned up after themselves in men’s rooms. The world would be a nicer place.

Make sure the slots in the screw heads line up in the same direction.

(Dad)

In other words, pay attention to the details. Or, “a job worth doing is worth doing well.”

A few years ago I was mounting an outlet cover plate on the wall after doing some wallpapering. I noticed that I subconsciously was making sure the slots in the screws lined up in the same direction (in this case, up and down — not sideways). I realized that I had picked this up from my dad years before. Then just a month ago I noticed that the electricians doing some remodeling for me did the same. I was pretty impressed there for a while… until I stepped back and realized they had mounted the outlet box at a slight angle.

I guess some people can learn principles but not quite fully apply them. It’s nice to have those screw heads straight, but I’d rather have the outlets square with the rest of the world.

Essential Reading

Certain books have been critical to shaping the way I think about management and product development. I consider these to be important to people managing groups of engineers or people involved in creative endeavors.

Zapp! The Lightning of Empowerment, Byham

Peopleware, DeMarco and Lister, Dorset House

The Bible, Various

The Macintosh Way, Kawasaki

“Contributors”

Dad — The best thing my dad ever did for me as far as preparing me for doing things myself was help me build a Soapbox Derby car. In the course of that project I learned a lot about doing a job and doing it right.

DeMarco, Tom and Lister, Tim — Met one of these guys at a Software Developers conference. Authors of Peopleware, one of the definitive works as it relates to my style of management.

Ennis, Neil — My supervisor at Rockwell. My first boss. An incredible role model and probably the source of more of this material than I realize.

Hansen, Kurt — My first close co-worker at Parsons. Rejuvenated my love of reading though he probably doesn’t realize it. Kurt once read through the first seven volumes of the encyclopedia. (OK, it would be more impressive if he had read the whole thing, but… seven volumes! That’s pretty good.)

Limbaugh, Rush — Radio host, author, consummate conservative.

Kawasaki, Guy — Author of The Macintosh Way and Selling the Dream. Offers a fascinating view of the computer industry and software development.

Novotny, Russ — Team leader on my first project at Rockwell.

Pagonis, Gus — Author of Moving Mountains. Managed logistics during the Gulf War.

Parsons, Bob — Founder of Parsons Technology. Madman and mentor. Probably also contributed to more of these aphorisms than I’ve acknowledged.

Stoll, Cliff — Author of Cuckoo’s Egg. Astrophysicist and techno-philosopher.

Theilen, Dave — Author of No Bugs. Saw him speak at a Software Developers conference. First software manager I heard who thought the same way I did about managing programmers. Again, many of the ideas I claim as my own are probably Dave’s, though I think I had many of my concepts nailed down before I first started reading his material.