Pardon me for waxing nostalgic for a bit before I get to the meat of this entry.
In early 1986, I bought my first self-improvement programming book, The C Programming Language, by Kernighan and Ritchie. At the time, all true C programmers had a copy of this book, and it was never referred to by title, but simply called “K&R” or even “The Bible”. I had a few other computer books, but they were all required reading for whatever class I was taking. Purdue didn’t teach C at the time to its CS students (that started a year or two later), so we were initially taught Pascal. Quite early on, though, I realized that Pascal wasn’t going to cut it and I needed to turn to a language with a bit more flexibility.
The book is very small for a computer book (the 1st Edition is actually tiny) and has a great quote in the Introduction: “Since C is relatively small, it can be described in a small space, and learned quickly.” The Preface to the 2nd Edition says it even better: “C is not a big language, and it is not well served by a big book.” That quote has stuck with me over the years (I didn’t even have to look it up).
Now, since I had picked up this book on my own, and not as required by a class, it took me a while to switch from Pascal. I had more important things to do than to read that silly little book; I had classes to keep up with, basketball games to go to, girls to date and break up with (actually, they probably did most of the breaking up...my memory’s a little foggy on the subject), etc. Finally, I got around to reading it and switching my language of choice for my classes from Pascal to C.
I hung around with some of the systems people at Purdue then (big C people whose names and initials are littered through the BSD source code), and they told me that my C looked like Pascal. Let me show you what they meant. I’ll give an example of how a cool C programmer would write a string comparison function and how I might’ve written one.
/* compare two strings
* return -1 if s1 < s2, 1 if s1 > s2, 0 if equal
*/
int strcmp(char *s1, char *s2) {
for(;*s1==*s2;++s1,++s2)
if(!(*s1))
return 0;
return (*s1<*s2)? -1 : 1;
}
vs.
/*
* Compare two strings terminated by NULL_CHAR (‘\0’)
* return 0 if they are equal,
* -1 if the first is less than the second, and
* 1 if the first is greater than the second
* Two null strings are considered equal and a null
* string is considered to be less than a non-null string
*/
int StringCompare(char *string1, char *string2)
{
char difference = 0; /* ASCII difference between two characters */
/* check for null strings first */
if (string1 == null && string2 == null)
return 0;
if (string1 == null)
return -1;
if (string2 == null)
return 1;
/* loop until we find a terminator in string1
* and check each character. As soon as we find a
* different character, return
*/
while (*string1 != NULL_CHAR)
{
difference = *string1 – *string2;
if (difference == 0)
{
*string1++;
*string2++;
}
else
{
/* we want to return -1/+1 rather
than the ASCII difference */
return (difference < 0) ? -1 : 1;
}
}
/* if we got here, we made it through string1
* so check whether there’s more to string2
*/
if (*string2 != NULL_CHAR)
{
return -1;
}
else
{
return 0;
}
}
If you have access to your C library source code, your strcmp probably doesn’t look exactly like the one above, because it’s most likely written in ANSI C, and the code above is “pre-ANSI”, or “K&R C” (1st Edition).
Anyway, I was told that my code was too Pacal-ish, and too unlike the code samples in K&R. This hurt me a little bit, and was definitely meant as a derogatory statement, so I soon learned to make my code more cryptic, but I never totally unlearned my Pascal lessons, so I was always a bit more verbose than typical K&R style. Eventually I learned that while the statement was meant derogatorily, it was actually a complement.
Mine is quite a bit longer than the cool programmer version, and would have to be tightened up a bit to go into the C library because it has some inefficiencies to it. It also does more than ANSI C requires of strcmp by checking for null strings. I just wrote both of these on the fly, and actually don’t have a C compiler handy at the moment, so hopefully they’re correct, but even if not, you get the idea. Which of the two samples is more readable? Some hardcore C programmers would say the first, because it’s so simple, but most non-C programmers would prefer the second. C programmers, especially systems programmers, pride themselves sometimes on making their code as terse and cryptic looking as possible, while other languages such as Pascal are much more verbose. Normally, I wouldn’t even use such non-descriptive variable names as string1 and string2, but in a string comparison function, I can’t really be any more descriptive without being silly (e.g. firstNullTerminatedString, secondNullTerminatedString).
This leads me to my real point. The C Programming Language is a great book for learning C, but a terrible book for learning software construction. Everyone using K&R wrote K&R style code, eventually. Over the years, I’ve bought many such books, most of which showed you how to make your code a bit more readable, but they most still all practical books such as Programming C#, by Jesse Liberty, and not practice books. By “practice books” I mean books that tell how to be a better developer, not how to program in Java, C#, or Windows better. Unfortunately, it’s only been in the last year or two that I’ve turned to “practice books”.
The C Programming Language may be “The Bible” of programming in C, but “The Bible” of software construction is Code Complete, 2nd Edition, by Steven McConnell, so that’s one of the ones I started with. I know, I know, it’s been on my “currently reading” list for a year, but I only got serious about it a month or so ago, and finally finished it last night. Unlike K&R, CC2E is not a small book. It tilts the scale at 864 pages + index & bibliography, and has 35 chapters. Believe it or not, it is fairly concise for the breadth of the topic it covers. Whole books can be (and have been) written on the topics covered in a single chapter of CC2E.
The book has some small issues with it, and I think deserved another round of editor review before being sent to the publishers. Despite being published in 2004, there’s almost nothing in the book concerning C#, and when Visual Basic is mentioned, it’s unclear whether he’s discussing “legacy” VB or VB.NET. As a matter of fact there are “Visual Basic” examples in the book that only work in “legacy” VB, and other examples that only work in VB.NET. There are also (unsurprisingly) parts of the book I don’t totally agree with, one of which I mentioned here. However, the point of the book is not to teach you how to be a better C#, Java, Ada, etc. programmer, it’s how to be better at software construction, or craftsmanship. As such, the text is relatively language agnostic, and the minor details I mentioned above don’t really detract from the book.
Even though it takes a while to get through it, the time spent is well worth the effort. The book is fantastic. Some of the text is obvious and well-known to experienced programmers, but I learned at least one thing in every chapter, and nearly every single section (there are 193 sections, an average of over 5 ½ per chapter). Some of the chapters really hit me hard and made me think, such as “The Pseudocode Programming Process”, “Organizing Straight-Line Code”, “Collaborative Construction”, “Managing Construction”, “Personal Character”, and “Themes in Software Craftsmanship”. Like K&R was on the desk/bookshelf of every C programmer, CC2E should be on the desk/bookshelf of every developer who wants to become more than just a “code-banger”, but who wants to be an “Architect” or “Lead” or whatever buzz-word you prefer. It should be read cover-to-cover, no matter how long it takes you. If you are at that “Architect” or “Team Lead” level (or probably even at the PM level), you need to be reading the book now (and you’ll learn that the second example above is better than the first).
Another thing I learned from the book is how far I still have to go on my “practice books” reading list. At Steve McConnell’s company, Construx, they have 4 levels of software developer, Beginning, Introductory, Competency, and Leadership. In the final chapter he discusses what’s necessary to move to each level, and I’m going to paraphrase the book here without permission:
Introductory Level
Adams, James L. Conceptual Blockbusting: A Guide to Better Ideas, 4th ed.
Bentley, Jon. Programming Pearls, 2nd ed.
Glass, Robert L. Facts and Fallacies of Software Engineering
McConnell, Steve. Software Project Survival Guide
McConnell, Steve. Code Complete, 2nd ed.
Competency Level
Berczuk Stephen P. and Brad Appleton. Software Configuration Management Patterns: Effective Teamwork, Practical Integration
Fowler, Martin. UML Distilled: A Brief Guide to the Standard Object Modeling Language, 3rd ed.
Glass, Robert L. Software Creativity
Kaner, Cem, Jack Falk, Hung Q. Nguyen. Testing Computer Software, 2nd ed.
Larman, Craig. Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process, 2nd. ed.
McConnell, Steve. Rapid Development
Wiegers, Karl. Software Requirements, 2nd ed.
Managers Handbook for Software Development, NASA Goddard Space Flight Center
Leadership Level
Bass, Len, Paul Clements, and Rick Kazman. Software Architecture in Practice, 2nd ed.
Fowler, Martin. Refactoring: Improving the Design of Existing Code
Gamma, Erich, et al. Design Patterns
Gilb, Tom. Principles of Software Engineering Management
Maguire, Steve. Writing Solid Code
Meyer, Bertrand. Object-Oriented Software Construction, 2nd. ed.
Software Management Guidebook, NASA Goddard Space Flight Center
I’d be stuck at the Beginner level, because I’ve read almost none of these books. (How does Construx hire new people? Does everyone start out at Beginner, or do they let people in at higher levels who haven’t read the books, and require them to be read immediately?) Unfortunately, reading them will have to wait, because my next book is Object Thinking, by David West. I’m going to try to read it next week while I’m at the PDC.
Whew! What a long post! But, as I said at the top: A Long Blog Entry for a Long Book. I hope you read it and get as much out of it as I did.