Seven deadly sins of programming – Sin #2

July 24, 2006 at 5:33 pm

One of the guys on my wing during my freshman year of college was a trust-fund kid. His great-grandfather had done well in the market, and had left some money for each the great-grandkids.


Michael wasn’t paying for his schooling, nor was he paying for his cars, his clothes, his nice stereo, or his ski vacations. But that was okay with us, because he *was* paying for pizza, and he *was* paying for beer. Or his trust fund was.


Everything was fine until spring came around, and Michael got some bad news. His trust fund had been set up to carry him through 4 years of school, but because he spent money so fast, he had burned through all of it in less than two years. He was forced to get a job at the local grocery store to finish the year out, but couldn’t afford tuition and had to leave school and find a job to support himself.


========


It typically shows up in chapter two or three of the programming book. There’s a section titled something like, “What is an object?”, which speaks in flowing terms about the wonderful work of object-oriented development, and uses one of the following examples:



  • Geometric shapes

  • Animals

  • Musical instruments

  • Cephalopods (rare)

In this section, we find out that a square is an example of a polygon, a cheetah is a cat and also a mammal, and so on.


All of this to introduce is to the concept of “is-a”.


We then see an example where we can ask any polygon how much area it covers, tell any mammal to walk, and tell any cat to ignore us while we’re talking to it, all through the wonders of inheritance and virtual methods.


Good taste and a firm grasp of the relative usefullness of this concept would dictate spending 10 or 20 pages explaining these concepts, but most texts significantly exceed that, and most programming assignments spend a fair bit of time on that as well. Kindof like how linked lists rule your life for a month or so.


It’s therefore not surprising that many younger developers think that inheritance is a feature that you should, like, “use” when you write software.


There are a few problems with this.


The first is that “is-a” is, in my experience, a pretty rare relationship between objects. More common is the “looks the same on one dimension but has different behavior across another dimension”.


Good luck implementing this:


public class Monotreme: Mammal
{
    public override GiveBirth()
    {
        // add appropriate implementation here
    }
}


That’s the sort of thing that tends to be non-obvious when you first create an object, but annoying obvious when you’ve bought into the whole inheritance mindset.


That’s not to say that inheritance isn’t useful. It’s just to say that you should understand that a MemoryStream isn’t really a Stream, at least in the true “is-a” sense, and be prepared to deal with it.


The second problem is more philosophical and aesthetic. I recently wrote code like this:


class ClimbList: List<Climb>
{

}


Which seems like a perfectly reasonable thing to do, at least on the surface.


But the surface – or at least the surface area – is a problem. List<T> is a pretty extensive class, and when I defined ClimbList, I was saying that ClimbList does the proper thing when any of the List<T> methods or properties are called.


I’m pretty sure that’s not true. Or at least, I’m not at all sure that it *is* true (I have no tests to support such a belief), but users of ClimbList don’t have any way of knowing that the only methods I’m currently using are Add() and the indexer. Intellisense brings up all of them when I go to call one of the methods I wrote.


Which brings us in a long and roundabout way to our penultimate sin:

Sin #2 – Overuse of Inheritance

So, what should you use if you don’t use inheritance (and I am advocating that you approach it carefully and thoughtfully – it’s a similar decision to adding a virtual method)?


Composition. Make the object a field inside of your object, and then write the forwarders that you need (it’s usually not more than one or two).


And, if you really need inheritance in your design, add it carefully and thoughtfully.

Seven Deadly Sins of Programming – #3

July 18, 2006 at 5:19 pm

I’m sure this is going to be a contentious one. I don’t have a good story about this one, so I’m just going to go right to the sin.


Sin #3 – Overuse of Virtual


There are two schools of thought when it comes to virtual. They are:



  1. Always use virtual

  2. Only use virtual when absolutely necessary

The first group’s argument is that original designer of a class is a poor judge of how the class might ultimately be used. Making all methods virtual allows the users of the class to easily extend/modify the behavior. Non-virtual methods make more work for the user.


(or that’s the argument I’ve heard – please comment if there’s something I missed…)


The argument is true. Virtual does make extensibility easier. The problem with virtual is robustness.


The original designer of a class has a good idea for what the class is about, and the implementation is designed (either explicitly through the tests written with TDD, or more implicitly through the mind of the designer) to support that idea (or contract, if you prefer).


In other words, the designer has an explicit idea about what extension points he wants to support in the class. If virtual is only on those points, then the designer has (or should have) done sufficient testing on those points, and it’s pretty likely that users who extend through those points get the behavior they want. And since only a few methods are virtual, the fact that a specific method is virtual is an important clue to the user that that method *is* an expected extension point.


If virtual is on every method, the user can extend in a lot of ways, but it’s very unlikely that the designer thought of all those ways – or all combinations of those ways – which means that such a user extension is going into uncharted territory. Maybe it doesn’t work when you try it. Maybe it works now, but breaks with the first update when the object behavior changes.


I prefer the “you can only do these 2 things, but I promise that they work” classes to the “you can do any of these 12 things, but they may or may not work” classes.

STP 2006 – one day

July 12, 2006 at 11:46 pm

T- 2.5 days:

It’s the Wednesday before STP. STP is the biggest cycling event in the Seattle area, in which 9000 riders will leave from Seattle, hoping to reach Portland under their own power.

Most will ride 100-125 miles on Saturday, and then finish the remainder of the 204.5 mile route on Sunday. About 20% will leave slightly before sunrise on Saturday, hoping to reach Portland before dark. They plan to spend 10, 12, or even 15 hours in the saddle.

They are, by any reasonable measure, more than a little disturbed.

I am one of those riders.

Of course, cycling is a pasttime of relative insanity.

The casual rider feels sane because he knows “crazy people” who ride 50 miles at a time. The 50-mile-rider feels sane because he knows “crazy people” who ride single day double centuries.

A good indication of the relative insanity of the STP one-day riders is the universal reaction from riders who are thinking of doing it. Their reaction isn’t, “wow, that’s a long day”, or “I wonder if I can make it?”. Nearly universally, their reaction is, “4:45AM starting time? That’s crazy…”

I feel sane because of these people. And they feel sane because of these people, who are crazy enough that they don’t care about their sanity. Which is good, because they are at the top of the pyramid.

T-1.5 days:

Tonight I spent some time getting my stuff together. Here is my list (well, lists, actually – there’s one for my backpack (going on a truck, a second (carried by me) , and one of things to do before I leave.

Bike:

  • Helmet (Giro Pneumo, red/white)
  • Gloves (Pearl Izumi, very gamey)
  • Sunglasses (Bolle)
  • Sunscreen (Coppertone sport 30)
  • Headband (Voler)
  • Shoes (Nike)
  • Camelback (70 oz)
  • 10x Accelerade
  • 4 Clif bars (Chocolate brownie, the only worthwhile flavor)
  • 4 Clif bloks (“Cliff” and “Block” are two words that we can’t spell…)(Cran-Raspberry)
  • Heart Rate Monitor (Polar 720i)
  • Jerky x 2 (1100 mg sodium per serving)
  • Phone (Nokia)
  • Extra tube (Continenta)
  • Jersey (Cannondale) with number already on it. Racers crumple theirs so that they don’t rustle in the wind. You can do this as well, but note that if you wear a camelback over the top, it sort of ruins the effect.

Bag:

To do:

  • Parking pass in truck
  • Bike with number in truck. STP gives you a number card (approximately 85″ x 32″) to go on the front of your bike so that the event photographer can identify you. They also give you a small adhesive label with the number to put on your helmet. Some people put the number tag inside the front of their frame, which identifies the bike but not the riders. The photo proofs aren’t big enough to tell what I look like, so I forgo the card and put the adhesive label on the bike.

T- 6 hours, 45 minutes:

This happens at 8PM on Friday night, where I head to bed. I manage to get some quasi-sleep between worrying whether I’ll hear my alarm.

T-0:

Federal regulations prevent my from actually telling you when I got up, but you can calculate it from the previous entry. I get up, eat a clif bar, have a glass of accelerade (you really need the sugar when you start off early), put in my contacts, and then put on my clothes.

Which brings us to a delicate topic. Chafing is an issue for some riders on long-distance riders. To get around it, you use what is known as “Chamois creme” on the pad inside your shorts (and on the complementary parts of your anatomy) to address the issue. The one I use is known as “Chamois Butt’r” (yes, those cyclists have such a sense of humor). Other cyclists use Bag Balm (Made in Vermont since 1899, for udder care. If you’re childless, you undoubtably find this pretty weird. If you’re a parent who used it on diaper rash, you’re nodding your head). Some of the pros use a creme from Assos, though I avoid it because a) it has menthol in it, which seems like the wrong choice for such an application, and 2) they don’t use cyclists in their ads.

That task completed, I pull on my underarmour base layer (very nice in the heat), and my jersey.

I then put on sunscreen, which is arguably one of the strangest things to do in the middle of the night.

I then leave to pick up F. at his house in Redmond. We get there, load his bike, and I realize I left both my water bottles in the fridge. Back to my house, pick up the bottles, and fly over to UW to the start. Meet up with S., who was also going to ride with us. Drop our bags in the portland van (there are other vans stopping at other places for the two-day riders).

Wait at the start for them to re-open the start (they have to start in waves), and roll through the gate at 5:00 AM.

(All times are ride times, not counting stops)

Mile 1

There’s a steady “tick, tick, tick” as I pedal. I look down, and see that my cadence sensor is hitting my crank. Reach down and move it, but it starts ticking again. Not really a recommended maneuver when you’re riding in a group. Finally stop, and realize that the tabs on the bottom of my carbon fiber bottle cage have broken, and the bottle is sitting on the sensor. Sensor finally gets caught and bent under. No more tick, no more cadence, but I can do without it.

Mile 24: 1:20

We stop at the REI headquarters stop for a nature break. I go to the water station. Fill up the bottle halfway, add in my accelerade powder, shake, top off with water, put on lid. Taste.

Amazing.

REI is on of the pre-eminent outdoor retailers in the world. Cascade is one of the best cycling clubs around. But neither of them know that:

  1. Garden hoses – especially new garden hoses – have lots of plasticizers in them. Not ones that you should be drinking.
  2. You can get hoses that are drinking water safe. They aren’t even that expensive.

If they did, I wouldn’t be drinking a bottle filled with parking lot runoff.

Mile 43.3: 2:24

“The Hill”

Okay, so it’s a bit steep, but if my polar data is right, it’s only a little over 200 feet. Not really a hill in my book. Wouldn’t be in the top 3 on flying wheels.

Mile 60?

So far, we’ve spent most of your time in pacelines. It’s hard not to with this many riders – you will catch up with people and join their line, or if not, you’ll be at the front of another group.

But the problem with the these pacelines is that most of the people aren’t experienced, so the pace wavers up and back, which makes it hard to ride in.

But about this time, we hook up with an organized group, all wearing Vitamin Water jerseys. There are about 6 of them, they rotate every 2 minutes, and – most importantly – they pull a very steady pace. We ride with them for about 2 hours. It is wonderful.

Mile 100: 5:27

The first century ends in Centralia. Many two-day riders stop here. They have a food stop for the one-day riders, but inexplicably all they have is fruit. For somebody who has been eating clif bars, clif bloks, and accelerade, fruit is not high on my list. I have some jerky, and after about 20 minutes, we set out on our second century.

I should note here that 5:27 is the fastest century I’ve done.

Mile 113.4: 6:09

We reach Napavine, WA. Not really noteworthy, except for the fact that they have closed one of their streets for a festival. The street we’d like to ride on. There’s nothing going on on the street, but the officials make us ride very slow for 1/2 mile, and then walk our bikes for 1/8 mile. Nobody knows why, but it slows us down a bunch. It takes us 9 minutes to go 1 mile.

While waiting for a train, I notice two things:

  1. My head hurts
  2. My stomach doesn’t feel good
  3. I don’t feel like eating anything sweet.

This bad. If I don’t eat enough, I’ll run out of carbs and bonk. But at this point, there’s not much I can do about it, so we ride on.

I’m having trouble staying in the pacelines. Like driving in rush hour, small changes in speed up front amplify towards the back, and you spend time alternatively riding hard to close a gap and coasting (or feathering your brakes). Doing that is making me feel worse.

I send another text message to my wife. Usually I just send her the mileage, but this time I tell her that I’m looking for the grupetto. (Sorry about the translated page, but I can’t find a good page in English.)

Mile 128: 7:03

Another stop. Feeling about the same (not good). I’m still not able to drink much accelerade, as it makes my stomach worse. I try to drink more water, which I can tolerate in small quantities.

Mile 140: 7:45

This stop is at Castle Rock High School. I pull off to the side and lay down in the shade of a tree. F and S are concerned. I’m *concerned*, because I still have at least 4 hours of riding left.

After a few minutes, I wander over to the school to experience the wonder that is indoor plumbing, and to buy a peanut butter sandwich and some cold water. This tastes pretty good. On the way back to the shade I pass more than one rider sleeping on the lawn.

When we start riding again, I’m riding behind my friends at my own pace. I look back at one point, and there are two riders drafting behind me. They pull in front, I slide behind, and we pull up to F and S, and now our group is 5.

And I feel sick again.

Turns out that as long as I set the pace, I don’t feel as bad. “Put the sick guy at the front” isn’t the most logical approach, but it works, and I ride either at the front of our group or behind our group.

My legs feel fine. If I keep spinning at around 100 RPM and keep my HR between 110 and 120 (maybe 140 on climbs), things go pretty well. Thank god for the tailwind.

Mile 152.8: 8:27

We take the Lewis & Clark bridge (named after Lewis & Clark, a college in Portland) across the Columbia. I tell S that I may starting singing “Roll on Columbia” on the crossing, but the climb is fairly steep, and while I can remember “Your power is turning our darkness to dawn, so roll on, Columbia, roll on”, I can’t remember any of the seven verses.

On the way down to the Oregon side, the rider in front of my brakes suddenly before an expansion joint, I shout “slowing”, hit the brakes, and hope that the people behind me don’t hit me. That’s not the kind of thing you want to do after 8 1/2 hours on a bike, but everybody else is paying attention, and we get into Oregon fine.

And we still have 50 miles left to ride. Bastards.

I ride on at a steady pace. S and F either lag behind a bit, or ride up in front.

Somewhere around mile 170, F disappears ahead of me. That’s fine – I know that I’m holding both of them up, and while I’m having no fun at all, I’m sure that I’ll finish.

Mile 189: 10:43

I have half a bagel and some pretzels, and dunk my head in water. That helps

Soon after the last stop at 189, S pulls off as well. I ride on, still feeling the same, but thanks to my training, my legs still feel fine. If my head and stomach were okay, this wouldn’t be that bad.

Mile 204.5: 11:46

The finish line celebration. As you pull through on the path, people cheer for you, and you get a “one-day finisher” patch.

I run into F and his mother as I wander around. I go to the adjacent hotel, grab my backpack, and ride to my hotel.

I check in, go to my room (two floor up is hard to climb), and collapse on the bed. My plan had been to take a shower and go out for some food, but it’s all I can do to call my wife, take a shower, take out my contacts, and crawl into bed. My head hurts, and my stomach hurts. I drink as much water as I can (not much) and try to sleep.

I wake up at 12:30, still feeling crappy, drink a whole bottle of water, and then finally get some quality sleep. But I’m awake again at 7AM, miraculously feeling decent, and eat breakfast.

And then I ride 3 miles to the train station (on a very tender butt), and ride Amtrak back to Seattle.

What worked:

  • My training was good. My legs never ran out of steam, and I was always fine aerobically.
  • S and F were good companions
  • The support was pretty good, with the exception of the aforementioned parking lot runoff
  • Riding the train back was a nice way to get back.

What didn’t work very well:

  • I tried to get used to getting up early by getting up at 5 that week. That made me more tired than I thought.
  • In retrospect, I think the headache and stomach upset was sinus/allergy related. I don’t usually have problems in this area, but I think I had a touch of it at Flying Wheels. If I’d taken the right drugs, I would have done better. Southwestern Washington is a lot drier and dustier than Puget Sound.
  • I should have grabbed something real to eat at Centralia.
  • I should have planned for food fatigue. You can only eat the same food for so long.
  • Start pouring water on to cool off earlier.
  • If you stop drinking your energy drink, drink more water. Lots more water.

Food:

I’m surprised how short this list is:

  • 5 bottles accelerade
  • 2 clif bars
  • 2 bags clif bloks
  • 1/2 bagel
  • 1 peanut butter sandwich
  • One chicken-vegetable wrap thingy
  • 1/2 banana
  • 1/2 bag pretzels

Misc:

  • 204.5 miles, 11:46, 17.4 MPH. Not bad for feeling crappy and having that walk in Napavine. Make it 11:40 @ 17.5 MPH without the Napawine slowdown.
  • 4422 calories (Polar estimate)
  • 86930 heartbeats
  • 123 BPM average heart rate
  • 3620 feet elevation gain.

Would I do it again? Well, it was absolutely the worst day I’ve ever spent on a bicycle, but if I didn’t feel so sick, I could see doing it again.