text: Clean Code 214) { //do something } if(ex == PrinterOnFireException) { //do something } logException(ex); }.
  You can purchase Clean Code - A Handbook of Agile Software Craftsmanship from amazon.com. Slashdot welcomes readers' book reviews — to see your own review here, read the book review guidelines, then visit the submission page.
  I really want a copy of this... (Score:5, Funny)
  Re:I really want a copy of this... (Score:5, Funny)
  "How to Write Unmaintainable Code".
  Use Perl!
  Re: (Score:3, Funny)
  A real programmer is lazy and uses a random character generator.
  ;p
  Re:I really want a copy of this... (Score:5, Funny)
  Mod parent redundant, gp already said 'Use Perl!'
  Re: (Score:2, Funny)
  Re: (Score:3, Insightful)
  Ken Iverson was a Real Man of Genius.
  Re: (Score:2)
  Re: (Score:3, Insightful)
  Re: (Score:3, Funny)
  Re:I really want a copy of this... (Score:5, Funny)
  to set right next to my "How to Write Unmaintainable Code".
  It's an artform, some people make it look so easy, but to write truly horrible code takes lot of practice. The key is gotos and ifs (preferably nested deeply). Consider the first "clean" sum generator:
  int sum(int n) {
  if(!n) return 0;
  return sum(n-1) + n;
  }
  We'll see about that:
  int sum() { int n,ro,r; ro=-1; n=r=0;
  f: if(n<10) {
  ro=r;
  r=r+n++;
  }
  if(!(ro^r)==0) goto f2;
  if(n>=10) goto f2;
  goto f;
  f2:
  return r;
  }
  It's important to note just how unmaintainable this function is. It's hard coded (the limit is stored in two different places), so that it only calculates the sum of 1...10, (so, in fact, the entire function could be replaced by a a constant integer). It also has a redundant check, to make sure that the two are the same (so that it doesn't get too large), but it might get too small. Naturally, goto is cruise control for cool.
  Re:I really want a copy of this... (Score:4, Interesting)
  Consider the first "clean" sum generator:
  int sum(int n) { if(!n) return 0; return sum(n-1) + n; }
  It's interesting you chose this one. I write a lot of Perl (tens of thousands of lines a year) and you might have done this in perl:
  sub sum {
  my $input = shift;
  if ($input =< 0) return 0;
  return sum($input - 1) + $input;
  }
  at which point you would tried it out on some large number and cried about the performance. Now the code is clean (albeit somewhat lacking in type checking) and it would be a shame to lose that cleanliness in the search for performance. This function is deterministic, so if we can cache the result, we can get the performance we want at the expense of memory usage. So we add the following to our code:
  use Memoize;
  memoize('sum');
  and magically, we get caching on the sum subroutine. And our code remains clean and understandable.
  Just because anyone can write unreadable, unmaintainable Perl doesn't mean you have to...
  Cheers,
  Toby Haynes
  Re:I really want a copy of this... (Score:5, Insightful)
  There are naturally various considerations: Value caching as you mention, whether the programming language optimizes tail recursion, and so forth.
  But the real shenanigans in the function is that you can use mathematics and find that the sum of the series 1...n is n*(n+1)/2 straight away, so making such a function is a moot exercise altogether.
  On the other hand, keeping that sort of mathematics arcane and shrouded in mystery creates thousands of extra programming jobs all across the world.
  Re:I really want a copy of this... (Score:4, Insightful)
  If you're operating in integers with a fixed range, computing n*(n+1)/2 might overflow in situations where computing the sum via a series of additions will not. You need to consider which of (n,n+1) is even, divide only that one by two, then multiply by the other odd term to get something that is both a fast computation and utilizes the full range of the integer size you're working with.
  While the above might seem simply pedantic, consider the case where a program built using a naive sum approach that needed the full range was broken by replacing it with the multiplication-based approach. That sort of issue, where clever code is more fragile than the simple implementation, is one reason some programmers shy away from being too clever.
  Re: (Score:2)
  Re: (Score:3, Insightful)
  Ouch... Your function fails miserably if n is negative. Check if n greater than 0, not !0
  Re: (Score:2)
  > int sum(int n) {
  > if(!n) return 0;
  > return sum(n-1) + n;
  > }
  Why do people insist on using recursion in stupid places?!
  Do something like:
  int sum(int n) {
  int result = 0;
  while(n > 0)
  result += n--;
  return result;
  }
  It's way faster since it doesn't have to go crazy with the stack. Also, it isn't harder to understand.
  Somewhat related, one of my peeves is using recursion to calculate factorials. Grrrrr.
  Re: (Score:2, Informative)
  Re: (Score:2)
  Y'all do realize that sum(n)==(n^2+n)/2, right? A solution that contains either recursion or a loop is inherently bad, with or without memoization. This is a O(1) problem. In Perl:
  sub sum() {
  my $n=shift;
  return 0 if $n=0;
  return ($n**2+$n)/2;
  }
  Re: (Score:3, Informative)
  Er.
  /. killed my less-than. That should say:
  sub sum() {
  my $n=shift;
  return 0 if $n<=0;
  return ($n**2+$n)/2;
  }
  Re: (Score:2)
  Once again someone proves that a little maths knowledge can have huge advantages.
  Yay for making me feel stupid though
  :(
  God's code... (Score:5, Funny)
  According to xkcd [xkcd.com]
  Good review (Score:5, Interesting)
  Re:Good review (Score:5, Funny)
  Re: (Score:2)
  Good meta-meta... I... joke.
  Re:Good review (Score:5, Funny)
  Good meta-meta... I... joke.
  Good recursive [ERROR: STACK OVERFLOW]
  Re: (Score:2)
  Re: (Score:2)
  Re:Good review (Score:5, Informative)
  Thanks. It was *not* a Slashvertisement - I try my best to actually make the Book Reviews I do meaningful.
  ;)
  Re: (Score:3, Insightful)
  Not ragging on you in particular, but I've never bought a book reviewed on slashdot. They all seem to be geared towards the novice. Where is the book review for "advanced systems programing in Haskell"? Or "Algorithms for taki
  Run with more threads than processors (Score:5, Insightful)
  Run with more threads than processors
  Funny, I've found more problems by running with fewer threads than processors. Otherwise, you aren't necessarily getting true concurrency. Running ten threads on a single processor isn't going to help you find some of the pesky concurrency issues that arise from true parallel execution. Of course, one should run with more threads than processors to test that as well.
  Either way, writing non-trivial parallel code isn't easy.
  Re: (Score:3, Insightful)
  So you're saying that you generally find more concurrency issues by running less than one thread on a single processor?
  Re: (Score:3, Informative)
  +1 Insightful? More like -1 Poor Reading Comprehension.
  If you have a quad-core machine and you run your app with three threads, then you're almost guaranteed that all of your threads will be running at once. On the other hand, if you're running with five threads, and thread #5 conflicts with thread #3, you may never notice that, because thread #5 could be sleeping the whole time.
  And as the GP said, it's a good idea to test your code with more and less treads than the optimal number.
  Write your code backwards (Score:2)
  It's much easier to write parallel code that way.
  Re: (Score:2)
  The solution is to make sure your parallel code is trivial, so it can be dealt with in a sane matter. When you start firing off threads that handle complex tasks and interact with other complex tasks often, it becomes VERY hard to keep things sane.
  Break complex tasks down into smaller, trivial ones that can be controlled easier and reduce the concurrancy/contention issues to very small easy to manage chunks.
  Bravo! (Score:2, Interesting)
  Re: (Score:2)
  Is this really what passes for informative these days?
  Is the problem one of craft or mentality? (Score:5, Interesting)
  I don't know that this is the right book for the general problem.
  In my career, the engineers who have been the most effective and most pleasant to work with usually do what they can to be better teammates. This includes but is not limited to: writing good code (or improving/refactoring existing code), and managing their personal interactions with teammates toward rational consensus and general embetterment (a perfectly cromulent word).
  In my experience, the guys who consistently write the worst code also tend to have "lone wolf" mentalities. These are the guys who say, "if it was hard to write, it should be hard to read", and not half-jokingly. I honestly get the impression that growing up they might not have had the sorts of personal interactions that lead a person to be mindful of "playing nice with others". Coding serves a much more selfish end. This doesn't mean they are not "productive" in the absolute sense, but they are solo silo stars and it's hard to pair or team them.
  Put another way, the kind of engineer that would actually benefit from a book like this, has probably already read a book like this.
  The needed book I think is for the manager: psychology of the antisocial geek
  Re: (Score:2)
  but they are solo silo stars and it's hard to pair or team them.
  Not that hard [yahoo.com], depending on how you do it [communityarts.net]. You really find out who can work well with a partner if you do it right.
  Re:Is the problem one of craft or mentality? (Score:5, Insightful)
  Put another way, the kind of engineer that would actually benefit from a book like this, has probably already read a book like this.
  I think you've created a false dichotomy.
  I haven't read this book yet (although Bob Martin's other stuff is great), but back at the dawn of time, I was working with a team that was all relatively young. When McConnell's "Code Complete" came out, we all went through it pretty excitedly.
  Although we had the right spirit, and we each could have named some of the things in the book, none of us could have articulated all of them. And there were a lot of subtleties that we had never thought of.
  So I'd agree that jerks won't read this and nice graybeards don't need to, there are plenty of people who are perfectly nice that haven't perfected their craft yet. They can use this book.
  Re: (Score:2)
  For the love of $DEITY, do not listen to ESR. [catb.org]
  That being said, most geeks aren't truly anti-social - they just work differently. Being cut from a different cloth means that you can't always tailor them to your needs - you may have to modify your pattern a tad.
  I've seen where giving an uber-hacker an inexperienced but - and this is key - very bright geek to teach brought them out of their shell a bit. Mostly because he n00b was able
  yay! (Score:5, Funny)
  hot damn. a new and useful [SI] unit. thanks
  Re:yay! (Score:5, Funny)
  Re: (Score:3, Funny)
  Re:yay! (Score:4, Funny)
  Re:yay! (Score:5, Funny)
  wtfs-per-minute [think-box.co.uk]
  Mod parent informative! (Score:2)
  The mentioned diagram is the original source of the whole joke.
  Re:yay! (Score:5, Interesting)
  hot damn. a new and useful [SI] unit. thanks
  All kidding aside, WTF/minute is a deceptive metric.
  I remember poring over about 30 lines of C for about two plus days with a WTF/minute ratio in the hundreds or thousands. And I knew what the code was supposed to do! It wasn't that I didn't understand it, I didn't understand why the guy who wrote it, a brilliant, brilliant hacker, wrote it the way he did.
  Over two days of following the nested ifs, the gotos (no STL, no exception handling, the gotos made perfect sense), the logic, then BAM!
  "Wow, that's fast!"
  It was the most difficult-to-read code I'd ever read - and it was brilliantly brilliantly fast. (It was a network proxy involving PKI-related messages embedded in LDAP, all based on ASN.1 - all speed improvements were important, his were amazing.)
  Most of the time, high WTF/minute is a good indication that the coder should never, ever have been allowed near a keyboard. Live an awful lot of Java.
  But every now and again, high WTF/minute is a sign of absolute genius. Like a lot of really cool Haskell code. Or wicked perl.
  Hmm, perhaps it's not WTF/minute that we need to consider, but its first order derivative. WTF/minute that peaks then declines to zero suggests genius. WTF/minute that remains constant suggests a bad day or a lot of PHB pressure. WTF/minute that increases without bound suggests brain-damage and a potential career in sales.
  Re: (Score:2)
  But every now and again, high WTF/minute is a sign of absolute genius. Like a lot of really cool Haskell code. Or wicked perl.
  I think that depends on why you're coding. If you're writing code in the spirit that people write poetry, that's fab. Or if you're dealing with a performance-critical section that can't work any other way, then sure, that's fine.
  But for most code (and more and more all the time), maintenance cost vastly overwhelms other factors. Real geniuses get the job done in a way that will last over the long haul.
  Re:yay! (Score:5, Insightful)
  And if he had documented his code, explaining the performance advantages, you'd have read it in an hour and reached the same goal, and he wouldn't have dozens of WTFs to his credit.
  Re:yay! (Score:4, Insightful)
  Over two days of following the nested ifs, the gotos (no STL, no exception handling, the gotos made perfect sense), the logic, then BAM!
  "Wow, that's fast!"
  And your understanding could've been faster if the author had bothered to include a comment block before the series of ifs/gotos.
  Example:
  /** The following series of if's/gotos are a hardwired implementation of ...
  * a finite state machine, as documented in the book "Efficient State Machine
  * examples for data processing (ISBN blablablabla, p.15).
  * The machine is as follows:
  *
  * A -> (condition 1) -> B
  * A -> (condition 2) -> C
  *
  *
  * The if at point 1 is node A
  * The if at point 2 is node B... etc
  */
  if(...) {
  goto B;
  }
  True, comments aren't an excuse for bad code, and WTF/min aren't necessarily accurate. But difficult to understand code without proper in-code documentation is a potential disaster. In fact, I'd call your example a mega-WTF for its lack of comments.
  Re:yay! (Score:5, Funny)
  Re: (Score:2)
  SI units always use seconds.
  :-)
  Bob's your uncle? (Score:3, Funny)
  "Bob Martin (Uncle Bob)'s"
  No wonder he's so good at making clean code... Bob actually is this guy's uncle!
  Depends on function (Score:2, Interesting)
  Re: (Score:3, Insightful)
  Re:Depends on function (Score:5, Insightful)
  related code" [sic] are NOT opposites. In fact, I have seen a huge number of situations where I sped something up by cleaning out the code.
  I know what you mean, but the guy has a point. I have also often sped things up by removing "performance improvements" that some dolt had added because he thought he was being clever.
  My view, which I guess you'd agree with, is that it's best to start with clean, simple code. Usually, that's plenty fast. If performance tests prove that you have a problem, and a profiler shows you the source of the problem, only then should you sacrifice clarity for speed. And you should only do just enough to meet your performance goals.
  Re: (Score:3, Insightful)
  It depends on the situation.
  Efficiency isn't always the desirable outcome as most code doesn't need to be exceptionally efficient - a good developer's time is expensive, and often anything that makes it easier to maintain is a good thing.
  It also means developers can spend more time developing extra functionality rather than coding uber efficient code that usually isn't needed - and then rewrite poorly performing code.
  That said, sometimes you really do want to go for the efficiency - a good developer will kn
  Re:Depends on function (Score:5, Insightful)
  Re: (Score:3, Funny)
  Re:Depends on function (Score:4, Interesting)
  This is dead wrong. It's true that sometimes
  purity is sacrificed for performance. But in
  general, good clean code matches a good clean
  design, which emerges when a problem is
  well-understood. Even code that has been
  tweaked to exploit certain compiler anomalies
  can remain clean.
  Re: (Score:3, Insightful)
  Comments are for readabilty, not the code. Always go for efficiency.
  I endorse the saying "when debugging, ignore the comments - they can be very misleading." Hence I want the code itself to be readable more than I want it to be maximally efficient.
  Re:Depends on function (Score:5, Insightful)
  Bzzt, fail, please go buy the book.
  Clean code is efficient and performs well because you can easily see where the issues are and optimise there appropriately.
  Re: (Score:3, Insightful)
  You're joking I hope.
  Clean is NOT the opposite of efficient.
  No. NO. NO!
  There is no excuse for writing unreadable code. The code itself must be readable. Then comments are necessary to supplement the code, to help understanding the tricky parts, explain the reasons that lead to choose this or that method to solve a problem or -the most important- explain the INTENT of the code. How many projects (FLOSS and closed source) have I seen that were a mess because they d
  Re: (Score:2)
  Clean code can be high performing, but most of the time, high performing code is not clean. Look at encryption algorithms. Look at Qt's premoc compiler. The nature of performance in code is inherently low-level. Want to maximize a function in C++ to its fullest extent? Great, take it too far and you end up with parts using inline ASM. Most p
  Re:Depends on function (Score:4, Insightful)
  Clean code is the enemy of robust code? I've never heard anyone state that before.
  Even when I don't need it? You don't make sense.
  Of course... (Score:5, Funny)
  Clean code? (Score:4, Insightful)
  Just write the code like it is YOU that has to debug it at 4am. Nothing to see here, move along, move along.
  Re: (Score:2)
  Re:Clean code? (Score:4, Insightful)
  LIKE it has to be you - not that it will. If I write code like that, then my buddy can debug it at 4am and not have to call me to fix it. And if his code is like that, I can figure out what is wrong easily and not have to spend hours fixing it.
  Re: (Score:2)
  Re: (Score:3, Insightful)
  Just write the code like it is YOU that has to debug it at 4am.
  It's likely it will be me who has to debug it at 4 am. Writing clear code with helpful comments where necessary makes me appreciate my past self, since if the code is more than a few weeks old, I've already forgotten a whole lot. If it's more than a year old, it might as well have been written by someone else. This is, in fact, how I learned the value of clear coding. It wasn't for others, but for myself. The early shit I wrote in perl looks like something that might originally have been scrawled in fe
  Re: (Score:2)
  Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
  The Elements of Programming Style (Score:5, Informative)
  I will seek out Clean Code and take a look at it. But I'd like to take this opportunity to plug a classic favorite of mine.
  The Elements of Programming Style by Kernighan and Plauger is an old book... so old that all its examples are in either Fortran or PL/I. It doesn't matter. They take examples of code, ruthlessly dissect each one, then rewrite each one; and in every case, their rewritten version is hugely improved. Then they present a rule that encapsulates what they did to improve the example. Their writing is clear, insightful, and entertaining. This is a book that I pull out again and again and re-read. [amazon.com]
  steveha
  So Dijkstra is no longer the go-to guy on this? (Score:3, Funny)
  At a coffee shop near you!
  If you think THAT's clean code (Score:5, Funny)
  You should see the SOAP request I wrote last year!
  [rim shot]
  Good night! Don't forget to tip your waiters!
  Clean Code (Score:5, Insightful)
  I recently ran across a situation where I looked a piece of code someone else wrote and thought to myself that
  is really ugly. I set out to write a clean version but gave up when I figured out that no matter what I did
  this was still going to be ugly. Not so much because of a poor job coding it but because of what the code had
  to actually perform.....I guess it is just not possible to always put lipstick on the pig.
  Re: (Score:2)
  I think a better way to look at this is that at the time you couldn't think of a better way. Often I've come back to a problem later and found some better abstraction. Or asked a colleague who has a nice trick to sort things out.
  On some days, I think the the main job of a programmer is to hide the ugliness as well as possible. The code bases that really scare me are the ones where people have admitted defeat and let the ugliness seep everywhere.
  Re: (Score:2)
  Actually there are off the shelf products that could handle the situation easily, cleaner and much more robust. However
  we where told to not spend any time on it since it is getting replaced. We all know how that story goes, that same line has been
  used for the last 6-8 years and there is still no replacement in site....the ugliness lives on...
  Re: (Score:2)
  Last week I rewrote some code that had been annoying me since early 2003. I knew intuitively it could be done better at the time but I didn't have time (or, I think, skills at the time) to dig into it. After 5+ years of the code working okay but bugging me every time I came across it again, having hacks added on top, and constant improvement of the stuff around it (including a lot of deleting) I finally had my a-ha moment.
  32 modified files and thousands of lines of code later, it was done, and my team rej
  Re: (Score:2)
  This may be the case, but what you *can* do is make sure that all of the publicly exposed methods are at least easy to use.
  Thing is, every class written is in a way an API unto itself. So even if it's ugly inside, make sure it's easy to use outside.
  Is it professional to cheat your boss? (Score:3, Informative)
  Here's an interview [blog.jaoo.dk] with Robert Martin (part of a panel) where he talks about cheating the boss (by writing good code without permission to use the time).
  Re:Is it professional to cheat your boss? (Score:5, Interesting)
  I totally agree with Bob Martin here.
  Suppose I go into the doctor and say, "I'm tired and not getting enough done. Please give me a bucket of amphetamines." The doctor will say no, as that would be likely to cause harm, followed by death. Instead, they'll try to figure out what's really going on, and help me appropriately. That's what professionals do.
  If a boss comes to me and tells me that for the new banking software they'd like me to skip testing, exception handling, and error logging, I'll say no. Instead, I'll ask them what their real goal is, and suggest ways they can achieve that.
  Over and over I see developers offering to write unmaintainable garbage, only to get in hot water in a year's time because productivity is in the toilet. It's not even fun the first time, but people keep on doing it. They should stop.
  who wants (Score:4, Funny)
  Re: (Score:2)
  a perfect example of unclean code? [thepiratebay.org]
  Sheets of unclean code as toilet paper. A match made in heaven.
  You had me right up to "Agile." (Score:4, Insightful)
  For some reason, whenever I see that word in reference to programming, I want to run screaming in the opposite direction. Does that make me a bad person?
  Re: (Score:2)
  If it does, there are a lot of us bad people around.
  Re: (Score:3, Insightful)
  Re: (Score:3, Insightful)
  For some reason, whenever I see that word in reference to programming, I want to run screaming in the opposite direction. Does that make me a bad person?
  Re: (Score:2)
  Superflous (Score:2, Informative)
  If you're in the field, you either know this stuff already and use it (won't be purchasing the book), know this stuff and don't use it (won't be purchasing the book), know this stuff and don't care (you wouldn't be pained to go purchase a book about it).
  Bob's really chosen a microscopic target reading audience imo.
  whitespace (Score:4, Funny)
  you can't get cleaner than that [wikipedia.org]!
  The 10 Line Perl Script that Cost Us $1000 per Day (Score:2)
  Some idiot in IT for a startup I worked for wrote some perl script that checks to see if our web page was up, and if it was down, it emails to 6 pages. Our ISP had a problem, and there were some other network issues and everyone just turned off their pagers and the script was constantly sending e-pages to all 6 pages, for a total for $1000/day. I guess the idiot didn't space out the times between checking the web site and paging, as it just constants sent e-pages. WTF!
  Re:The 10 Line Perl Script that Cost Us $1000 per (Score:3, Insightful)
  Sounds to me like the problem was with the idiot who signed a SLA allowing for that much downtime and to the owners of pagers for turning them off without investigating. IT worked as it should have.
  Re: (Score:2)
  Quite Useful I think (Score:2)
  Why so difficult. (Score:2)
  Just follow one coding standard and stick to it, preferably a aerospace and/or military related one (as those are the ones that happen to be the best worked-out I've seen).
  Personally, I prefer 2RDU00001 [jsf.mil], because not only it has the rules, but explains why every single specific rule makes sense, thus making it easier to enforce in a team.
  Re: (Score:2)
  [I'm the reviewer]
  There are several resources out there. For example, here's the code conventions for Java: [sun.com]
  The best thing is to simply find out what your team is doing and document it. Then read the book to see if there are ways to improve what you are already doing.
  If you'd like to contact me, I'd be happy to talk about what I've done with my teams (foyc at cornet design dot com)
  Re: (Score:2)
  Re: (Score:2)
  What one programmer's definition of documented, is another programmer's definition of over-documented. Should the documentation for a function be at the top of the file, above the function definition, or between the function definition and the first opening brace?
  Should comments be alongside the lines of code they are describing, above them at the start of the line, or are they simply index points numbers (eg.
  // 1.1) with the actual definition above the function?