Review:The Practice of Programming
This book is written by some heavyweights in the industry: Brian Kernighan and Rob Pike. I have not read previous efforts such as The UNIX Programming Environment or The C Programming Language, but I understand that they are excellent works. I was hoping that this book would live up to that pedigree.
I was not disappointed. The Practice of Programming is a great resource. I found the book to be a good mix of Steve McConnell's Code Complete, Steve Macguire's Writing Solid Code, and Jon Bentley's Programming Pearls: all excellent works in my experience.
Structure
The book offers nine solid chapters devoted to the practice of programming: the tasks that we perform every day to develop software. They range from the beginning of the process (eg, interface design) to the end (eg, testing); from higher-level considerations (eg, portability) to lower-level (eg, naming).
The authors provide examples culled from their real-world experience. I particularly enjoyed their debugging anecdotes, especially their hubris in discussing their own bugs. The authors also provide illustrative exercises, annotated supplementary reading, and an appendix of collected rules. The quality of these is high.
Style
Kernighan and Pike write with facility, clarity, and authority. It is easy to tell that their advice comes from wisdom and experience. I found the text to be readable and enjoyable, and the examples to be relevant and understandable.
The authors' presentation really makes this book valuable. It is neither dry nor difficult to read. In fact, even when they cover difficult material, they are careful to present it in an accessible manner. A college-level programmer should be able to absorb chapter 9, even though the authors build a toy VM with JIT compiler -- not a trivial undertaking.
Examples
The examples in this book really stand out. There are many, almost one per page. The bad examples are appropriately marked with '?' characters, the good examples are nicely commented, and each is concise and typically adapted from real code.
The authors employ many programming languages to illustrate their points. Although they have a distinct bias towards C and Awk, they also present C++, Java, and Perl code, and are careful to use idioms particular to each language.
Often, they will present several versions of the same program. When they do so, they discuss code length, clarity, and related issues, and compare performance, scrupulously noting the environments used.
For example, in chapter 3 they design a single program and implement it in C, Java, C++, Awk, and Perl. In chapter 6, they apply their testing tips to those programs. I appreciate this kind of continuity in a book.
Nitpickings
I have a few nitpicky comments regarding this book. I really don't like the
authors' predilection for short local names, which seem clear in a book's
example but aren't so sensible when being maintained in real-world code. The
world would have been a better place with a compare_strings
function instead of strcmp.
Scott Meyers counsels us (More Effective C++ Item 6) to prefer
preincrement to postincrement, yet the authors continue to use the latter in
loop control statements. The authors also eschew Java's
boolean/false/true in favour of int/0/1; for what
reason, I am not sure.
Still, these are nitpickings. Those issues are relatively minor, somewhat religious, and do not detract from the value of the book.
Summary
I think this is a good book, and I definitely recommend this sort of reading for colleagues of mine. If you've read the books I listed in the overview, then you can get by without this one. However, I feel that it doesn't hurt to be exposed to slightly different presentations of the same material, if only to reinforce the lessons learned.
While I read this book, I was engaged in a coding standards effort in my previous employment. I did find this book, in conjunction with others, to be a useful resource. In particular, I believe it is the most directly applicable book of its sort to development shops that have a lot of C code. That includes the Linux community.
The Practice of Programming is most suited to an intermediate level programmer, although beginning and advanced programmers will also find knowledge in its pages appropriate to their level.
The book's official site contains source code and other resources.
To purchase this book, head over to Amazon and help Slashdot out.
TABLE OF CONTENTS
Preface
Chapter 1: Style
Chapter 2: Algorithms and Data Structures
Chapter 3: Design and Implementation
Chapter 4:
Interfaces
Chapter 5: Debugging
Chapter 6: Testing
Chapter 7:
Performance
Chapter 8: Portability
Chapter 9: Notation
Epilogue
Appendix: Collected Rules
Index
Linkers are only required to maintain 6 charicters for external references. Just because nearly all modern linkers maintain more does not mean they all do, nor that your code will not be called to run on an old hp (which is the only machine I'm aware of that accually only maintained 6 charicters) I'm always careful that my external references are 6 charicters. Note that this does not mean they are six charicters long, only that the first six charicters are always significant enough.
Maybe this should be in the jargon artical that follows this one...
Any programming language that wasn't designed by God will have flaws; it's inevitable. Besides, most of the languages that are usually considered "better" than C (Scheme, Java, etc.) use run-time interpreters that are usually implemented in C.
TedC
The original intent of Pascal was to teach programming to undergraduate CSci students.
Borland tweaked it quite a bit and turned it into a pretty good C-like systems language.
It's regretable that no one is working that much on new systems languages these days. Most of the interest seems to be with higher level application programming and scripting languages. I think part of the problem is that C is "good enough" -- there isn't any one thing that could be done to make it a really great language, but there are 30 or 40 minor tweaks that that would make it really good (and incompatible with existing code, unfortunately).
TedC
"Pipe dreams" might be a better phrase than "goals".
TedC
A language that can be used to write an operating system or language compiler without dropping down to assembly language too much. A certain amount of asm is probably unavoidable for performance reasons, although good optimizing compilers are getting harder to beat unless you're really an expert asm programmer.
I'll have to look into the five alternatives that you mentioned. I've heard of Eiffel and Dylan, but I thought they were higher level OO languages intended more for application programming that systems programming.
TedC
I do, because I'm resisting the temptation to make up my mind about anything when it comes to programming. I figure that day I do that is the day I start impeding my own progress. Besides, there's nothing worse than working with a progammer who has made up their mind, and I don't want to be hard to work with. :-)
TedC
I would assume they don't use boolean because it is not part of C which is where they are coming from. The worst thing you can do in C is declare a boolean type, or possibly worse:
...
...
#define TRUE 1
Ugh, that is such a bad idea. When I write C++ I prefer to see:
if (strcmp(x,y) == 0)
But when I write C, I prefer:
if (!strcmp(x,y))
Different idioms for different languages. (Of course, in C++ I would use a string class, but that was tangential to my point.)
I'm not saying it is illegal in C++. I knew I should have found a better example. C++ can obfuscate your code in too many ways to add more of them.
That may be the most readable code, but it's also wrong.
strcmp returns a value greater, equal to, or less than zero. It does not return 1, 0, and -1. That means you shouldn't compare the return of strcmp with your STRCMPGREATER or STRCMPLESS.
This allows strcmp to be implemented in a very simple and efficient way.
I have always enjoyed Kernighans style (and Ritchies to obviously) I have the elements of programming style on my desktop, and reckon its really useful even if I have to translate the points made from PL/1 and fortran (I can't remember which they use) to C(++) and Perl.
I have to point out that using an int as a Flag or True/False allows you to do 2 extra things -
1 it can be used as a simple semaphore which is always handy and still preserves the true/false testing by having a 0 or not 0 state
2 it can be used as True/False/ErrorCode(n)/ErrorCode(n+1)
and again preserve the testing by having a 1 or not 1 state
The flag could also be used to return an int value as a result and maintain state in the same way as a semaphore.
Using a true/false bool type limits it really badly.
Aaron
Intranet/Internet Developer & Linux Advocate
I had NO idea I was addressing a bodhisattva of coding wisdom... perhaps I should ditch my job, give away my belongs and follow you barefoot for the next decade...
On the other hand, your attitude indicates that while you may (again, MAY) be 'enlightened', maybe you're such a pain in the a$$ to work with that you have little opportunity to share your knowledge with others.
Before knocking the 'world' others live in, why not check out your own? Yours seems to be full of road signs that indicate that only *you* know the right way... or better still, join the real world that the rest of us poor stiffs have to live in... you might find it refreshing.
I haven't read 'Code Complete' before, so take this with a grain of salt. If I were going to buy a 'coding best practices' book it would be most likely this one, simply because Kernighan and Pike are the authors. These are two guys who have been writing solid (and in many cases, revolutionary) code for DECADES now.
On the other hand, I never heard of the guy who wrote 'Code Complete' before the book came out. And (warning: anti-Mickeysludge diatribe follows) from the several unpleasant times I've actually seen M$ code before there may not be a SINGLE PRODUCT from M$ written with any of the techniques 'Code Complete' advocates.
*Programmer to Customer* 'Yep, Mr. Smith, using our nifty new evolutionary software engineering process, we can produce a program that works FABULOUSLY... and we can deliver it in a mere 1.5 million years...'
If you're going ot be dealing with normal, human timeframes, evolutionary programming is unlikely to deliver the goods. This is the reason why bridges and buildings are designed and built by people, rather than letting a few packs of chimps loose in a forest full of hardwoods and saying 'we'll be back for our structure in a few eons...'.
You mean you know of a skyscraper that was completely evolved from scratch? One where wild animals were let loose on a set of raw materials at close to their lowest form, and through almost completely random action, along with natural selection and survival of the fittest, produced a completed building?
If you have, I suggest you alert the media. Otherwise, I think what you mean is that the designers and builders tweaked things as it went along. that's completely different from what people mean by 'evolutionary' programming.
Choose a language because it efficiently maps onto the problem set. C has proven that it maps well onto a wide range of problem sets.
Soustrup designed C++ because the language he was using didn't map well. That's a good reason to switch languages.
You should never pick a language because it is "new" or even because it is "interesting", but because it does a good job with the problem at hand.
I imagine that was a very illuminating and entertaining course. I've only seen Pike in person a couple of times at a Usenix sometime in the previous decade. Among other things, he delivered a paper wearing harem pants (him, not the paper).
-- Alastair
If you try something like: if (a == TRUE)
it maps to: if (a == !0)
which means if (a == 1) NOT if (a != 0)
so non-1 values of a will still fail this test.
Bottom Line: Don't test against TRUE/FALSE no matter how they are defined
From reading the other comments here, it seems that several readers agree that this book isn't truly necessary if you've already "been around the block", so to speak. That may be true.
However, I am still seriously considering getting this book so that when people ask me "what's a good book on programming", I can reach over to my shelf and grab a good book before they accidentally pick up the latest boat-anchor by some dubious author such as Herbert Schildt* or the like. All too often, people buy books based on size or weight, and not on the solidity of the content. (Even K&R2's latest reprinting is twice as thick as the one I bought, but with the same number of pages.)
If you're a good, professional coder in any reasonable organization, you will eventually be asked to mentor, tutor, or otherwise assist less-experienced programmers. Make sure you can make the best of the opportunity by having appropriate resources ready.
(*Note: I realize that my comments regarding Schildt might be slightly inflammatory to some, but they're not without some forethought. See the comp.lang.c FAQ for more information. And no, I don't let the FAQs think for me -- I've actually seen Schildt's work and found it atrocious. I reference the FAQ since it points out most of the same things I would and more.)
--Joe--
Program Intellivision!
I found this book to be useful, but if you're a halfway experienced programmer, I think you will have dealt with all of these issues and settled on solutions that you are satisfied with.
Everyone has an opinion on variable names, but once you've made up your mind, do you really care how someone else deals with them? Would any advice make you change? This is the sort of thing I am talking about.
This is a good book for someone to look at after completing a few undergrad courses (when they only know enough to be dangerous, and could use the "realignment").
For more experienced programmers, I don't see too much of use.
Just when I'm having fun reading constructive discussion in here, I come across crap like
I would suggest you stop pretending to be an "experienced" programmer and go back and read the book.
Oh Chad, you don't know how many times (a day, perhaps) you benefit from my programming. How droll. And no, I won't tell you what it is or who I am, but if you use a web browser you'll catch the hint.