Sunday, February 25, 2007

The Old New Thing

I also really enjoyed The Old New Thing by Raymond Chen, a long time programmer at Microsoft. This is a collection of his writing, much of it from his blog of the same name, about Windows software development. It ranges from history, to how-to, to humor.

After I finish a book, one measure of how "interesting" I found it, is the number of sticky markers I've added. This book ended up with quite a few.

Although my impression of Windows as a baroque hodge-podge was reinforced by the book, at the same time I also gained a new sympathy for the difficulties of developing software as widely used (and abused) as Windows.

I've already applied one of the small exercises in the book (converting a bitmap to a brush) to Suneido to accomplish a task I've been wanting to do for a long time, but just didn't know a reasonable way to go about it. In the process though I struggled through a typical example of the difficulties in Windows programming. I wanted to find the size of the bitmap - something that wasn't covered in the example in the book. You'd think that would be an obvious, simple thing to want to do. Guess what API call you use? "GetObject". And, of course, it's not under the bitmap section of MSDN, because it works on other things as well as bitmaps. Nor is it linked to LoadImage, although I would think that getting information about the image would be the obvious next step after loading it. It's another one of those things that's trivial once you know it, but next to impossible if you don't. What did we do before Google?

I'm pretty sure I'll be able to apply several other things I learned from this book - definitely a worthwhile book if you're a Windows programmer.

Dreaming in Code

I recently read Scott Rosenberg's book Dreaming in Code - about the development of Chandler, the Open Source Applications Foundation (OSAF) personal information manager. I'd recommend it - it's interesting and well written. For anyone dreaming of creating software, it's a scary story.

If you haven't heard of Chandler, don't feel bad. Despite the project being started in 2001 it has yet to release an actual product. The web site says they're "getting close" to a "preview release". Coming from a small business background it's hard to comprehend how anyone can go that long and spend that much money without actually producing anything for people to use.

One lesson I think the book illustrates is that constraints are good. Given virtually unlimited time and money what will you produce? Judging by this story, probably nothing.

Drag and Drop to Firefox

This blog post - Upload Files in a Browser Using Drag and Drop - describes a great add-on for Firefox - that lets you drag and drop files to your browser instead of either typing the complete file path, or browsing to it. You can even drag and drop multiple files at a time.

Even my wife complains about the awkwardness of attaching files to Gmail messages. I've suggested zipping up multiple files so she only has to attach one zip file, but to her, that's just adding complexity. I think she'll be happy with this new trick. (Once I get around to installing it on her computer and explaining how to use it.)

Bad Code

Soon after writing my Good Code post I ran into some code that really sucked. It was hard to understand and hard to modify. The sad part was that it met most of my "good code" criteria - it had reasonable names, little duplication, and small methods. You could criticize some of the coupling, but that wasn't the cause of its "ugliness". (In the process of refactoring it I found several bugs, which demonstrates that "good code" is not just an aesthetic judgment, but really does affect the quality of software products.)

Knowing some of the history of the code, how it had grown, I could see why it ended up like it did. You could blame some of the problems on insufficient refactoring as it was worked on. The programmers working on it had just been concerned with getting their task accomplished. If they noticed how ugly it had become, they probably felt they didn't have time to do anything about it.

The lesson is that the criteria in Good Code are necessary, but not sufficient. You need to do them, but you also need to think about whether the end result is understandable.

Sunday, February 18, 2007

Monster Palm

I recently ran across Bruce Tognazzini's web site Ask Tog. (I'd previously read his book Tog on Interface - recommended.)

One of his articles was Make Your PalmOne a Monster Machine

My list would include:

TextPlus - Suggests words and phrases as you enter letters. This makes entering text on the Palm hugely more efficient. I'd have a hard time living without this now. The ability to add your own words and phrases makes it even better.

Wikipedia for Palm (and other platforms) - I have the 2 gb version on an SD card. It's great traveling to be able to look up information about where you're going. Or to scratch a curiosity itch when you're away from the Internet.

Noah Pro - a dictionary with 122,000 words. Again, great when traveling and away from the Internet. I always hate it when I come across a word that I don't understand, or aren't sure of the exact meaning.

Bonsai - an outliner for Palm and Windows. I use this to keep to-do lists, shopping lists, ideas, packing lists, etc.

Aigo - a Go game for Palm. Considering the limited capabilities of the platform it plays amazingly well. It probably won't be good enough for a real Go player, but for someone who just fools around like me, it's great. This is the only game I play at all, and I don't play it much. I had a chess game on my Palm for a while, but never used it.

I've also been checking out the software Tog recommends in his Make Your Mac a Monster Machine article.

Surprisingly, I couldn't find an RSS feed for his web site. Tog is falling behind the times!

My Mouse Has Two Buttons!

I'm almost embarrassed to tell this story! Again, Mac users will be shaking their heads.

Since I got my new Mac, I've been cursing the lack of a "right-click". I've gotten really accustomed to using this on Windows. It was especially bad when I was running Windows under Parallels. I kept thinking that Apple really needed to drop their old obsession with one-button mice.

I tried using the configuration where holding down the mouse button is eventually treated as a right click. But if the delay was too short I kept getting it by mistake, and if it was too long I got impatient. I could use CTRL+SHIFT+click but that seemed pretty awkward.

I knew my "Mighty Mouse" (who picks these names?) had an "extra" button if you pressed on the little scroll-ball since I annoyingly kept triggering it by mistake and bringing up the dashboard widgets. I wondered if I could re-configure this to be a control/right click.

When I went into the mouse settings, lo and behold there was a setting for clicking on the right hand side of the mouse! My Mighty Mouse does have left and right buttons! That's the problem with overly slick, seamless designs - there are no "affordances" to let you discover their capabilities.

I pull down the choices for the right button but there is no choice for CTRL+click. Strange. But there is a choice for "secondary button" - I wonder what that does? I try it and it seems to do the trick. And it works in Windows under Parallels. Problem solved!

This was a good lesson. It's so easy to make fun of stupid users. We're always amazed when we observe someone using our software in such awkward ways - why don't they do it the "right" way. Or getting complaints from customers about missing features when it's right there in front of them! Obviously, if I had looked at the specs or looked more carefully at the settings I would have solved this a lot sooner. But if I can fall into this trap, with umpteen years of experience in the business, it's hard to blame someone who has little or no experience.

Thursday, February 15, 2007

Mac OS X with Windows Printer

I struggled on this one for a while. My printer (Epson 2200) is hooked up to my main Windows box and shared so my wife and I can print to it from our Windows laptops via wireless.

I could find and add the printer in the Mac printer setup but it wouldn't work. I was getting NT_STATUS_ACCESS_DENIED.

Searching the web found many people with the same problem. I eventually got it working by using the Advanced printer setup (a little tricky to find) and using a URI of:

smb://andrew:@mckinlayhome/epson2200

Judging by what I found on the web this has been an ongoing problem with OS X. I wonder why it hasn't been fixed?

Funnily, my copy of Windows running under Parallels on the Mac had no problem connecting to the printer.

Monday, February 12, 2007

Rogers.com won't take no for an answer!

This is classic - they give you a checkbox to say whether you want email, but they won't let you save unless you say "yes"!


So I changed my email address to nospam@really.com :-)

Sunday, February 11, 2007

Good Code

After 30 plus years of programming, the basics of good code has boiled down in my mind to just a few things:
  • Good names
  • Consistency
  • No duplication
  • Small pieces
  • Loosely coupled
These are roughly ordered by scale - from individual "words", to lines, to modules.

None of these are original. They have all been endlessly discussed, analyzed, and written about.

Good names

Why is "i = j * 2 + k" bad? Because you have no idea what it means without studying a much bigger context of code to try to figure out what i, j, k, and 2 mean.

It isn't just that you should have long names, they also need to be accurate. A name that was once accurate but has since drifted into being use other ways is just as bad as a comment that gets out of sync with the code.

Not all good names need to be long. There's nothing wrong with using "i" for a loop index, where it's obvious what it is.

Good names often eliminate (or at least greatly reduce) the need for comments.

Consistency

Consistency ties in with good names. Use the same name consistently for the same purpose. Conversely, do not use the same name for different purposes!

Consistency includes:
  • Coding standards or guidelines
  • Coding idioms
  • Organization, design, architecture
If you can look at a few lines of code and tell who wrote it, then you probably don't have a high level of consistency.

Code reviews, pair programming, and joint ownership of code all help with consistency.

No duplication

Programming by "copy and paste" is easy and quick. It's code re-use - isn't that supposed to be good?

The problem is that code isn't "write-only". You're going to need to fix it, improve it, add features to it. And that becomes much harder when you've got the code in multiple places.

Another problem is that it usually isn't just "copy and paste", it's "copy, paste, modify". So now you not only have multiple copies of the code, but they're each slightly different. Even tougher to work with. And it lowers your consistency.

But there are subtle advantages to DRY (Don't Repeat Yourself) that are just as important as these obvious issues. To avoid duplication, especially when the duplication has variations, you have to think about the code, what is common, what varies, why it varies. Does it vary just because you used different variable names? Maybe you should be consistent. Does it vary because it behaves differently? Maybe whoever uses this code (end user or another programmer) would benefit if it behaved consistently.

Small pieces

In some ways this is both one of the easiest and the toughest guidelines.

It's easy because anyone can see whether you've broken your code up into bite size chunks. You can write automated tools to check function / method / class sizes.

It's hard because it's not just breaking it up, it's how you break it up. You want the pieces to have high cohesion and low coupling, and that's hard. We've been struggling with this one for a long time e.g. Yourdon & Constantine covered this in depth in Structured Design in 1979!

A big benefit of small pieces comes from giving the pieces good names.

Loosely coupled

If every line of code connected to every other line of code then complexity would go up as the square of the number of lines of code. N squared goes up fast. If this was the case we'd never manage more than tiny programs.

On the other hand if every line was totally independent, then complexity would only go up linearly with the number of lines of code. That's a lot more manageable.

The reality is somewhere between. The bigger a program gets, the more important it is to keep the pieces as independent, loosely coupled, as possible. The higher your coupling is, the bigger the risk that a change will have unexpected side effects (also known as bugs).

Again, this is easier said than done. Structured programming aimed to reduce coupling. One of the big goals/advantages of object-oriented programming is looser coupling. "Interfaces" are another tool. Our tools are getting better. But are programs are also getting bigger.

Thursday, February 08, 2007

Working at Home

Lately I've started working at home some of the time, nominally Tues. and Thurs. - so I'm still around the office at the beginning, middle, and end of the week.

As our business has grown my days have grown more and more interrupted and fragmented. I seem to go from talking to one person to helping another, to supervising another. I could close my office door, but that wouldn't stop people from knocking on it or cornering me when I went for coffee or to the bathroom. And I don't really like the idea of closing my door anyway.

I could tell people to get lost, but the truth is I still want to deal with all these things. I'm not ready to step back totally, even if somehow I could. I still want to guide and help people. I just don't want to do it 100% of the time. Or more accurately, I still want to spend some of my time programming.

I want to spend time programming because that's what I enjoy doing. But I think it's probably good for the company as well. There are things that I can work on that will be beneficial, that would never get done otherwise, either because they're things like Suneido C++ internals that no one else works on, or because they're general enhancements that will never be "urgent".

I'm finding my programming time at home surprisingly enjoyable. I guess it shouldn't be surprising - I wouldn't have been programming for 30 years if I didn't enjoy it. But it's been a long time since I was able to focus on it for significant periods of time. On top of the pleasure of coding, it's also nice to feel like I'm getting things done. You don't get that as much when you're managing. In the big picture you're still getting things done, but it's not as personal.

For a lot of people, there would probably be more distractions at home than at work, but I haven't found that. I don't sleep in or watch tv or read a book. I actually want to be programming. And because of that, I'm less likely to be sucked into email or surfing the web. At work, when I know I'm liable to be interrupted any minute, it seems like I might as well kill time, since it's pointless to start anything more serious.

I'm not sure what my staff thinks about it. I wonder if some of them might resent it or feel like I'm "abandoning" them. Hopefully they'll be ok with it. They're certainly capable of operating without me.

An added (intended) benefit is I've been getting on the treadmill first thing in the morning. That way I get my exercise for the day, and I only have to shower once :-) And since I don't have to travel to the office, I still start work at more or less the same time.

Funnily, I've still been going in to the office on the weekends, since it's quiet then.

Here's my new Ikea desk, Mac mini, JBL Spot speakers, and Starbucks coffee mug - all the essentials :-)