Saturday, August 30, 2008

The BBQ: working great

Well, it’s been over a week. And how’s the BBQ doing? As a matter of fact, it’s doing quite well. Unfortunately, the very first thing I tried was steak, and it didn’t come out well. (A bit more well done than I like, even though I followed instructions which should have made it medium. It wasn’t bad—I still enjoyed it—it was just too well done.) We’ve also done lamb burgers from President’s Choice, which were great, lamb skewers (also President’s Choice, also great), zucchini and eggplant, chicken with BBQ sauce, salmon steaks and salmon kebobs, and finally, burgers. Everything has been great.

Speaking of which, if you want a really good recipe for making burgers, see this recipe. You won’t regret it.

What I haven’t yet done, but hopefully will soon, is try making curry on the side burner. As it is, I’m too busy enjoying the flavour of the BBQ on my other foods, but using the side burner for curry was one of the selling points of this BBQ for me, so I owe it to myself to give it a try.

Wednesday, August 20, 2008

BBQ

We finally—finally!—bought a barbeque. We’ve been living in our townhouse for over three years, and all that time I’ve wanted a BBQ, and now we finally have one.

One of the main things holding us up was that Andrea’s dad had a used one, that he had volunteered to give us, but we never got around to digging it out of his garage. So we finally went and picked it up on Sunday. (Actually, we went on Saturday afternoon and wiped and hosed it down, to get rid of the dust, and then picked it up on Sunday, after it had dried off.) Unfortunately, it turned out that it didn’t work. The burner wasn’t connected properly to the hose from the propane tank, and I couldn’t figure out how to connect it properly. Plus, it was pretty rusty in there. So we decided to go and get a new one, because I didn’t want to mess around with propane connections. Which, in retrospect, I’m happy about, because we also wanted a side burner, which the free one didn’t have.

I had been thinking about getting a Weber. That seems to be the cream of the crop, when it comes to BBQs. However, although Weber BBQs last forever, they are also very expensive. So, after much soul-searching, I decided that it wasn’t worth the money; even if a cheaper BBQ didn’t last forever, it would probably still be cheaper in the long run.

Once I’d made up my mind to get something cheaper, I actually thought about getting a President’s Choice BBQ, from Fortinos. For about half the price of a Weber, I could get a BBQ with a side burner. There was a good chance that it would be a piece of crap, but, on the other hand, President’s Choice is pretty good, so there was also a chance that it would be a good, lasting unit. But we finally gave up, and got a Sterling, which is even cheaper. Who knows how long it will actually last; I’m hoping it’s not a disposable BBQ! (Obviously, if we have to buy a new one every year, we would have been better off getting a Weber…)

Anyway, you probably don’t care about all of that. I got it put together on Monday night, which wasn’t as bad as I’d been led to believe. It took an hour or two, but very little cursing. (I did end up with one extra nut and bolt, which I couldn’t attach; the holes in two pieces of metal that it was supposed to connect together wouldn’t quite line up. But there were three other sets of nuts and bolts keeping them together, so I don’t think it will cause any problems.) I also couldn’t get the lighter button to work, but wasn’t overly worried about it, since we have a lighter.

I had been hoping to fire it up on Tuesday, and cook something. (I’d been further hoping that the “something” I cooked would be a nice, juicy steak.) Unfortunately, we had leftovers in the fridge that we had to eat out. And, since I’m an adult now, and I have to make mature decisions, we decided to eat the leftovers first, and maybe cook something on the BBQ on Wednesday. I did take the opportunity to season the grill, though, and I also figured out why the lighter button hadn’t worked. (I’d missed connecting a wire. And it’s a good thing I figured it out, because the wire was within the BBQ—or very close to it, anyway—and probably would have caught on fire or something.)

I’m crossing my fingers, hoping to be able to cook something tonight. (I’m also crossing my fingers that I’ll be able to cook it well—it will seem like a terrible waste of money to have bought a BBQ, if it turns out I have no BBQing skills.)

Wednesday, August 13, 2008

Beautiful Code: What Is Beautiful Code?

This post is part of the Beautiful Code series.

No complex programming concepts in this post. Just a question: What is beautiful code? What makes code ugly? (And isn’t that a matter of opinion? Pshaw…) Most of the posts so far have been about beautiful ideas encapsulated in the programs, but what about the code itself?

This post is all over the place, so brace yourself for it.

Reusability

To start with, some thoughts from Adam Kolawa.

…. Code reuse significantly reduces the effort required for code development, testing, and maintenance. In fact, it is one of the best ways to increase developers’ productivity and reduce their stress. The problem is that reuse is typically difficult. Very often, code is so complicated and difficult to read that developers find it easier to rewrite code from scratch than to reuse somebody else’s code. Good design and clear, concise code are vital to promoting code reuse.

Unfortunately, much of the code written today falls short in this respect. Nowadays, most of the code written has an inheritance structure, which is encouraged in the hope that it will bring clarity to the code. However, I must admit that I’ve spent hours on end staring at a few lines of code…and still could not decipher what it was supposed to do. This is not beautiful code; it is bad code with a convoluted design. If you cannot tell what the code does by glancing at the naming conventions and several code lines, then the code is too complicated.

Beautiful code should be easy to understand. I hate reading code that was written to show off the developer’s knowledge of the language, and I shouldn’t need to go through 25 files before I can really understand what a piece of it is really doing. The code does not necessarily need to be commented, but its purpose should be explicit, and there should be no ambiguity in each operation. The problem with the new code being written today—especially in the C++ language—is that developers use so much inheritance and overloading that it’s almost impossible to tell what the code is really doing, why it’s doing it, and whether it’s correct. To figure this out, you need to understand all of the hierarchy of inheritance and overloading. If the operation is some kind of complicated overloaded operation, this code is not beautiful to me.

This is an interesting quote—one with which I both agree and disagree. I definitely agree that code which is difficult to understand is not beautiful; Kolawa uses reusability as a criterion for beauty, which I think is a good criterion to use. I also agree that if it takes a few hours to understand what a piece of code is doing, that code is not beautiful, and not reusable.

And I also agree that code written to show off the developer’s knowledge of the language is not beautiful. You might have a very good reason why you had to take advantage of some obscure feature of the language, but if your program is going to be at all maintainable, you’re going to have to comment it so well that you might have been better off finding another way to do it, that other programmers would understand more easily. Either that or you don’t actually care about maintainability; you might feel that people should have to spend hours going through the language reference guides, trying to decipher your code—which is arrogant—or you might just be worried about job security, for which I have no respect.

However, at the same time, this quote also seems to be a diatribe against object-oriented programming. It almost sounds curmudgeonly; “In my day, we didn’t have no object-oriented programmin’. We had miles and miles of procedural code, and that’s the way we liked it!” I agree with Kolawa’s main points, but I disagree that object-oriented programming in general, or C++ in specific, are to blame for bad code (if that’s what he’s saying). You can write clear, concise, object-oriented code, and you can write really terrible object-oriented code. Just as you can with procedural code. It’s true that you have to get your mind around object-oriented programming before object-oriented code is going to make sense to you, but that doesn’t make object-oriented programming bad, or even necessarily more difficult; it’s just a different way of thinking about code. (I can’t believe I’m typing this in 2008.)

On the next page, Kolawa had another quote that I also found interesting:

My next criterion for beautiful code is that you can tell that a lot of thought went into how the code will be running on the computer. What I’m trying to say is that beautiful code never forgets that it will be running on a computer, and that a computer has limitations. As I said earlier in this chapter, computers have limited speed, sometimes operate better on floating-point numbers or integer numbers, and have finite amounts of memory. Beautiful code must consider these limitations of reality. Quite often, people writing code assume that memory is infinite, computer speed is infinite, and so on. This is not beautiful code; it’s arrogant code. Beautiful code is frugal about things like memory use and reuses memory whenever possible.

I have mixed feelings about this quote, too. I find myself wanting to agree, and I do agree under certain conditions, but I also disagree under other conditions. There are cases where a developer should not worry about memory, should not try to optimize for particular CPU architectures, should not worry about the low-level details of a computer. (After all, computer science has been trying to abstract these concepts away almost since its inception.) Writing code in C++ that will run on a Windows desktop is much different from writing code in Java that will run on a J2EE application server.

But, to Kolawa’s point, using memory as an example, even if Java is supposed to abstract away details about memory cleanup, that doesn’t mean that Java code running on a J2EE server can use up as much memory as it wants. Just because some of the details are no longer important, you still have to put some thought into how much memory you’re allocating. Maybe loading up 10MB worth of data into a user’s session every time the user logs in to your web site is a really bad idea. The fact that Java will automatically garbage collect objects when they’re no longer used isn’t going to help you in this case, you’re just wastefully using up too much memory.

The Actual Source Code—The Seven Pillars

This is all well and good, but it’s still a bit too conceptual; what about the code itself? The semi-colons and the tabs and spaces and newlines? What makes that beautiful? Chapter 32 talked about that, based on an article by Christopher Seiwald called Seven Pillars of Pretty Code. I won’t bother to list all of the “pillars”, you can read the article if you wish, but some examples they gave are making code “bookish”, making alike look alike, and overcoming indentation.

“Bookish” Code

When they say making code bookish, they’re talking about a couple of things, which can be summed up by laying out your code the way that text is laid out in books or magazines; “columns” of code shouldn’t be too wide, and it should be broken up into chunks, not put in continuous blocks. The writers commented on this:

Research also seems to show that, when it comes to line lengths of text, there’s a difference between reading speed and reading comprehension. Longer lines can be read faster, but shorter lines are easier to comprehend.

Chunked text is also easier to comprehend than a continuous column of text. That’s why columns in books and magazines are divided into paragraphs. Paragraphs, verses, lists, sidebars, and footnotes are the “transition markers” of text, saying to our brains, “Have you grokked everything so far? Good, please go on.”

As a side note, as of this writing, I still haven’t got around to fixing the width of the text in my blog. My apologies to anyone who’s reading this on a really wide widescreen display. (As another side note, see the definition of “grok” from the Jargon File, if you’re not familiar with the term.)

Making Alike Look Alike

For making alike look alike, they’re just saying that when code blocks that are similar in nature look similar to each other, it’s much easier for the brain to comprehend what’s going on at a glance. They give an example, that looks like this:

while( d.diffs == DD_CONF && ( bf->end != bf->lines() ||
lf1->end != lf1->lines() ||
lf2->end != lf2->lines() ) )
Even if you know nothing about this code—as I don’t—you can easily see how the conditions within that while loop are all similar to each other. The fact that each test looks the same (compare the end member to the result of the lines() method—and not the other way around—indent them all to the same place) makes it easier to comprehend this code.

Overcoming Indentation

And finally—or at least, finally for the points that I’m going to mention here—they mention overcoming indentation. By which they are not saying that you shouldn’t indent code! What they’re saying is that you should avoid nested code as much as possible. (Which, in so doing, will reduce indentation. Which also does help, by the way, since it helps with keeping your columns of text narrow, although the main point here is that we’re trying to avoid nested logic as much as possible.) If you can, try and avoid having nested conditionals in your code; they’ve got a bunch of statistics showing how much harder it is to maintain deeply nested code than code that isn’t nested.

For example, suppose I want to write a function to calculate a tip, based on a bill. But I only want to calculate the tip if it hasn’t already been included on the bill; if it has, the tip is 0. If I had some kind of DTO object, with details about the bill, I might write a method like this:

float calculateTip(Bill bill) {
if (!bill.includesTip) {
for (int i = 0; i < bill.lineItems.length; i++) {
float subTotal += bill.lineItems[i].cost;
}

return subTotal * 0.15;
}

else {
return 0.0;
}
}
This does exactly what I’d said above, and calculates the tip only if it hasn’t already been included on the bill. Unfortunately, it means that the bulk of the code for this method has to be included within that if statement. And that means that the code is inherently a little bit harder to understand. Although the logic isn’t too complex, in this case, when you’re reading that for loop, you do have to keep in mind that this is within the if statement, meaning that it only happens when the tip is not included on the bill.

But there’s another way of looking at this logic; if the bill includes the tip, we can return 0 and exit the method right away:

float calculateTip(Bill bill) {
if (bill.includesTip) {
return 0.0;
}

for (int i = 0; i < bill.lineItems.length; i++) {
float subTotal += bill.lineItems[i].cost;
}

return subTotal * 0.15;
}
Although it logically does the same thing as the version above, the fact that it’s got less nested logic makes it inherently a bit easier to read and comprehend. We took care of the logic of determining if the bill already includes the tip, and once that is done, we can carry on with the rest of the code, and not worry about it again.

Self-Documenting Code

Interestingly, I was surprised at an aspect of code that wasn’t mentioned in the book, but since I’m talking about pretty code, I’ll mention it here. In Martin Fowler’s excellent book Refactoring: Improving the Design of Existing Code—a book I highly recommend—he introduced me to the concept of “self-documenting code”. Let me give a silly example, using Java-like pseudocode:

/* note that I've hard-coded the amounts for tax and tip,
but this isn't real code, it's just illustrating a point,
and in real life I would never do that, blah blah blah */

Bill calculateBill(BillLineItem[] lineItems) {
Bill bill = new Bill();

bill.lineItems = lineItems;

//calculate and set bill subtotal
for(int i = 0; i < lineItems.length; i++) {
float total += lineItem[i].cost;
}
bill.subTotal = total;

//calculate and set tax (PST and GST)
bill.provincialTax = bill.subTotal * 0.06;
bill.federalTax = bill.subTotal * 0.05;

//calculate and set tip
bill.tip = bill.subTotal * 0.15;

return bill;
}
To make the code self-documenting, you might refactor it to make it more like this:

Bill calculateBill(BillLineItem[] lineItems) {
Bill bill = new Bill();

bill.lineItems = lineItems;

calculateAndSetBillSubtotal(bill);

calculateAndSetTax(bill);

calculateAndSetTip(bill);

return bill;
}

void calculateAndSetBillSubtotal(Bill bill) {
for(int i = 0; i < bill.lineItems.length; i++) {
float total += bill.lineItems[i].cost;
}

bill.subTotal = total;
}

void calculateAndSetTax(Bill bill) {
bill.provincialTax = bill.subTotal * 0.06;
bill.federalTax = bill.subTotal * 0.05;
}

void calculateAndSetTip(Bill bill) {
bill.tip = bill.subTotal * 0.15;
}
In other words, where possible, when you have a comment in front of a block of code, you can break it out into its own function instead, and name the function such that it replaces the comment. In general, this simplifies the calling function, and promotes reuse, since the smaller chunk of code is more likely to be usable somewhere else. (Not guaranteed to be reusable, obviously, but there’s more possibility of reusing a smaller piece of code than a larger piece, in general. The larger a block of code is, the more chance that it will have a specialized side effect that you don’t want, when you’re trying to reuse it.)

Now I know—I know!—that I’m going to get a bunch of comments on this example, talking about execution speed and optimization. Especially since the method in question was so simple in the first place. “Why would you take the performance hit of making that a function call… blah blah blah…” Yes, yes, stay with me folks, there are always multiple tradeoffs to consider. But we’re talking about making the code understandable, and if you can make the code self-documenting, instead of putting in explanatory comments, it’s easier to read, and therefore, easier to maintain. (I don’t have statistics to back that up. If you disagree and would like to comment on the fact, feel free—I’m getting good at separating the wheat from the chaff in my comments.)

If you look at the new calculateBill() method, you can see the high-level logic much easier than you could with the previous version. It’s true that you can’t see the details of everything that it’s doing all at once—and that’s the point. You don’t need to know every detail of everything this method is doing all at once. If you’re reading the code to get an idea of what it’s doing, you can look at the calculateBill() method, and not get sidetracked with details about how the tip is calculated; conversely, if you’re tasked with fixing a bug in how the code calculates a tip, you can glance at the calculateBill() method, see that you should be looking at the calculateAndSetTip() method, and concentrate your energies there. And, again, not be bogged down with details on how tax is calculated.

Code Should Be Concise

Another aspect of beautiful code, which was mentioned numerous times by numerous authors in the book, is that it should be concise. I was reminded of this by another quote from Diomidis Spinellis (who was mentioned in the Computer-Generated Code post):

I always feel elated if, after committing a refactoring change, the lines I add are less than the lines I remove.

And I have to say that I have the same feelings. When I’m modifying some code, I get a great feeling of satisfaction when I can make the code smaller, rather than larger. But it should be noted that conciseness is something you have to work at. Typically, you will write code that is longer, and only with some extra thought can you make it more concise.

Along these lines, my email sig includes a bastardization of a quote from Blaise Pascal; it says:

Sorry this email was so long—I didn’t have time to make it shorter.

Tuesday, August 12, 2008

Calzones

If you like calzones, Andrea found a great recipe on AllRecipes.com for Broccoli, Pepperoni and Three Cheese Calzones. We tried it on Sunday, and they were excellent.

Fortunately or unfortunately, the bread is completely hand-made. This is unfortunate because it means that you have to spend hours making the darned things, but fortunate because the bread is really good. I’m sure I’ll make them again, but only if there is a special occasion, that would warrant the work. For example, if the Queen of England were visiting. To ask me to marry her daughter. And she’d specifically mentioned ahead of time that she liked calzones.

Tuesday, August 05, 2008

Blood

I had previously attempted to give blood—and I had previously failed. But it was time to try again on Friday, and this time I was determined to give my blood, come hell or high water.

I was worried that I’d get nauseous again, as I did last time. I did my best to eat properly on Friday—I didn’t even have any coffee that day—and I also had a game plan: If I did get nauseous, I wouldn’t tell them. (It’s a brilliant plan! Foolproof!) Only if it got really bad would I let on that I was nauseous.

We went through all of the same procedures, but this time, there was a lot of waiting involved. There was a big line of people there ahead of me, also giving blood. (Lesson for the day: If you’re going to donate blood, don’t do it at Woodbine, where there are lots of people donating blood. Do it at Sherway Gardens, where there aren’t any lines.

Finally, I got on the table, and they put the needle in. And right away, I felt a bit nauseous. (Andrea still feels that this is psychological.) However, I wasn’t that nauseous; just a bit. So I stuck to my plan, and didn’t tell anyone. (“Are you okay?” “Yep, everything’s fine.”) And it quickly passed, so my plan was a good one. There was a moment of panic, when the woman had to adjust the needle, and pull it a bit further out of the vein; I guess the blood wasn’t flowing as well as she would have liked.

As an aside, there was another woman there, just ahead of me, who was also donating blood. She was the type of person who laughs constantly when she talks, so I was hearing her laughter the whole time I was there. When I was on the table, she was behind me, where I couldn’t see her, but I was constantly hearing her laughter. And then at one point it occurred to me: “Wait a second. She got on the table well before I did, but I still hear her laughter! How long has she been there?!? It’s been at least fifteen minutes—does that mean I have another ten minutes here?” As it turns out, she’d left her table long before, and was sitting at the recovery area; it’s just that, because I couldn’t see her, and could only hear her laughter, I assumed she was still being drained.

In any event, whatever the nurse did with my needle worked, because I was finished much sooner than I’d thought I would be. (Especially given my panic over the woman on the table behind me.)

And then she took the needle out, and I got hit with a real strong wave of nausea. For a moment, I thought I was going to throw up. (Again, people were asking me if I was okay, and I was telling them yes.) Luckily it passed after a few moments. They brought be over to the recovery area, and gave me some juice and cookies, and by the time I finished, I felt completely normal.