Worst… Code… Ever…

March 16, 2006 at 12:24 pm

Like many developers, we enjoy making fun of other people’s code. I’ve had lots of those discussions over the years. And when it comes to who has had to work with the worst code, I’ve never lost.


Way back when I was just out of college – when 7-bit ASCII ruled the world, and people hadn’t decided whether lowercase characters were a fad or not – I worked for a Large Seattle Aerospace Company, at Large Seattle Aerospace Company Computer Services, in a group that built graphics tools for engineers.


One of the libraries that we owned was generated code.


Now, I don’t hate generated code. The Windows Forms Designer and I have a generally felicitious relationship. I even have a patent cube (which you get when an application is accepted at Microsoft) sitting on my windowsill that is related to an architecture for doing generated code.


This particular library was special. It goes without saying that the source to the generator was lost in the card recycling bin of time, but that was not what made it unique.


First of all, it was in FORTRAN. And not that namby-pamby FORTRAN where you can have modern control structures, this was FORTRAN 77, and you had better know how to count spaces and what it meant to put a character in column 6. Did you think that python came up with the idea of significant whitespace? Pshaw.


Secondly, the programmer who had written the code generator was a bit of a FORTRAN afficianado. There’s a feature in FORTRAN 77 known as the “assigned goto”. Here’s an example:


      ASSIGN 30 TO LABEL
      NUM = 40
      GO TO LABEL
      NUM = 50                ! This statement is not executed
30    ASSIGN 1000 TO IFMT
      PRINT IFMT, NUM         ! IFMT is the format specifier
1000  FORMAT(1X,I4)
      END


Now, to understand this, you have to remember that by default, any variable that starts with the letters I-N is implicitly an INTEGER variable (all others are implicitly REAL). So, you can assign 30 to LABEL (this is *not* the same thing as writing LABEL=30, which means what you expect it to mean), and then use “GO TO LABEL” to goto 30.


Suffice it to say that the developer had never read Dijkstra.


Now, my guess is that while the vast majority of you are thankful that you don’t have to work in FORTRAN, there is a divide in opinion beyond that. Some of you are saying “Well, that’s not really that bad”. But the rest of you are shaking your heads, because you know what is coming.


When you’re doing code generation, you need to somehow come up with variable names. In this case, the developer took the easy way out, and all integer variables were something like “I1344”.


And line numbers also use the same range, starting at 1000 and going on up.


So, it means that the code has lots statements like:


GO TO 11634


and lots statements like:


GO TO I1655


Did I mention that in the fonts of the day, the difference between “1” and “I” was fairly subtle? Even if you did notice the I in front, you had to cope with the fact that


GO TO I1655


really meant


GO TO 3455


At least, it meant that sometimes, but I1655 would be re-assigned when the program ran.


IIRC, there were about 15K lines of this in library.


So, bother me not with tales of poorly-formatted C# code or 2000 line C functions. They are mere trifles. To snatch the rock from my palm will require something stronger. Are you up to the challenge?


(I am a bit worried that there might be some LISP or APL programmers out there…)

TDD and design methodologies

March 7, 2006 at 1:24 pm

(something I posted on our internal agile alias, in response to a question about how design works in TDD…)


There’s an underlying assumption in software engineering that “more design == better design”, despite that fact that the vast majority of us have worked with baroque systems that answer a bunch of questions that nobody ever asked.

 

The traditional theory is that if you don’t do the up front design, your code will be poorly architected, inflexible, and you’ll be in trouble when you try to maintain it. Which is true. But it’s also true that up-front design – especially the “spend a milestone” type of up-front design – often leads to the same result.

 

The ideal architecture is a minimalist one. It provides all the features that are needed and no features that aren’t needed (I mean “features” in the class method sense, not the user-visible sense)

 

The up-front approach attempts to do that without the data around which features are needed and which ones aren’t needed, which always changes along the way.

 

TDD says, “We’re going to figure out what we need and how to put it together along the way. We know we’re not going to get it exactly right the first time, but with our tests we can refactor as necessary

 

Comments?

Practical Tips For Boosting The Performance Of Windows Forms Apps

March 7, 2006 at 12:18 pm

Practical Tips For Boosting The Performance Of Windows Forms Apps

Over-updating…

February 24, 2006 at 12:23 am

Raymond writes an interesting post about how some programs run faster if you hold down the mouse.


This is a classic situation to get yourself into – I’ve probably seen it 5 times, and hit it again recently.


When we’re burning a DVD, the burn engine calls back into the UI layer so that we can update the progress bar. To give the user a single monotonically-increasing progress bar, we (well, Dean, actually) have to play some games with our progress tracking, which means that sometimes we get progress callbacks once a second, and sometimes we get them 100 times a second.


The progress dialog looks fine, but if you look a profile of the burn, you’ll find that a fair amount of time is being spent in the UI code updating. In this case, it’s not a big deal, but I’ve seen cases where programs are spending 90% of their time updating the UI. That takes a 10 second operation and makes it take 100 seconds, which is pretty bad.


The fix? Well, there are two good ones.


The simplest one is to simply update every <N> calls. I traditionally start with N=10, which is guaranteed to same 90% of the overhead, and usually works fine.


If your callbacks are sporadic – as they are in the DVD Maker case – it works better to timebox the updates. Whenever you update the UI, record the time, and then don’t update it again until a specific time has gone by. I usually find 1/4 second to work well.


 

Resistance to pairing

February 3, 2006 at 11:54 am

Paul wrote an informative response to my post on collaboration.

I’ve just been writing some stuff about where I think our group should go in the future, and I’ve decided to downplay pair programming. Not because I think it’s a bad idea, but more because I think that opinions around it tend to be a bit religious.

Instead, I’ve decided to advocate an open environment where pairing can happen in a natural way

Collaborative development, pair programming, etc.

January 31, 2006 at 3:28 am

There have been some interesting discussion on our internal “agile” alias around pair programming, with some advocates and some skeptics.

I wrote something in response to one of the skeptical posters, who (to paraphrase badly and perhaps miss his point) said that he was an introvert and preferred to work alone. Not that I’m advocating forcing something like pair programming on anybody.

Here’s what I wrote, slightly edited to protect the innocent.

*****

The introvert/extrovert concern is an interesting one. I like to be left alone at times, and I’m also a big fan of flow state.
 
But I’m also pushing for us to *experiment with* pair programming in our next cycle. Why?
 
Well, I’ve been on a lot of projects in my career, and I see the same bad things happening over and over again. Code reviews that don’t happen. Important components that one or fewer people on the team understand. Overly grandiose architectures. Re-inventing the wheel. Solutions looking for problems. Bad bugs that are really expensive.
 
Who is at fault? Well, we are.
 
For example:
 
You’ve just finished adding a new feature, and to do so you had to do a bit of re-architecting to fit it in. Do you ask one of your co-workers to review what you’ve done before you check it in?
 
Reasons you get the review
  1. It’s the right thing to do
Reasons you skip the review
  1. You’re an introvert. Given the choice between personal interaction and working on something new, you usually choose something new.
  2. Your co-worker is also an introvert.
  3. Nobody really understands your code because you’re the only one who works on it, so the review may not give useful feedback
  4. You have to get up, leave your office, find the person, and bring them back. Lots of time, and they may not be there.
  5. You get evaluated on the features you produce and don’t feel review pain because of the bugs in your code.
  6. It’s early/late, and you’re by yourself
  7. You don’t want people to say bad things about your code.
There are a lot of factors pushing you to do the wrong thing, so it’s not surprising that the right thing rarely happens.
 
So what about TDD? Well, I think TDD is a great way to get code that has fewer bugs in it, and I don’t underestimate the value in that. But TDD doesn’t address code maintainability issues – you can still write overly grandiose and poorly factored code using TDD. You can still write code that is inconsistent with code elsewhere in the project, or using the wrong library. You can still spend hours trying to figure out something where the group knowledge could have solved it in 5 minutes. And – as I am chagrined to admit – I can still write code that should be under TDD but isn’t because it wasn’t convenient.
 
I don’t think that collaborative development – by which I mean anything from co-location in a big room to pairing – is a silver bullet that is going to solve all these. But I think that it can make a pretty big dent. And as a company, I think we have to figure out a way to stop producing big legacy codebases that nobody wants to work on.

Flow vs. Collaboration

December 16, 2005 at 1:31 pm

I’ve been talking about some agile techniques with one of my co-workers, and one of his concerns about pair programming or not being in separate offices is that he won’t be able to get into a state of flow in that kind of environment.


My limited experience with working on projects in group settings leads me to believe that the benefit you get from informal collaboration is far more important, but I’d like some more data.


What do you think? Is the lack of time for flow a real issue, and if it is, how do you deal with it? Or do you find that the collaboration is more important.

Flow, and Cycling

October 31, 2005 at 10:39 pm

Tonight I read a post by Eldon, where (among other things) he says that he has learned how to lose himself in his ride. I’ve experienced that a number of times – I’m just riding, still paying attention to what’s going on, but not thinking about anything.

I’ve been thinking about how that relates to the flow state when programming. In my experience, it’s a lot easier to get into the flow state when programming than it is to get into the analogous state when riding. It may have to do with the degree to which you can shut out external input. In programming, it’s pretty easy – put on some appropriate music, and lose myself in the task. On the bike, it’s often not possible, since losing oneself can have some pretty bad consequences.

Thoughts? Are the two states analogous, or are they different things entirely?

Bicycle Climbs of Seattle, Eastside Edition

June 16, 2005 at 12:24 pm
Spent a bit of time polishing up my google maps application last night, and it’s ready for public showing.
This is based on an idea I’ve had percolating away in the back of my mind for a few months now…
That takes you to a google map which shows a fair number of climbs around these parts. Click on a climb, and you’ll get a popup with some data about the climb, and click on the name of the climb to go to the detail page.
I feel fairly confident that the length and elevation gain data is correct, and therefore the average gradient is likely to be pretty good as well. The maximum gradient – well, I’ve taken that from the steepest parts of the gradient plot, but there is certainly some chance for error there. Not only do the roads on Topo USA not conform to actual contours (which definitely messes up the gradient plot on any climb with switchbacks), their topo data may also not take into account that grading that takes place during road construction.
I’m looking for:
  • General comments and suggestions
  • New climbs to add, both on the eastside and in Seattle and elsewhere
  • Better data for maximum gradients
  • Descriptions for the climbs.
  • Rankings for the climbs. I currently have green, yellow, and red. I’m going to add something beyond red for climbs like the zoo, but if you think I’m off on the relative ranking of climbs, let me know.
(Technology stuff)
This was originally going to be all generated on the fly, but I’d forgotten how much of a pain it is to work with a database on a web server. So, the data lives in a database on my machine, and there are a set of C# scripts that generate both the detail pages and the xml to drive the google maps page (yes, I know, how 1998 of me). The maps and gradient plots are hand-extracted from Topo USA.

How To Do A Good Performance Investigation

May 27, 2005 at 8:56 pm

More sage words from Rico…


And a followon