Saturday, June 12, 2004

Easter Eggs, Part Deux


Alpha Five Easter EggLoyal reader B wrote me the following note in response to my earlier article regarding the Alpha Five version 1 Easter Egg.


It's interesting that you wrote about easter eggs. As an end user and gamer I love them. As an IT professional, I hate them. Since it's clear that you understand the end user "cool" aspects, I thought I'd talk about why I hate them. True story: Back in '98 I was in CITY DELETED for the COMPANY NAME DELETED quarterly meeting. At each of these meetings we have the CIOs of each of the various operating units in for a meeting to discuss new technology trends, standards development, and security. At the time I was the security architect for COMPANY NAME DELETED.

As part of each meeting we invite a strategic vendor to come and talk about their roadmap/vision. At this particular meeting Microsoft presented on the upcoming Windows 2000 release. They gave a very impressive presentation on how MS is now linked to open standards like Kerberos, LDAP, etc. They talked about how secure their new system is going to be. They talked about how they have made major improvements in their QA processes and how we should trust the next version of their OS.

I was interested in easter eggs at the tiem because I had recently discovered the Excel Flight Simulator egg and was really wondering whether having stuff like that in their products effected the stability and security of the product itself. I asked the MS guys from Redmond about the eggs and wanted to know if they underwent the same rigorous QA process as the rest of the product. Since they had just gotten done talking about their new process they had to state that, of course, the eggs underwent the same QA process and we can be assured that they wouldn't impact he security of the product.

Mind you, it took me a good 20 minutes to get them to admit that the eggs existed and were sanctioned by management. The CTO at the time, C, a spicy, southern gentleman, was beside himself. Keep in mind that this guy is all business. COPMANY NAME DELETED as a whole, was having huge problems with performance and capacity on their corporate systems (largely MS-based). Then the vendor comes in and tells you that with every product of theirs that you install, they have included seceral hundred k of unnecessary code. If you multiply this times the thousands of users that COMPANY NAME DELETED had, it adds up to real costs in disk, tape, memory, etc.

It was enjoyable watching the MS reps dance and try to justify why they allow, and in fact endorse, the inclusion of easter eggs in their products. Not only do they exist, but MS knows about every one of them and QA checks them. This final point is something that I have a hard time believing. My point at the time was that they might do better to spend some of the easter egg QA time on making their products more secure and bug-free instead of checking the eggs.

In the end their justification for allowing it was to stay competitive in the market for developers. You see, other companies allow developers to include easter eggs in their products and if MS didn't allow it they would be at a disadvantage when trying to recruit good coders. All in all I have to agree with C. It's bad business. Products are there to meet a specific market need, not stroke the ego of the development teams.


Yo, our egg occupied a total of 17K and was QA'ed by me. Nuff said.

Actually, I'm not saying I disagree with you. Especially if we're talking about Microsoft's products. But since Alpha's were rock-solid from both a security and a stability standpoint ;-) ... there's no reason the development team couldn't engage in a little value-add fun. Consider it the Alpha Bonus Pack.

In praise of continue



Advanced C++ Programming Styles and IdiomsI've read some fairly daunting software engineering manuals that discourage -- or even ban altogether -- the use of a 'continue' statement. This, in my experienced but fallible opinion, is a complete mistake. I will illustrate to you, using actual code (no, seriously?), why I believe this is so.

I've abbreviated this code to make it easier to follow. It resides in the heart of the BadBlue scheduler, which mimics Outlook's recurring appointments feature. One of the neat things about the scheduler is that it allows recurring events, no matter how many times it occurs, to be stored in a single record. So if you have an 8:00am daily appointment with your therapist, Monday through Friday, the cost is a single database record.

This code is abridged from the method that finds tasks in a specific "window" of time (a begin-date and end-date). Virtual, recurring events are extrapolated from the physical records that serve as their instantiator. This code finds events (real and virtual) in an ordered list and, if they fall into the window, saves the event ID for the caller's use.



// Set up a search loop until we find something in...
// the find-window (or we run out of items).
//
while (m_posFind != NULL) {

// Get next item in ordered list...
//
if ((pstrKey = m_tplResultSet.GetNext(m_posFind)) == NULL) {
continue; // 1
}
strKey = *pstrKey;

// Does a delete record override this item? If so, skip it.
//
if (m_mapDeleteSet.Lookup(strKey, strJunk)) {
continue; // 2
}

// Find the real key: key contains date/time + taskID.
// ...content contains caption, duration, recursion-flag.
//
if (!m_mapResultSet.Lookup(strKey, strContent)) {
continue; // 3
}

// Decode key...
//
yr = mon = day = hr = min = sec = 0;
sscanf(strKey.GetBuffer(0), "%d-%d-%d %d:%d:%d %ld",
&yr, &mon, &day, &hr, &min, &sec, &dwTaskID);
CDateTime odtItemStart(yr, mon, day, hr, min, sec);

// Decode content...
//
bufferCaption[0] = '\0';
yr = mon = day = hr = min = sec = 0;
bufferIsRecurrence[0] = '\0';
sscanf(strContent.GetBuffer(0),
"%[^~]~%d-%d-%d %d:%d:%d~%[^~]~"
"%[^~]~%d-%d-%d %d:%d:%d~%ld~",
bufferCaption,
&yr, &mon, &day, &hr, &min, &sec,
bufferIsRecurrence,
bufferExtraInfo,
&yrx, &monx, &dayx, &hrx, &minx, &secx,
&dwExtraInfo
);
CDateTime odtItemEnd(yr, mon, day, hr, min, sec);

// Is item in find window? If not, continue...
//
if (InWindowNonRecurring(
(CDateTime) odtItemStart, (CDateTime) odtItemEnd,
m_dFindWindowStart, m_dFindWindowEnd, 0)) {
continue; // 4
}

// Store appropriate args for caller's edification...
//
dStartDate = (CDateTime) odtItemStart;
dEndDate = (CDateTime) odtItemEnd;
strSubject = bufferCaption;
bIsRecurrence = (!stricmp(SRECURS, bufferIsRecurrence));

// Found... quit.
//
bRet = TRUE;
break;

//
// ...end of loop through major window items...
//
}


Note the four continue statements, marked above.

1) Is the loop finished? If so, let the loop terminate gracefully (m_posFind == NULL)
2) Does a "delete" record override this item (e.g., has the appointment been cancelled or otherwise overriden)? If so, skip to the next item
3) Can we find more information about this event in the result set? If not, then it's been removed from the pool of valid events and we can skip to the next item
4) Lastly, is this item even in the window of interest (i.e., does it occur after the begin-date and before the end-date)?

Now imagine if this code was written without benefit of continue statements. In other words, we would use nested "if ... else ..." clauses... and nested rather deeply based upon my initial take.

Now note the relative clarity of the above logic compared to the hypothetical three or four levels of nested if constructs. To me, there's no comparison between the two approaches. I would encourage any developer to use continue constructs wherever clarity can be used to fight nested if statements.

Tuesday, June 08, 2004

Vacation



How a Second Home Can Be Your Best Investment: New, Tax-Free Methods for Using a Vacation Home for Recreation, Retirement...AND Investment!I will be on hiatus for a few days. Vacation. Beach. Sand. Sun. Kids fighting and complaining.

Actually have read several books, one of which I can highly recommend. Endgame - The Blueprint for Victory in the War on Terror is chilling, fascinating and a very quick read. It spells out exactly what steps the United States (not a multi-lateral commission, the UN or other tools of the proponents of appeasement) must take to survive and win the war on terror.

I'll have a full review posted shortly.

Friday, June 04, 2004

Easter Egg!



Alpha Five version 1 Easter Egg - Use Help -- About, then hold down the [Ctrl]+[Shift]+[Tab] keys with your lefthand, move the About window using the mouse with your right handFor those unfamiliar with the term "Easter Egg" -- as it applies to software -- it means a hidden feature that can only be activated through an intentional set of actions. Usually, Easter Eggs provide scrolling "credits" where the developers get to pay homage to their friends, hobbies or themselves.

One weekend I decided to create an "ultimate" Easter Egg for Alpha Five version 1. We were getting close to release, so I decided to use the "About Box" as the platform. I wanted to credit the developers and others who played key roles in creating the product. So what would you expect me to do? I created an Alpha Software version of Space Invaders with the developers and other key personnel as the "invaders". That way, a user who got ticked off at some (mis)behavior of the software could exorcise his angst by blasting our heads into clouds of bloody gunk.

How did the Easter Egg get activated? For the answer, I've included an Easter Egg on this page. Roll your mouse over the picture and you'll get the instructions. Not that too many folks still have version 1 installed. It might be in version 2 as well, I can't remember. Senility tends to do that.

Funny story: Richard, Selwyn and I went up to Corel for some discussions about licensing the Alpha Five database to them. While Richard and Selwyn went off into hard-core negotiations with their top people, I showed them the product and some source-code. After a few hours, we'd exhausted those topics. The discussion turned to Easter Eggs. I said, "Hey, what's the Easter Egg in Corel-Draw?" They proudly fired up a copy and unveiled their egg. It depicted a balloon, gently floating, with the names of their key personnel floating by. They turned to me.

I fired up our Easter Egg and played a few rounds, scoring a not-so-impressive 2700 points. They were wide-eyed. "You win! Your Egg rules! We don't deserve to be even considered developers, not compared to you guys." I've kind of forgotten the conversation, though, perhaps that's not verbatim. Anyhow, they did like it and sometimes I think it helped seal the technical side of the deal.

At the time, though, this may have been the premier Easter Egg of consumer software. The Excel team later came out with a mini-"Doom" game with 3D graphics. But this came first and was, as far as I know, the initial foray into a full, playable game in a commercial package.


Depicted in the Alpha Five version 1 Easter Egg, from top left:
Doug, Pete, Selwyn, Gerry, Cian,
Dave D, Peter, Norris, Dave M, Nori,
Eleonora, Gregory, Dave T, Richard


Thursday, June 03, 2004

Tales of Alpha



You Need to Be a Little Crazy : The Truth about Starting and Growing Your BusinessThere were a lot of benefits to working for a mass-market software company. Some of them were obvious. And some weren't.

The obvious ones probably apply to a fair number of companies. If you wanted to wear a T-shirt and shorts, you did it. If you needed to show up at 11am and work until 9pm, you did it. If you wanted to write a quick program to help with ordering the pizza, you did it.

But some of the benefits weren't so obvious. They were... well, simply, good karma. One day I received this email, which was sent to the entire company.


To: *ALL
From: Peter E
Subject: Re: ted
Date: 10/02/92
Time: 2:39p

by popular demand more on..... Ted "$72000.00 dollar man "
We made his wifes day. He made an pplication for thier girl scout troop.
His application is a run time for the state of tennessee. I believe the application was for the state school
system. A year and a half ago he was a mechanic. Now he is an Alpha applications programmer.

We also made his kids year. This year his kids will have christmas. Next year his family will have a house.
Hats off to all for helping this man with his new life.

peter "proud to be on the team" e...


Ted had created an application for the state and had negotiated a $72,000 license fee using the Alpha run-time engine, which allowed distribution of applications. That was probably one of the better holiday seasons at Alpha.

Bad karma days? I remember one vividly. We had a product for a while called "AlphaWorks" [1], which Cian and another developer had spearheaded. It was a very good product, back in the days of DOS. And it even got a PC Mag Editor's Choice Award in the late 80's or early 90's, tying Microsoft Works.

The company had cut a deal with some low-budget computer firm to bundle AlphaWorks with each computer. The computer was sold on a home shopping TV network with a very, very hard-sell. My guess is the computer company was a fly-by-night operation, because if you received a computer from them, the only phone number you could find in the entire boxed system was... yes, Alpha Software's 800-number on the AlphaWorks manual.

How do I know this? Funny you should ask, friend. I happened to show up at the office on December 26th. I was new to the company and didn't know that day was a holiday. So there was no one there. Ghost town. The phone rang - on night ring, so it echoed throughout the building. It was quite loud and annoying, so I picked it up. This was maybe 9am.

"Alpha Software". Now you need to voice-over a hillbilly [2] accent here.

"Ah jest bought mah comm-pewter and Ah turned it on an' it jest sez Cee". This was in the days of DOS prompts. When you powered on a computer, it did just say "C>".

"Well, sir, we don't make the computer, you'll have to call the "D" company." After several minutes of disentangling myself from this hilljack's situation *, I managed to hang up. NIGHT RING. NIGHT RING.

"Alpha Software, can I help you?".

"Ah jest get me a comm-pewter, when the TV part comes on, it jest sez Cee. What do ah do now?"

Imagine an entire day filled with those calls and you have a good idea how I spent much of 12/26 that year. After a while, fifteen or so calls just like those, I made my home-brew, prison-style earplugs (use warm water, toilet paper and a patient rolling motion) and got back to work.

I don't know if the D company was a mob "bust out" operation or what. But I do know their tech support was nowhere to be found that day. And that's probably how they planned it.

[1] AlphaWorks ended up getting sold to Lotus and it became... drum roll... can you guess... no, the suspense is killing me... hold it... hold it... LotusWorks. Genius! That's gold, Gerry, pure gold! Not sure what happened to it, but the librarian at the Lotus Division of IBM may be able to tell us. IBM must have also purchased the AlphaWorks name, because I believe that's used by one of their mainstream developer sites.

[2] I'm licensed to use and mock hillbilly accents as I've technically been accused of being one. Peace out.

Wednesday, June 02, 2004

$970,000



Killing Floor, by Lee ChildIt's amazing how money is relative. When I was growing up, my Dad served as Treasurer for a volunteer organization. When they held an art auction, he was responsible for all of the funds. I remember him coming back late that night with more cash than I'd ever seen in my life. My brother and I helped him count it. I think it was twenty-two or twenty-three thousand in cash. What surprised me at the time was it really wasn't that bulky. An enormous amount of cash -- in small bills -- could be held in a shoebox.

My Dad had a reputation for honesty that went beyond normal. I assume that's why he had the job. When I was growing up, he was an up-and-coming manager with a large apparel firm. He used to take me into work with him on Saturdays and I'd help him out, pulling swatches to send to the New York office, stuff like that.

Anyhow, I would also work on my baseball magazines and comic books. I used to create my own version of "Baseball Digest" (concentrating heavily on the Reds, since they were the hometown team despite being 150 miles away). And I would also write, illustrate and letter my own comic books: primarily a rip-off of Marvel's Sergeant Fury and Howling Commandos and DC's Sergeant Rock. It was named, uhm, "Sergeant Rage".

Anyhow, I would come in on Saturday with my material ready to be published. And I wanted to use the company's Xerox machine. My Dad had no problem with it. But, scrupulous as he was, he wrote down the number of copies I made so that he could report it and reimburse the company. He even wrote it in the copier log to ensure he didn't forget. Now, that's an honest man.

Years later, he became President of the company and I don't think he needed to worry about logging each copy he made. But he probably did anyway. That's just the way he is.

Back to the relative nature of money: when FASTech closed on its first round of venture money, Jim and Hans sat with the board and the investment bankers, signed all of the thousands of pages of agreements (I was very much a minority shareholder compared to them), and were handed in return a check for $970,000.

Jim said that he was very excited... after all, who wouldn't be with a check for a million bucks in their hands? He ran to the bank to deposit it. Waited in line for a teller. Waited in line a little longer. Finally, walked up to the teller with a grin, expecting a nice reaction. Hell, it's a million-dollar check, we should get at least a smile and a veiled glance from the teller. He made the deposit, watching for a reaction. *Stamp*... clicking on the deposit keys... *Stamp*... not a word, not a bit of reaction from the teller. He gets handed a deposit slip. Have a nice day.

Lesson learned: in Boston's financial district, apparently, a million dollar check ain't diddly squat. It just goes to show you... it's all relative.

Tuesday, June 01, 2004


This will be interesting

The Weblog Handbook: Practical Advice on Creating and Maintaining Your BlogIn preparation for heading off on vacation this summer, I've configured my blog to accept email posts. Blogger allows you to "check on" an option setting for this purpose. You can then send posts to a secret destination email address hosted by blogger and, if you so choose, they'll be posted and published immediately.

So this is the first test of that system.

As an aside, Blogger has added a feature that allows you to post photos to your blog using your IM client. What's cool is that a "blogger bot" hangs around in your buddy list, waiting for you to message it. When you want to post a photo, you just IM the bot and send it the JPG. Blogger will even host the photo for you (which is a policy change for them, to be sure).

What I haven't figured out is whether you can do this without an IM client. Now that would be very cool.

Sunday, May 30, 2004


Logic for Licensing

Share Excel Spreadsheet Files over the Internet using Web BrowsersHaving some fun designing and implementing the BadBlue server's new licensing scheme. In a nutshell, the Excel sharing features allow browser-based remote users to update a Excel spreadsheets running on the server. The new licensing scheme limits the Excel collaboration features to a fixed number of "named users".

So to have Joe and Fred both update a spreadsheet, you'd need at least two "user licenses". You'll be able to order a "license pack" that will bump your licensed user count to the desired level. The "license pack" product simply comes in the form of a "license pack code", which gets emailed to you upon confirmation of the order.

The code works like this when you enter a new license pack code:

- Read the currently installed license packs
- Has the code already been installed?
- If so, set "UsersToAdd" to zero
- If not, set "UsersToAdd" to the encrypted value and save the new license pack code
- Bump the "LicensedUserCount" by "UsersToAdd"

One of the pages of the user-interface allows you to review your current licensed user count and see which codes have been installed.

When the product starts, it does the following:

- Set the "LicensedUserCount" to 1
- Read the currently installed license packs
- For each installed license pack...
- Decrypt each installed license pack code
- Bump the "LicensedUserCount" by "UsersToAdd"

The Enterprise Edition product, which includes the Excel sharing capability, will have a built-in licensed user count of 1. License packs will be sold in units of 5, 10, etc.

This is a new licensing model and one precipitated by a major investment in new features, which have been added by popular demand. In particular, a couple of accounting firms are trying to open up large legacy spreadsheets to the web without having to pay for a major application conversion.

This seems like a good alternative: users and business processes get to employ the same underlying Excel technology but open it up to anyone with a browser. The multi-user conflict resolution and audit-logging capabilites are pretty standard fare for this type of app. But one of the neatest new features is the ability to restrict which cells are visible and/or modifiable based upon the identity of the logged-on user.

There appear to be specific accounting situations in which this comes in handy. Say an auditor wants to comment on a spreadsheet without letting some of the data-entry folks see the comments. His notations are visible to certain users but invisible to the clerical users. Likewise, a law firm might want to place additional comments that aren't visible to either the auditors or anyone else. Oh, what a complex web we weave...

Anyhow, if you're interested in unlocking a spreadsheet by sharing it with browser-based users, give it a look.

BadBlue Tutorial - Excel Sharing FAQ (Share Excel Spreadsheets over the web, LAN or other network)

Saturday, May 29, 2004

The Accidental Project Manager by Patricia Ensworth is a survival guide for the person who suddenly becomes a software project leader without preparationIn a recent JOS post, an anonymous poster asked:

Where the heck are all of the good software engineering jobs? With good software companies? I'm not talking about a Crytsal Reports writer or business applications programmer/analyst or a stupid Access database programmer! I'm talking about C/C++ development of hardcore stuff like content creation, games, operating systems, utilities etc etc. I want to be on the team who makes Crystal Reports, Access, .NET, MS Windows, Adobe Photoshop, QuarkXPress, DreamWeaver, Norton Utilities etc etc..

Does anyone here work at these places? What does it take to get in? Can anyone else here identify with the "I hate business development stuff." It seems like all the fun stuff is gone or the positions are filled or some other such nonsense.


As someone who was fortunate enough to work on a couple of mainstream commercial applications, I can only respond, "it takes a career plan... persistence... luck... and skill."

So how did some midwestern hick debugging firmware at a process control company end up architecting a mass-market database package? It didn't happen overnight, that's for certain. I did it in stages. While at the process control company ("the O Corporation"), I started writing more and more code. I loved it. I wrote code all the time. Firmware. UI code for the color ISC terminal. I even wrote a VisiCalc-like spreadsheet for the PDP-11 (RSTS/E) for engineering calculations since DEC didn't offer one on that platform. Because I typed about 100 words-per-minute, I could crank out more code than most of the other guys. So I experimented constantly.

Interestingly, one of the reasons I left my first company was how I was treated. Even though my pay was abysmal, I didn't really mind because I made enough to live comfortably. I had amorphous goals for making more money, but nothing set in stone like, "I want to make $X my age 25 and $Y by age 30". I had been there several years when the pivotal event occurred.

My boss, Mike, at the time was generally a decent person but a tad reactionary and insecure. He was pissed about something and called me into his office. I walked in and he spat at me, "Sit down!" - everyone in that area of the engineering floor could hear it. I felt pretty low, almost like he was talking to a dog. But after a moment's hesitation, I obeyed and sat. In my mind, I was saying, "that's it - I don't need to be treated like a dog". I resigned in my head that day. And I had a real job offer a few weeks later and resigned for real... giving two weeks' notice. Of course, I never really told the president of the company why I was leaving. It was just very hard to describe that feeling of degradation.

That also taught me something about how I wanted to treat people if I ever got a software management job. For sure, I thought, life is too damn short to be treating anyone with disrespect. That goes for the president of the company down to the person who empties the trashcans. I've tried to abide by that philosophy. Anyhow...

I moved to PMC, the division of the Fortune 500 company. Rich Alden ran the Engineering group and was a very good leader. He was organized but not a micro-manager. He trusted his engineers because he had hired a talented group of guys. And they were fun people to be around.

Almost immediately after I was hired, our parent division ("Systems Division") received a huge contract from IBM for a large portion of a printer assembly plant. The factory control software fell on me, since I was the only Intel specialist in the place. It was a fantastic opportunity. I designed the real-time, multi-tasking OS, the scheduler, the controller, the user-interface (RS-232 to a terminal)... everything. It was a fantastic leanring experience and with my background, it was cake.

Systems Division in Cleveland and IBM in Charlotte seemed pretty impressed with the system. I met a wonderful project engineer in Cleveland: Topper Hill. A unique, funny character, Topper always wore a solid, bright red tie. Topper and I got along famously as we worked on integrating his mechanical pieces with the software. Topper took me to my first Armenian restaurant in east Cleveland and that was quite an experience. Ethnic cuisine at its best and the liquor wasn't bad either.

Unbeknownst to me, Topper was working on several projects, including one with folks from GMF Robotics in Detroit. A couple of the senior GMF folks were Jim Pelusi, a very bright Harvard MBA, and Hans Bukow, a Purdue master's grad. Both were confident, eloquent guys. Somehow, Jim and Hans mentioned to Topper that they were thinking about starting a software company. And they were looking for talent.

I don't know what Topper told them but the next thing I knew, Hans and Jim were sitting in my office at PMC in Cincinnati. They described their vision of a user-friendly system that would allow automated factories to be assembled quickly and easily. And they indicated that they had the connections to get the company funded. They wanted me to participate as a co-founder and help get the software off the ground. I would be the third employee.

I knew I wanted to work on more mainstream software than the "hidden glory" of process and discrete control equipment. I had a gut feel that this was one step closer. I told them I was "in". And within a period of a month, September 1987, I got married, started a new job and moved to Boston. No stress!

Even better, FASTech hadn't closed its first round of funding when the Stock Market Crash of '87 occurred. Talk about high blood pressure! To Jim's credit, his connections were solid and came through with a $970,000-or-so check just weeks later. They started hiring and selling; and I started coding.

Ever since Hans had expressed his vision to me... a user-interface that would make multi-tasking and real-time processing a breeze, I had a picture in my head of how it could be done. I mean I had it designed, completely. We had a few engineers there who either didn't believe that I could do it or that it could be done at all. One, Charlie, was a decent enough guy, but believed that I should "mathematically prove" that the system would work before I coded it up.

We would sit in meetings and I would listen to various suggestions, thoughts, criticisms mostly directed at me. I would listen patiently, nod, then grin. And then I would conclude the meeting with, "No". I was partially kidding, but basically I knew I could do it. Just get out of the way and let me work. It was innate. My meeting behavior was so negative that John and Charlie collaborated on the purchase of some "Doug-Bats". At the inevitable, meeting-concluding "No", they would beat me mercilessly with the foam bats. It was pretty funny.

I drank nine cups of coffee a day and typed 100 words a minute of raw C. There were days where I pounded out 1,000 lines of code -- all original -- in a day. I had to ramp down on the caffeine when my heart started racing at 100 bpm while lying in bed.

But within a year, we had shipped the first version of CellWorks (the product's name) to GM and Honeywell. It could be done, and we had done it. I must admit, though, that I was a bit let down after we shipped the product. I had created the flagship parts: the graphical UI, the logic engine, major pieces of the windowing system, and so on. I expected something. A promotion. A title change. A raise. A bonus. Whatever. Nada.

I started getting paranoid about the cost of living. I was making a not-so-great wage in Boston and housing seemed unattainable. My first child was on the way. Day-care would be unbelievably expensive. And I had heard nothing from Jim and Hans about a salary commensurate with my level and what I'd achieved. And other people were buying houses and seemingly getting ahead while I felt trapped.

I started looking around, working with Sophia Navickas (who now owns Lynx). I would heartily recommend her for anyone who needs a high-quality recruiter. I described what I was looking for in a new employer. She got me three interviews right off the bat:

1) with a minicomputer spreadsheet maker (I can't remember the company name, but the product was called 20-20). It was very popular at the time with DEC systems.
2) with Rational (not the CASE company), a very small development firm whose primary product was a C interpreter (seriously) for faster development. Compilers at the time weren't very quick.
3) with Alpha Software, a very small consumer database company with perhaps 18 employees.

#1 just felt wrong strategically. I hated DEC systems, loved PCs and felt DEC would be out of business soon. Shoulda shorted them when I had the chance. #2 had a great, friendly group of guys, but the product seemed too techie, too low-level. #3 had it all. A chance to work on consumer software. Small company, so a lot of hats could be worn by the right person. Richard and Selwyn Rabins, two very smart brothers -- both MIT grads -- were the principals. I got along very well with them. In my first interview, Richard had me cracking up with various filthy jokes. I think he was testing to see what kind of personality I had. No problem, I love filthy jokes.

So, Alpha it was. Consumer software. Finally. The company, through massive marketing expenditures, ended up selling a million-plus seats worth of database licenses. Pete and I got to architect a mass-market Windows database product. And it still kicks Access' butt in a lot of head-to-head computer mag reviews. Cian Chambliss is the head software guy now and he is a very talented developer. I'm still pretty proud, though, that we had a tiny development team compared to the hundreds of people and the reported $60 million that Microsoft spent getting Access 1.0 out the door. And we got it done.

So how'd I get there? Like I said. Career plan. Persistence. Luck. Skill. Damn, sorry... that's a long answer to a short question!

Friday, May 28, 2004

Amazon.com: Books: The Blankenhorn Effect: How to Put Moore's Law to Work for YouJakob Nielsen speculates on personal computing power in the year 2034:

...According to Moore's Law, computer power doubles every 18 months, meaning that computers will be a million times more powerful by 2034. According to Nielsen's Law of Internet bandwidth, connectivity to the home grows by 50 percent per year; by 2034, we'll have 200,000 times more bandwidth. That same year, I'll own a computer that runs at 3PHz CPU speed, has a petabyte (a thousand terabytes) of memory, half an exabyte (a billion gigabytes) of hard disk-equivalent storage and connects to the Internet with a bandwidth of a quarter terabit (a trillion binary digits) per second...

...By 2034, we'll finally get decent computer displays, with a resolution of about 20,000 by 10,000 pixels.
By 2034, we'll finally get decent computer displays, with a resolution of about 20,000 pixels by 10,000 pixels (as opposed to the miserly 2048 pixels by 1536 pixels on my current monitor). Although welcomed, my predicted improvement factor of 200 here is relatively small; history shows that display technology has the most dismal improvement curve of any computer technology, except possibly batteries...


What he leaves unstated is the user-interface technology we might anticipate. My take: Research on spinal cord and nervous system injuries will lead to breakthrough interface technology that will not only empower the paralyzed to utilize their limbs... but also provide magnificent new user-interfaces for conventional users:

1) Body-worn computers will interact by reading gestures, eye movement, leg and arm movement (e.g., for game-play), etc.

2) Users will have the option of retrofitting a pluggable adapter into their body that will interact directly with their brain. A short, 30-minute (and almost painless) operation will safely allow direct interaction with a computer and the brain.

3) Future applications that harness the direct brain-to-computer interface will include recording of your vision, your hearing, etc. Recording of thoughts. Even playback of another's experiences or thoughts (a la Strange Days).

4) A wireless brain-to-computer interface (BCI) will also support retrieval of data (e.g., a Google-like seach for information)... browsing of web pages... and some fascinating advertisement technologies - everything will be inside your head.

5) New remote control capabilities spawned by BCI.

Sounds scary, but I think it will be commonplace and well-accepted in thirty years.

Thursday, May 27, 2004


Alpha Frisbee Golf, part 17

Disc Golf: All You Need to Know About the Game You Want to PlayPete's blog stirred a bunch of fun memories. He published a map of the Alpha Software frisbee golf course. I had forgotten the explicit rules that made it so tough (i.e., all concrete constituted a water hazard). He even pointed out an incident involving a lost frisbee:

Another time Doug got a Frisbee stuck on the roof of the building you approach at hole 9 and had to climb a tree to get on the roof and retrieve the disk. After the experience of watching him awkwardly climbing up and down I recall telling Doug, "I think I've just seen proof that man cannot have descended from apes..".


What's bizarre is I remember that exact incident, his comment, and everything. And the shameful thing is when I was a kid, I was pretty lithe and limber and I could scale a tree lickety-split. But, at that time, maybe 1991, I weighed about 225. I could say I was ripped and that I was wearing 32" jeans ("and they're loose!"). But that wouldn't be very accurate. I do remember being pretty blocky and struggling to get up the tree. It felt like it took five minutes of grunting, painful branch burns, stubby nubbins scratching my private parts, to climb about twelve feet off the ground. Of course, Pete was very helpful. He just laughed the entire time.

I did weigh 225, but I was trying to pack on pounds to change weight classes for the first (and last) powerlifting competition I ever participated in. There were three weight classes with which I was concerned. 198 - at the time, too heavy to get down to that level. 220 - which I had no shot at winning because there were a couple of really strong dudes in that class. And 242. There were very few people who ranged from 220-241. So I carbo-loaded all of the time and got my weight over 220. At a weight of 227, I ended up totalling 1200 (405 squat, 340 bench, 455 deadlift). While this was enough to win the class, it was such a laughable total for a serious powerlifting contest that I pretty much gave up ever thinking about competing.

But I was fortunate that Richard and Selwyn agreed to let me buy a bunch of weights for the small Alpha gym. With a budget of perhaps $600, I got some great stuff: a Titan competition bench, a power-rack, and about 400 some odd pounds of Olympic weights. The small gym, used mainly by Selwyn (for bike riding), Sean and myself was also the scene of a pretty scary lifting incident.

I used to bench all of the time without a spotter. Not a problem, unless you went heavy. Well, at that time, I was always going heavy. I would routinely crank out six reps at 285. Well, except for that one day where I had the music cranked up and the door closed. I was pounding out reps and was pushing up the sixth and last one. Uh oh. Couldn't get it locked out. No safety bars on the Titan bench. Panic started to set in. Re-doubled my effort and pushed harder. Now I was seeing stars, literally, and getting close to passing out.

So the bar, weighing close to 300 pounds, was sitting right on my chest. So tapped out, I couldn't move it a millimeter. I yelled, "Help!". No one could hear - the music was cranked and you can't scream real loud with all that weight on your chest. Yelled again. Sh*t. Nothing. Now I knew I was in trouble. With a lighter weight, I could have rolled it down my body without damaging vital organs and my reproductive parcel. But not with that much weight. Not possible without warping the kitschkes.

Or I could have tilted the bar and dumped the weight... if it didn't have collars. But it did. I was locked in.

Finally, I figured out that I could slide off the bench while tucking my head in to avoid the brace. So I jettisoned to the left of the bench. One side of the bar slammed into the ground, the other side hit the bench, and I was safe and sound on the floor next to the bench. Not a hair out of place. Wow.

I popped up just as Dave Mahoney came running in. "What the heck just happened?" More onlookers piled in to see what was going on. "Nothing to see here, just go about your business." I did finally explain, sheepishly, what had happened. Mahoney just looked at me like I was an idiot, "Ross, you came very close to becoming the poster-boy for the Use a Spotter campaign." How right he was.

Anyhow, it didn't feel very healthy carrying that much weight. After my Dad had his heart attack in 1997, I changed my diet completely. I got down to 179 while continuing to lift hard. At a body weight of about 183, I benched almost (325) as much as I did weighing 40 pounds more. Weird.

Anyhow, back to frisbee golf for a moment. What Pete didn't say is that we were very addicted to the sport. It was a blast. We played it in every kind of weather, year 'round. In fact, the frozen tundra of One North Avenue became the scene of the worst frisbee golf injury ever.

The fairways were like sheets of glass. The temperature was quite nippy. And JL, a large gentleman whose dimensions were about 5'9", 300, was playing in our foursome. On the sixth hole (a long Par 4), he flung his disc with reckless abandon and somehow slipped and became airborne. He was frozen horizontally in the air for what seemed like an entire second - several feet over the icy ground. And he landed with a "whump" that was audible from many yards away. He wasn't moving.

"Jim, you okay?" We rushed over. "Jim!"

"Unhknhhh. Unnnhkkh."

If you remember what Sergeant Hulka was trying to say in the movie Stripes when he fell off the tower, you've pretty much got the picture. I think he had just had the wind knocked out of him. But I don't remember him ever playing frisbee golf again. It took true dedication and a love for the game. And only a select few were born to play the Alpha version of frisbee golf.

Alpha Frisbee Golf

Wednesday, May 26, 2004


Affiliated

Search Engine Optimization for DummiesI was talking with Ted McConnell several years ago about search engine optimization. Ted is the head of P&G's IT Research Organization (or ITRO) and who, along with Terry McFadden, was one of the ultra-smart dudes I came across while hanging around the Chemed Center in downtown Cincinnati.

Anyhow, Ted told me about a few of his ideas for utilizing search engine optimization (SEO) techniques for marketing purposes. A lot of them were very clever and I hadn't heard about them being used before. One of his ideas I've modified and I'll share it here.

One of the keys to successful marketing on the web is to have a high ranking in a lot of good keyword phrases. Feel free to voice-over at this point, "Thanks, Captain Obvious!" But hear me out. In this context, "good" means commonly employed search terms used by your target audience. Sure, that's a key. But how, practically, is that achieved? Ah, there's the trick.

Imagine if you were selling baseball cards on the web. Wouldn't it be worthwhile to post some links to Amazon's books and collectibles related to baseball and card-collecting? And to have some good descriptions of each item? And, better yet, to augment those links with your Affiliate code?

So what I have done is combined meaningful links (say, to Amazon SKU's with my affiliate code) on certain of my pages with good excerpts of each item's description. This kills two birds with one stone:

- It generates lots of good keyword hits for the topics, driving traffic
- It generates affiliate bucks for purchasing more Amazon junk

Oh yeah. Thass' what I'm talking about. So click away on any Amazon SKU you see on these articles. My wish list seems to grow by the day, and Daddy needs a new pair of books.

BadBlue - Other Resources

Monday, May 24, 2004


Lemon Squares

How to be InvisibleI think the first person that I grabbed for the Alpha Software development team was Gerry Polucci, who is now the president of Mindstorm Technologies (see link at right). Gerry was right out of school (Comp. Sci. at U. Lowell) and I knew his Dad really well. Hanging out with his Dad, I knew Gerry pretty much throughout college and knew how talented he was.

One of the funny stories he likes to tell is his experience -- at age 16 -- with a U.K. game company that wanted to license a game he created. They flew him over to England and basically asked, "How much do you want for your game?". He said something to the effect, "Enough to make me comfortable for the rest of my life." After the laughter subsided, Gerry ended up back in the States without a deal.

I don't know if he still keeps his hand in these areas, but in his heyday, I would put him up against anyone in the world with respect to his knowledge of MFC and ATL. Aside from being a great developer, he is a very funny person.

At lunch time, we specialized in constructive exploits like playing frisbee golf. My hole-in-one on #2 still stands as one of my greatest athletic achievements, slicing a beautiful 141 gram shot through a maze of trees and clanging it off the Alpha Software sign. You may have seen it on ESPN Classic. They showed it right after a replay of Nicklaus winning the Masters.

Once in a while Gerry, Pete and a few others would walk in the woods past Mitre Corp. My terrifying experience at "the Cliff" still haunts me. It was an immense overhang over the Mitre parking lot. When Pete saw it (after my dramatic description of its daunting scale), he proceeded to walk down it, then back up. In Sperry Top-Siders. Okay, so maybe my perspective isn't so good.

Sometimes we would head over to the inimitable Burlington Mall. Home to Electronics Boutique, the endless Sears credit-card solicitations and... the bakery. Ah, the bakery. One day I received the following email from Gerry. Note the time that the email was sent.


To: Dave D, David M, Dave M, Pete L, Peter M, Doug R, Gerry P
From: Gerry Polucci
Subject: Warning!
Date: 5/16/95 Time: 2:49p

Lemon-squares are an extremely powerful bowel accelerant, and should not be consumed at work or any place greater than 50 feet away from an unoccupied toilet.

Further cautions:
Do not mix lemon-squares with coffee, this will result in the both famed and dreaded bowel-burst (also known as "The Clash of the Colons").

Mixing lemon-squares with ANY Burger-King food has proven deadly in all cases.

There are however several circumstances where the eating of lemon-squares is acceptable:

1. Any situation in which you're sure you are about to die and are not concerned with making a mess
2. When crossing the Amazon naked and being closely pursued by a school of piranha
3. Whenever solely in the presence of your Mother-in-Law
4. In Lemon-Square eating approved areas (i.e., the developers' lounge)
5. When taken hostage and attempting to convince your captors that you are dying from a rare and deadly African stomach virus that is easily communicable
6. When wearing a Depends undergarment while standing in a Hefty trash bag near a small pond or lake with a change of clothes. (CAUTION do not tie trash bag around waste. See Rectal Implosion).

This has been a public service announcement brought to you by the President's Council on Colon Health.


I'm not sure I ever knew what event precipitated this message. But I am certain I don't want to know. He could have simply said he needed to download some log files.

Sunday, May 23, 2004


Unifying HTML and Javascript

BadBlue Web Collaboration and Sharing Tools for Excel SpreadsheetsHave been working on a bunch of new features for BadBlue that relate to Excel collaboration.

The gist of the new features are to allow multiple users -- at different locations -- to modify the same Excel spreadsheet using only their browsers. The users don't have to have copies of Excel (in fact, they don't even need to be running Windows). There are a whole bunch of features related to multi-user conflict resolution, audit logging, cell-by-cell control of who gets to see and edit what, and a bunch of other stuff.

But implementing a rich, browser-based user-interface is challenging. As more and more features were added (based upon explicit requests from users), the amount of Javascript kept going up. Need to pop up an editor window? Javascript. Want to change the colors of a table's cell or its value "on the fly"? Javascript.

The conclusion I've come to is that HTML, as a browser markup language, doesn't have much value without Javascript. Yes, you can put up a static page with HTML and omit Javascript altogether.

But if you're doing a real application, well, you need Javascript.

Why is this important? Think about the HTML and XHTML DTD's. They really have no connection or knowledge of Javascript. Nor does Javascript have a consistent view of the HTML DTD. Need an example?

Consider how you change the contents of a table cell (an instantiated TD tag) on-the-fly:


opener.document.all ? opener.document.all[sCell] // IE4+
: opener.document.getElementById ? opener.document.getElementById(sCell) // NN6
: null;
if (cell != null) {
cell.innerHTML = "something";
}


Of course, if Javascript and the HTML DOM were integrated just a little bit better,


opener.document.table[2].tr[1].td[0] = "something";


or, if the table had a name attribute (doh!):


opener.document.mytable.tr[1].td[0] = "something";


or, if the table and the column each had name attributes:


opener.document.mytable.row[1].labelcolumn = "something";


In other words, why can't the HTML DOM and Javascript be completely integrated?

More importantly, why do we care about this from a strategic sense? Javascript and HTML, each operating in their own vacuum-like silos, benefits only thick-client vendors like Microsoft. The spectrum of user-interfaces available to web application designers ranges from just-plain shitty to a cut above mediocre.

An example of a web app that is pushing the limit is Google's Gmail. It might consist of 80% Javascript and 20% HTML. It is probably the most sophisticated web interface I've seen yet. It is very well done but it still doesn't approach the seamless usability of a desktop app.

A standards-based effort towards integrated HTML and Javascript (i.e., the W3C and ECMA form the necessary committees or initiatives to state what we have... and where we should be going) will bring rich, desktop-like applications to the web.

And who (except, perhaps, Microsoft) would argue against that?

BadBlue Excel Collaboration Tools for the Web

Saturday, May 22, 2004


Practical Jokers

Krakatoa : The Day the World Exploded: August 27, 1883I left the O Corporation after receiving a job offer from PMC. PMC was a division of a Fortune 500 company that specialized in motion control systems. Nearly every person in the small, Cincinnati office was either an electrical engineer or a software engineer.

The two funniest characters in the place were Tim and John. Tim was a really talented hardware guy. He couldn't write a lick of code (and was proud of it). For example, I once watched him write the following boot routine for one of his boards in assembler:

mov [r0 + 0], 0

mov [r0 + 1], 0

mov [r0 + 2], 0

mov [r0 + 3], 0

...


Loop, Tim, loop!

Tim, while growing up, was also famous for his "fireworks". Once, he patiently explained to me that he had gone to a junkyard with some friends, filled a hefty bag with pure oxygen and gasoline (while somehow preventing a static discharge), lit a fuse, ran like hell, and set off a monstrous explosion that mobilized police from several nearby towns. Don't try that at home, kids.

He was also notorious for an explosion of another type. One Friday a VP big-wig was visiting from corporate headquarters. A pizza lunch was generously brought in to the conference room so the VP could mingle with the commoners. Tim was the first to finish his lunch. He grabbed his plate, stood up and ripped a completely accidental fart that echoed from one end of the room to the other.

To this day, I have never seen a face turn that shade of purple, either before or since. And PMC employees still refer to that day as "The Great Pizza Fart of 1984".

John, his friend, was a combo hardware/software guy who was very skilled with autos. His sideline business involved buying Honda Civics with blown engines, rebuilding them and selling them to turn a quick $1k or $2K profit.

Tim and John were long-time buddies, but they loved to play practical jokes on each other. And, as these things sometimes do, the pranks got a little out of control.

I think it began with Tim "modifying" John's car by tying a short crowbar to the undercarriage with a steel cable. The idea being that the crowbar would drag on the ground for a while until sufficient speed was reached. At which point, the crowbar would start bouncing all over the place, slamming varying metal thingies under the car, and generally making a horrible racket - sounding something like your transmission had just fallen out.

Sure enough, John was driving home that afternoon and all hell broke loose under his car. "Cheezus! What the hell!" Pulling over on a busy street, he peered under the vehicle and instantly saw what was up. And he knew exactly who the culprit was.

A few days went by and Tim figured that either the stunt hadn't worked or John wasn't sure who'd done it. He was driving down I-71, during rush hour after work, when he heard squealing tires and horns sounding directly behind him. He looked in his rearview mirror and saw... thousands of pieces of paper flying everywhere, cars braking and swerving, just an unbelievable paper storm that seemed to be emanating from his car.

He managed to pull over to the side of the road. Checking his undercarriage, he saw what John had done. A "Yellow Pages" directory had been cabled to his car. It had just dragged along on the ground for a while, until sufficient friction had built up; it then started flinging pages, one by one in machine-gun fashion, everywhere.

At that point Tim decided that a "coupe de grace" was appropriate. One final payback so depraved, so horrible, that it would be the final act in their long-running series of pranks.

So one evening he and a few friends stayed late after work. John's hard-walled office was situated directly across the hall from the men's bathroom. Tim, with some expert mechanical help, re-routed the exhaust fan from directly over the toilet. He routed it into the HVAC for John's office, directly over the desk.

Things went back to normal, at least for a few days. John didn't notice anything. Must have been no one was stinking up the bathroom too badly. Finally, one Wednesday, John had a sales rep visiting and they were in his office with the door closed.

Tim watched as Jeff, a grizzled manufacturing guy known for eating all sorts of unhealthy slop, headed to the bathroom. Holy s**t... Tim knew Jeff had just had a nasty sausage lunch that had to be headed for oblivion. He watched as Jeff entered the bathroom and locked the door. And he waited. And waited.

Both doors remained closed for at least ten minutes. Finally, he heard the toilet flush, the sink run, and Jeff came out with a spring in his step. Not 30 seconds later, John and the customer burst out of his office. "CHEEZUS, WHAT THE HELL STINKS IN HERE!" John was freaking out, the sales rep was nauseated and had to leave. Tim tried to look innocent, so he turned away, doubled over in apoplectic laughter.

I never really found out how the "prank wars" ended. In fact, as far as I know, it could still be going on today. I do know this. If you happen to see either of them around, don't bother trying a practical joke on them. Biting off more you than can chew is the operative phrase.

Friday, May 21, 2004


How Zaxxon Taught Me to Program

ARCADE FEVER The Fan's Guide to The Golden Age of Video GamesI don't know many of you remember the arcade game Zaxxon. I do know that seeing Zaxxon for the first time -- in the mid-eighties -- transformed my feelings on user interface.

Until Zaxxon appeared, and even for a significant time thereafter, arcade games were centered in two-dimensional worlds. Space Invaders, Asteroids, Galaga, Qix... some of the names escape me, but they were flat. Stuck in a world that was one pixel deep.

But Zaxxon changed all of the ground rules, introducing a fascinating, unique and three dimensional landscape. And it opened up my eyes to alternative designs for even the relatively tame process-control software I worked on at that time.

Yes, I was still at the O Corporation (described in exquisitely boring detail in earlier blog entries). And one of our more advanced process control devices used a radioactive source (say, Cesium-137) and a matching detector to scan the width of plastic sheets. Here's a stupid-looking text "diagram" that imagines we are standing at the very end of the line looking forward as plastic sheeting comes toward us:


|| -> detector
----- Plastic Sheet -----
|| -> source


The sheet would be running in belt fashion toward the end of the line and the detector and source would move in tandem. The software we created would read the measurement signal from the detector, calculate the depth of the plastic sheet along its width, and render a pretty picture of it in 2D.


X X X X
X X X X X XXXX
XXX X X X X X XXXX
XXXXX X XXXXXX XXX X XXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX
X X X X X X X
X X X


The whole point of our system, though, was not just to render the excess width (and, thus, expensive wastage), but to support real-time control of the width. The problem was the dimensional nature of the sheeting. The plastic was controlled by a series of bolts (around 32, I think). If you screwed a bolt down, less plastic came out at that point. And if you opened it up, more plastic came out.

Making sure the plastic was as flat as possible was the key. No waste, lots of money saved, happy bosses and fat bonus checks. Yeah, sure.

Anyhow, the early attempts at control just divided the width of the plastic into cross-sections, matched each section up with a bolt, and ran a straight PID feedback loop. What they quickly discovered was the "squish" effect. That is if you tried to respond to a bump in the plastic "web" by just screwing down on the bump using PID, you simply got two bumps on either side of the bolt. In other words, the plastic just kind of got "squished" down at that point and resurfaced elsewhere.

I was sent up to company "B" in upstate New York for a month to figure out how to tackle this issue. Luckily, it was the summer. If it had been winter, I might only be surfacing now as a frozen historical oddity like the ancient glacier-dude they found a while back in Switzerland. Only the archaelogists would be wondering about my pocket-protector and tape-covered glasses.

Anyhow, with a week to go, I still hadn't come any closer to a solution to the squish problem. I grew panicky. As I passed a local arcade, I started thinking about Zaxxon and its "3D belt" user interface. Was there a three-dimensional solution to the problem? What if we took adjacent bolts into the equation... and time-phased the bolt adjustment? In other words, could we take another dimension into account?

After a bunch of late night tinkering with the algorithm, I was ready for testing. We kicked off a few runs and, sure enough, the results were much better. We played around with the adjacent bolt algorithm and with the time-phasing. By Friday, we had results that were, for the first time, quite promising.

I learned from that experience the value of embracing new and different concepts, regardless of their origin, background or creators. And, if that meant more time in the arcades playing games, what's not to like?

Return-codes vs. Exception, Part 336

Rapid Application Development with MozillaToday I was, purely by accident, browsing the Mozilla documentation for details on their browser architecture. I stumbled upon the following section:

Exceptions / nsresult

Code execution can fail at runtime. One programming mechanism to deal with failure is to use exceptions. While Mozilla uses Exceptions in its JavaScript code portions, it does not in C++. One out of several reasons for this is exceptions haven't always been portable, so what was done in the past has stuck. Mozilla C++ code uses return codes to simulate exceptions. That means, while in JavaScript you can use try-catch blocks, in C++ you should check the return code whenever you call an interface method. That return code is of type nsresult. For this reason, the logical return type, as defined in the IDL file, is mapped to an additional method parameter in the C++ code.

The nsresult type is intended to transport additional failure reasons. Instead of simply reporting failure or success, an integer type is used instead, to allow for defining a lot of different error codes...

While I realize their solution is specific to C++, I thought it was worth noting.

Mozilla Exceptions / nsresult


The Pantheon

In the Name of the FatherHe's alive! A.J. Quinnell, among the finest adventure novelists I've ever read, recently emerged in public on a fan's web site. AJQ is a pen name. Many of the other hard-core Quinnell fans figured he had passed on, since his most recently announced book ("The Scalpel") never made it to print and had been scheduled for release years ago.

You may know Quinnell from the popular movie Man on Fire. But the book has been out for more than twenty years. It introduces Creasy, the quiet and deadly ex-mercenary with a penchant for serious revenge. A whole series of Creasy books exist, but are mostly out of print in the U.S. A six month effort of international purchases over the web brought me the entire collection of both Creasy and non-Creasy books.

So imagine my surprise when I read this on Tony's site:

After having maintained this web site for 8 years and never having heard a word from A.J. Quinnell himself, imagine my surprise and excitement, when I received what appeared to be an email, with an attached letter from him. I have done some research and am satisfied that this is a genuine letter from A.J. Quinnell. The letter is reproduced below...


I was greatly interested to read Quinnell's book recommendations:

...American writer Charles McCarry whose 2 books 'Tears of autumn' and 'The secret lovers' I regard as masterpieces. Of course they are out of print, but if you can find them I urge you to do so. I also like Len Deightons early books, particularly 'Funeral in Berlin' and 'Horse under water'...


I was also excited to read that a new Creasy book is (hopefully) coming out soon. The working title is Priests of a dead God. There will also be a Creasy preqel, covering his experiences in Korea and Vietnam.

If you're wondering why myself and the other Quinnell fan-boys are so excited, it's simply this. With C.S. Forester, Raymond Chandler, and Lee Child, A. J. Quinnell ranks at the pinnacle of "The Pantheon". Those are the novelists who have never failed to write exquisite works of action and adventure. You can't go wrong with your purchase of any of their books *.

Quinnell

* And, no, Vince Flynn, we booted you out of the Pantheon with your release of "Executive Power".

Thursday, May 20, 2004


Return-codes vs. Exceptions, Part 228

Measures for Excellence: Reliable Software on Time, Within Budget (Yourdon Press Computing Series)Pete's blog had a good critique of my last blog entry on return-codes versus exceptions. The examples were quite accurate, though...

I guess I'm beating a horse that's not only dead, but is already sleeping with the fishes (and Big Pussy) in the Hudson river... but,

I had comments inserted (the "// log" lines) where logging and instrumentation would go... the idea being that we could reconstruct a series of faults from the lowest level as we audited or unit-tested the code. I'm not sure how we would do that in Pete's examples - feedback?

The idea is that we end up with a log like this:

11:01:00 TableDebits.Lock failed for table 'ade1201' (layer 3)
11:01:00 Table 'ade1201' update failed - locking fault - rolled back (layer 2)
11:01:00 "Transfer failed, please try again later" (layer 1, the UI)


Again, this is a highly simplified example, but hopefully that indicates the kind of detailed logging/instrumentation I'd like to see at every step of the way.

Wednesday, May 19, 2004


Return-codes vs. Exceptions, Part 129

User Interface Design for ProgrammersThere's been an ongoing debate in the software development world regarding whether return-codes or exceptions should be used. Here's a brief recap.

Joel lists several good reasons why return-codes are preferred over exceptions:

#1 "They (exceptions) are invisible in the source code" - thus, they are difficult to maintain ("...even careful code inspection doesn't reveal potential bugs")

#2 "They create too many possible exit points for a function" - effective cleanup code is predicated upon predictable unwinding of state as a method or function terminates

Joel continues, "...I consider exceptions to be no better than "goto's", considered harmful since the 1960s, in that they create an abrupt jump from one point of code to another. In fact they are significantly worse than goto's..."

Sergio states (regarding Joel), "His stance against exceptions as a method for handling abnormal program behaviour is just plain wrong. Joel recommends using error return codes, and dealing with them immediatly. There are two big problems with this approach:

It places abnormal behaviour treatment inline with normal execution. It hurts code readability.

Without exceptions, dealing with code transactions and rollbacks produces an imense tangling of ifs or procedure calls.

There is a valid discussion open on whether exceptions should be checked or unchecked, but the mechanism itself is, for me, proven..."

Ned agrees with Sergio, "Exceptions keep the code clean". At least he provides some examples.

And, in a recent interview, James Gosling had some interesting things to say. He wasn't speaking directly about exceptions versus return-codes, but he had some salient points that relate to the mission-critical software world.

"You talk to people in banks, where large quantities of money get lost if there's a problem. They take failure very seriously. The spookiest folks are the people who have been doing real time software for a long time. I've spent a certain amount of time with that crowd. By and large these folks are very conservative and very careful. A lot of them know what it's like to go visit the family of the deceased and explain the bug to them. There are a number of places that have policies that if a test pilot augers in, then once it's all figured out what happened, the people who engineered the thing that failed have to go explain it to the family. I've actually only met one person who has ever actually had to do that. That would change your attitude about dealing with failure really quickly"


Here's my take: Joel is dead-on. I'll tackle Sergio's item number one first. Look: we (the software development community) have a problem with software quality. I don't think I'll get much disagreement on this fact. Software quality, in general, sucks. The reason for this is that many developers are too lazy to instrument, monitor and and respond to all sorts of strange conditions.

In other words, many of us are undisciplined. We're more worried about "readability" (and I disagree with that contention as well - but I'll get to that) than whether or not or software will kill anyone, debit the wrong account by a million bucks, or screw up the actuarial table for 83 year-old transvestites.

Like it or not, dealing with aberrant conditions is a contract we agree to when we decide to be professional and responsible software developers. Treating "abnormal behaviour inline with normal execution" is a misstatement. We need to deal with the unexpected. And the best place to do it is the place where you can "unwind" the logic that's gone bad.

My guess is that Sergio never wrote a database engine or other mission-critical, system-level code. This is the kind of logic you'd implement (it's a simplified example only, so please don't send me syntax error, faulty logic, or "you coulda used diagnostic macros" messages):



do { try {

if ((rc = tableCredits.open()) != OK) {
// log
break;
}
bUnwindTableCreditsOpen = TRUE;

if ((rc = tableCredits.lock()) != OK) {
// log
break;
}
bUnwindTableCreditsLock = TRUE;

if ((rc = tableDebits.open()) != OK) {
// log
break;
}
bUnwindTableDebitsOpen = TRUE;

if ((rc = tableDebits.lock()) != OK) {
// log
break;
}
bUnwindowTableDebitsLock = TRUE;

if ((rc = ::IntegralTransaction(tableCredits, tableDebits, curAmount)) != 0) {
// log
break;
}

} catch (...) {
// catch miscellaneous exceptions here
} } while (0);

if (bUnwindTableDebitsUnlock) {
tableDebits.unlock();
}
if (bUnwindTableDebitsOpen) {
tableDebits.close();
}
if (bUnwindTableCreditsLock) {
tableCredits.unlock();
}
if (bUnwindTableCreditsOpen) {
tableCredits.close();
}
return (rc);


Can you imagine trying to unwind these kinds of "abnormal events" outside the scope of the method that was orchestrating this sort of activity? It wouldn't be fun.

And my take is that readability isn't compromised here. No one is espousing tons of nested if's or other convoluted logic to keep track of state. Do it the easy way. If you have to throw an exception, do it. Right to the bottom of your method. Or, if you can't, hit the "break" (pun intended). Either way, you can start unwinding based upon your current state without compromising the integrity of an 84 year-old transvestite's term-life premium.

Trust no one. Check everything. Log everything. Go forth and prosper.

Tuesday, May 18, 2004


A bald-faced bug

The Enemy - Lee ChildAny developer has their "toughest bug they ever cracked" story. I'm no different.

Those of you who know me know that I'm hair-challenged. Thinning on top. Approaching cleanhead status. Alright, I'm basically bald. This is the story of how I got bald over the period of two days. Ripping out clumps of hair in frustration. Cats and dogs, sleeping together. Total chaos.

I had this small utility program I'd created in ANSI C running on a mid-range HP/UX server. Mid-eighties. The program was no more than five or six hundred lines in length. It read some input files and did some calculations for motion control. I think it created pre-planned routes for a high-speed turning machine that cut specially shaped pistons for Cadillac. Either that or it was routing air traffic over LaGuardia.

Anyhow, the program would do some complicated calculations and run for a while. Most of the time it would work. In fact, it might work perfectly forty times in a row. But on the forty-first run, it would crash. And it was completely random. It might work forty times, crash twice, work another five times, crash, then work fifty times.

I threw in printf's to isolate the location of the crash (no IDE's available on the HP/UX back then, Jimbo). It was crashing in RANDOM FRICKING LOCATIONS every time. WTF?

I analyzed the time-of-day of each crash. Nothing. It didn't seem to be time-based.

I analyzed the input data. The same data file would crash sometimes and not crash other times.

Exasperated, I started stripping out large chunks of code. The math calculations got stripped out, over several iterations, until there were no calculations whatsoever. Still crashed. Cheezus. What in the...?

I excised the up-front error-checking. Nada. Same results. And it was crashing in random locations!

Now all I had the was the loop that read the input file and pre-processed the data for calculation. Ripped out the pre-processor part. ARGGHHHGH! It still crashed.

All that remained was a loop and an fscanf that read the raw input data into the initial data variables. I removed the fscanf.

It worked. Well, it better, given that the whole damn program was just a freaking loop now. Something in the fscanf was toasting something else, given the random location of the crashes.

Long story short: one of the data items was overranging fscanf's load of a variable. Just one in a series of eight or nine. And since HP/UX's I/O subsystem was handling the fscanf (to give time back to the system)... the subsystem was occasionally blowing away my process - randomly, just to ratchet up the fun factor.

So... the I/O subsystem was randomly crashing the application code. Hey, HP/UX designer! Nice separation of process and system code! Okay, that's my frustration talking, it really wasn't their fault.

Lesson learned: separate steps wherever possible. For example, read input data into a buffer, _then_ sscanf it. Don't mask too many operations in the interest of "more elegant" code. You might end up, ahem, hair-challenged.