Reading up on code commenting, there seems to be a general support for comments that do not explain anything the code itself can explain. All the sources (not that many, but a few still) I have looked up say that the comments should be explaining the code on a higher level of abstraction.
However, experts in the field I socialise and work with are supporting that more comments are better than not enough, that even if the comments explain something that the reader/coder can decipher from the code, there are different levels of this, and some people may decipher the code faster than others, so to be safe it would be better to comment code whose meaning is not painfully obvious; after all,
"it will help you, as a coder, when you don't have to read the actual code, and can understand what a function does in English, rather than try and decipher code. Sometimes, it might even help writing the function out in comments and pseudocode before coding it; It will help as a constant reminder of what this function is supposed to do."
These two are quite different schools of thought as far as comments go. Which begs the question:
What are the different schools of thought about code commenting, and what are the most popular (so as to avoid asking about the best ones, as that is subjective) sources I can read up on about code commenting practices?
This is a fairly sharp write-up called The Fine Art of Commenting over at ic#code. It's not perfect (Hungarian notation is horrible and should not be inflicted on developers), but it is still fairly interesting.
The author correctly notes that there are different things you may want to use comments for, and splits them into 3 classes:
Documentary comments, for example copyright information, authorship, and version and changes information.
Functional comments, which are your various "TODO" and "BUG" comments signaling out areas of code that may require further attention.
Explanatory comments, which explain what the code does.
The third category is obviously the interesting one being discussed here. In my opinion, comments should describe why the code does why it does, and not how. For example, if your codes sorts a list, you should explain why the list has to be sorted in the first place - that the list is being sorted is (or should be) obvious from the code.
Finally, the most important thing about comments is that they are not compiled and have no effect on the behavior of the program. This may seem obvious. The consequence of this is that during the maintenance phase of the software, bugs in the code may be fixed, but the comments often remain unchanged, and may document behavior that is no longer observed. As wrong documentation is even less useful than non-existent documentation, it is very important to fix bugs in the comments as well as in the actual code.
Background:
An art teacher once gave me a design problem to draw a tiger using only 3 lines. The idea being that I study a tiger and learn the 3 lines to draw for people to still be able to tell it is a tiger.
The solution for this problem is to start with a full drawing of a tiger and remove elements until you get to the three parts that are most recognizable as a tiger.
I love this problem as it can be applied in multiple disciplines like software development, especially in removing complexity.
At work I deal with maintaining a large software system that has been hacked to death and is to the point of becoming unmaintainable. It is my job to remove the burdensome complexity that was caused by past developers.
Question:
Is there a set process for removing complexity in software systems - a kind of reduction process template to be applied to the problem?
Check out the book Refactoring by Martin Fowler, and his http://www.refactoring.com/ website.
Robert C. Martin's Clean Code is another good resource for reducing code complexity.
Unfortunately, the analogy with the tiger drawing may not work very well. With only three lines, a viewer can imagine the rest. In a software system, all the detail has to actually be there. You generally can't take much away without removing something essential.
Check out the book Anti-Patterns for a well-written book on the whole subject of moving from bad (or maladaptive) design to better. It provides ways to recover from a whole host of problems typically found in software systems. I would then add support to Kristopher's recommendation of Refactoring as an important second step.
Checkout the book, Working Effectively with Legacy Code
The topics covered include
Understanding the mechanics of software change: adding features, fixing bugs, improving design, optimizing performance
Getting legacy code into a test harness
Writing tests that protect you against introducing new problems
Techniques that can be used with any language or platform—with examples in Java, C++, C, and C#
Accurately identifying where code changes need to be made
Coping with legacy systems that aren't object-oriented
Handling applications that don't seem to have any structure
This book also includes a catalog of twenty-four dependency-breaking techniques that help you work with program elements in isolation and make safer changes.
While intellectually stimulating, the concept of detail removal doesn't carry very well (at least as-is) to software programs. The reason being that the drawing is re-evaluated by a human with it ability to accept fuzzy input, whereby the program is re-evaluated by a CPU which is very poor at "filling the blanks". Another more subtle reason is that programs convey a spaciotemporal narrative, whereas the drawing is essentially spacial.
Consequently with software there is much less room for approximation, and for outright removal of particular sections of the code. Never the less, refactoring is the operational keyword and is sometimes applicable even for them most awkward legacy pieces. This discipline is however part art part science and doesn't have very many "quick tricks" that I know of.
Edit: One isn't however completely helpless against legacy code. See for example the excellent book references provided in Alex Baranosky and Kristopher Johnson's answers. These books provide many useful techniques, but on the whole I remain strong in my assertion that refactoring non-trivial legacy code is an iterative process that requires both art and science (and patience and ruthlessness and gentleness ;-) ).
This is a loaded question :-)
First, how do we measure "complexity"? Without any metric decided apriori, it may be hard to justify any "reduction" project.
Second, is the choice entirely yours? If we may take an example, assume that, in some code base, the hammer of "inheritance" is used to solve every other problem. While using inheritance is perfectly right for some cases, it may not be right for all cases. What do you in such cases?
Third, can it be proved that behavior/functionality of the program did not change due to refactoring? (This gets more complex when the code is part of a shipping product.)
Fourth, you can start with start with simpler things like: (a) avoid global variables, (b) avoid macros, (c) use const pointers and const references as much as possible, (d) use const qualified methods wherever it is the logical thing to do. I know these are not refactoring techniques, but I think they might help you proceed towards your goal.
Finally, in my humble opinion, I think any such refactoring project is more of people issue than technology issue. All programmers want to write good code, but the perception of good vs. bad is very subjective and varies across members in the same team. I would suggest to establish a "design convention" for the project (Something like C++ Coding Standards). If you can achieve that, you are mostly done. The remaining part is modify the parts of code which does not follow the design convention. (I know, this is very easy to say, but much difficult to do. Good wishes to you.)
Following my previous question regarding the rationale behind extremely long functions, I would like to present a specific question regarding a piece of code I am studying for my research. It's a function from the Linux Kernel which is quite long (412 lines) and complicated (an MCC index of 133). Basically, it's a long and nested switch statement
Frankly, I can't think of any way to improve this mess. A dispatch table seems both huge and inefficient, and any subroutine call would require an inconceivable number of arguments in order to cover a large-enough segment of code.
Do you think of any way this function can be rewritten in a more readable way, without losing efficiency? If not, does the code seem readable to you?
Needless to say, any answer that will appear in my research will be given full credit - both here and in the submitted paper.
Link to the function in an online source browser
I don't think that function is a mess. I've had to write such a mess before.
That function is the translation into code of a table from a microprocessor manufacturer. It's very low-level stuff, copying the appropriate hardware registers for the particular interrupt or error reason. In this kind of code, you often can't touch registers which have not been filled in by the hardware - that can cause bus errors. This prevents the use of code that is more general (like copying all registers).
I did see what appeared to be some code duplication. However, at this level (operating at interrupt level), speed is more important. I wouldn't use Extract Method on the common code unless I knew that the extracted method would be inlined.
BTW, while you're in there (the kernel), be sure to capture the change history of this code. I have a suspicion that you'll find there have not been very many changes in here, since it's tied to hardware. The nature of the changes over time of this sort of code will be quite different from the nature of the changes experienced by most user-mode code.
This is the sort of thing that will change, for instance, when a new consolidated IO chip is implemented. In that case, the change is likely to be copy and paste and change the new copy, rather than to modify the existing code to accommodate the changed registers.
Utterly horrible, IMHO. The obvious first-order fix is to make each case in the switch a call to a function. And before anyone starts mumbling about efficiency, let me just say one word - "inlining".
Edit: Is this code part of the Linux FPU emulator by any chance? If so this is very old code that was a hack to get linux to work on Intel chips like the 386 which didn't have an FPU. If it is, it's probably not a suitable study for academics, except for historians!
There's a kind of regularity here, I suspect that for a domain expert this actually feels very coherent.
Also having the variations in close proximty allows immediate visual inspection.
I don't see a need to refactor this code.
I'd start by defining constants for the various classes. Coming into this code cold, it's a mystery what the switching is for; if the switching was against named constants, I'd have a starting point.
Update: You can get rid of about 70 lines where the cases return MAJOR_0C_EXCP; simply let them fall through to the end of the routine. Since this is kernel code I'll mention that there might be some performance issues with that, particularly if the case order has already been optimized, but it would at least reduce the amount of code you need to deal with.
I don't know much about kernels or about how re-factoring them might work.
The main thing that comes to my mind is taking that switch statement and breaking each sub step in to a separate function with a name that describes what the section is doing. Basically, more descriptive names.
But, I don't think this optimizes the function any more. It just breaks it in to smaller functions of which might be helpful... I don't know.
That is my 2 cents.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Sometimes its really difficult to decide on when exactly you have written enough comments for someone to understand your intentions.
I think one needs to just focus more on writing readable, easy to understand code than on including a large number of lines of comments explaining every detail of whats happening.
What are your views about this?
Comments aren't there to explain what you're doing. They're there to explain why you're doing it.
The argument is based on a false dilemma: Either your code is a horrible abomination and you write tons of comments to explain every statement and expression, or your code is beautiful poetry that can be understood by your grandmother with no documentation at all.
In reality, you should strive for the latter (well, maybe not your grandmother but other developers), but realize that there are times when a couple of comments will clear up an ambiguity or make the next ten lines of code so much more plain. People who advocate no comments at all are extremists.
Of course, gratuitous comments should be avoided. No amount of comments will help bad code be more understandable. They probably just make it worse. But unless you're only coding trivial systems, there will be times when comments will clarify the design decisions being made.
This can be helpful when catching bugs. Literate code can look perfectly legitimate while being completely wrong. Without the comments, others (or you six months later) have to guess about your intent: Did you mean to do that, or was it an accident? Is this the bug, or is it somewhere else? Maybe I should refer to the design documentation... Comments are inline documentation, visible right where you need it.
Properly deciding when the need for comments actually exists is the key.
Try to make the code self-explaining. One of the most important things is to use meaningful names for classes, functions, variables etc.
Comment the sections that aren't self-explaining. Trivial commenting (e.g. i++; // Add 1 to i) makes the code harder to read.
By the way - the closer to pseudocode you can work, the more self-explaining your code can become. This is a privilege of high-level languages; it's hard to make self-explaining assembly code.
Not all code is self-documenting.
I'm in the process of troubleshooting a performance issue now. The developer thought he discovered the source of the bottleneck; a block of code that was going to sleep for some reason. There were no comments around this code, no context as to why it was there. We removed the block and re-tested. Now, the app is failing under load where it wasn't before.
My guess is someone had previously run into a performance issue and put this code in to mitigate the problem. Whether or not that was the right solution is one thing, but a few comments about why this code is there would now be saving us a world of pain and a whole lot of time...
Why you need comments. The name of the method should be clear enough that you don't need comments.
Ex:
// This method is used to retrieve information about contact
public getContact()
{
}
In this case getContact doesn't need the comments
Aim for code that needs no comments, but don't beat yourself up too much if you miss.
I think commenting enough so that you could understand it if you had to review your code later in life should be sufficient.
I think there would a lot of time wasted if you commented for everyone; and going this route could make your code even harder to understand.
I agree that writing readable code is probably the most important part, but don't leave out comments. Take the extra time.
Readable code should be the number 1 priority. Comments are, as Paul Tomblin already wrote, to focus on the why part.
I try to avoid commenting as much as possible. Code should be self explanatory. Name variables and methods properly. Break large code blocks in methods which have a good name. Write methods that do one thing, the thing you named them for.
If you need to write a comment. Make it short. I often have the feeling that if you need to elaborate long on why this code block does this and that you already have a problem with the design.
Only comment when it adds something.
Something like this is useless and definitely decreases readability:
/// <summary>Handles the "event" event</summary>
/// <param name="sender">Event sender</param>
/// <param name="e">Event arguments</param>
protected void Event_Handler (object sender, EventArgs e)
{
}
Basically, putting aside a good but possibly brief comment at the beginning of a class/method/function declaration, and - if necessary - an introductory comment at the beginning of the file, a comment would be useful when a not-so-common or not-so-clearly-transparent operation is coded.
So, for example, you should avoid commenting what's obvious (i++; on a previous example), but what you know is less obvious and/or more tricky should deserve some clear, unconfusing, brilliant, complete line of comment, which naturally comes along with a Nobel prize for the clearest code in history ;).
And don't underestimate the fact that a comment should be also funny; programmers read much more gladly if you can intellectually tease them.
So, as a general principle tend to not be overwhelming with comments, but when you have to write one, be sure about it to be the clearest comment you could write down.
And personally I'm not a big fan of self-documenting code (a.k.a. code w/o a single damn slashstar): after months you've written it (it's just days for my personal scale) it's very likely you couldn't tell the true reason for choosing such design to represent that piece of your intelligence, so how could others?
Comments are not just that green stuff among code lines; they are the part of code which your brain is better willing to compile. Qualifying as braincode (laughing) I couldn't affirm comments are not part of the program you're writing. They're just the part of it which is not directed to the CPU.
Normally, I'm a fan of documentation comments that clearly spell out the intent of the code you're writing. Spiffy tools like NDoc and Sandcastle provide a nice, consistent way in which to write that documentation.
However, I've noticed a few things over the years.
Most documentation comments don't really tell me anything I can't really glean from the code. That assumes, of course, that I can make heads or tails out of the source code to begin with.
Comments are supposed to be used to document intent, not behavior. Unfortunately, in the vast majority of cases, this isn't how they're used. Tools like NDoc and Sandcastle only propagate the incorrect use of comments by providing a plethora of tags that encourage you to provide comments that tell the reader things that he should be able to discern from the code itself.
Over time, the comments tend to fall out of synch with the code. This tends to be true regardless of whether or not we're using documentation software, which purports to make documentation easier because it puts the documentation closer to the code it describes. Even though the documentation is right there next to the method, property, event, class, or other type, developers still have a hard time remembering to update it if and when the intrinsic behavior changes. Consequently, the documentation loses its value.
It's worth noting that these problems are, by and large, due to the misuse of comments. If comments are used solely as a means of conveying intent, these issues go the way of the dodo, since the intent of any given type or its members is unlikely to change over time. (If it does, a better plan is to write a new member and deprecate the old one with a reference to the new one.)
Comments can have immense value if they are used properly. But that means knowing what they are best used for, and constraining their use to that scope. If you fail to do that, what you end up with is a plethora of comments that are incorrect, misleading, and a source of busywork (at increased cost) since you now have to either remove them or somehow get them corrected.
It's worth it to have a strategy for using comments in a meaningful way that prevents them from becoming a time, energy, and money sink.
Studies have stated that optimal readability happens when you have about 1 line of comments for 10 lines of code. Of course, that's not to say that you need to keep your ration at 1/10 and panic if you go over. But it's a good way to give you an idea of how much you should be commenting.
Also remember that comments are a code smell. That is to say that they may be indicative of bad code but aren't necessarily so. The reason for this is that code that is more difficult to understand is commented more.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I am a hobbyist programmer (started with VBA to make excel quicker) and have been working with VB.NET / C#.NET and am trying to learn ADO.NET.
A facet of programming that has always frustrated me is what does 'good' look like? I am not a professional so have little to compare against. What makes a better programmer?
Is it:
They have a better understanding of
all the objects / classes / methods
in a given language?
Their programs are more efficient?
The design of their programs are much
better in terms of better
documentation, good choice of names
for functions etc.?
Put another way, if I were to look at the code of a professional programmer, what is the first thing that I would notice about their code relative to mine? For example, I read books like 'Professional ASP.NET' by Wrox press. Are the code examples in that book 'world class'? Is that the pinnacle? Would any top-gun programmer look at that code and think it was good code?
The list below is not comprehensive, but these are the things that I thought of in considering your question.
Good code is well-organized. Data and operations in classes fit together. There aren't extraneous dependencies between classes. It does not look like "spaghetti."
Good code comments explain why things are done not what is done. The code itself explains what is done. The need for comments should be minimal.
Good code uses meaningful naming conventions for all but the most transient of objects. the name of something is informative about when and how to use the object.
Good code is well-tested. Tests serve as an executable specification of the code and examples of its use.
Good code is not "clever". It does things in straightforward, obvious ways.
Good code is developed in small, easy to read units of computation. These units are reused throughout the code.
I haven't read it yet, but the book I'm planning to read on this topic is Clean Code by Robert C. Martin.
The first thing you'd notice is that their code follows a consistent coding-style. They always write their structure blocks the same, indent religiously and comment where appropriate.
The second things you'd notice is that their code is segmented into small methods / functions spanning no more than a couple dozen lines at the most. They also use self describing method names and generally their code is very readable.
The third thing you'd notice, after you messed around with the code a little is that the logic is easy to follow, easy to modify - and therefore easily maintainable.
After that, you'll need some knowledge and experience in software design techniques to understand the specific choices they took constructing their code architecture.
Regarding books, I haven't seen many books where the code could be considered "world-class". In books they try mostly to present simple examples, which might be relevant to solving very simple problems but aren't reflective of more complex situations.
Quoting Fowler, summizing readability:
Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.
'nough said.
Personally, I'll have to quote "The Zen of Python" by Tim Peters. It tells Python programmers what their code should look like, but I find that it applies to basically all code.
Beautiful is better than ugly. Explicit is better than
implicit. Simple is better than complex. Complex is better
than complicated. Flat is better than nested. Sparse is
better than dense. Readability counts. Special cases
aren't special enough to break the rules. Although practicality
beats purity. Errors should never pass silently. Unless
explicitly silenced. In the face of ambiguity, refuse the
temptation to guess. There should be one-- and preferably only
one --obvious way to do it. Although that way may not be obvious
at first unless you're Dutch. Now is better than never.
Although never is often better than right now. If the
implementation is hard to explain, it's a bad idea. If the
implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Code is poetry.
Start from this point of logic and you can derive many of the desirable qualities of code. Most importantly, observe that code is read far more than it is written, hence write code for the reader. Rewrite, rename, edit, and refactor for the reader.
A follow on corollary:
The reader will be you at time n from the code creation date. The payoff of writing code for the reader is a monotonically increasing function of n. A reader looking at your code for the first time is indicated by n == infinity.
In other words, the larger the gap of time from when you wrote the code to when you revisit the code, the more you will appreciate your efforts to write for the reader. Also, anyone you hand your code off to will gain great benefit from code written with the reader as the foremost consideration.
A second corollary:
Code written without consideration for the reader can be unnecessarily difficult to understand or use. When the consideration for the reader drops below a certain threshold, the reader derives less value from the code than the value gained by rewriting the code. When this occurs the previous code is thrown away and, tragically, much work is repeated during the rewrite.
A third corollary:
Corollary two has been known to repeat itself multiple times in a vicious cycle of poorly documented code followed by forced rewrites.
I've been programming for 28 years and I find this a tough question to answer. To me good code is a complete package. The code is cleanly written, with meaningful variable and method names. It has well placed comments that comment the intent of the code and doesn't just regurgitate the code you can already read. The code does what it is supposed to in an efficient manner, without wasting resources. It also has to be written with an eye towards maintainability.
The bottom line though is that it means different things to different people. What I might label as good code someone else might hate. Good code will have some common traits which I think I've identified above.
The best thing you can do is expose yourself to code. Look at other people's code. Open Source projects are a good source for that. You will find good code and bad code. The more you look at it, the better you will recognize what you determine to be good code and bad code.
Ultimately you will be your own judge. When you find styles and techniques you like adopt them, over time you will come up with your own style and that will change over time. There is no person on here that can wave a wand and say what is good and that anything else is bad.
Read the book Code Complete. This explains a lot of ideas about how to structure code and the the reasons for doing so. Reading it should short-circuit your time to aquiring the experience necessary to tell good from bad.
http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1229267173&sr=8-1
Having been programming for nearly 10 years now myself and having worked with others I can say without bias that there is no difference between a good programmer and an average programmers code
All programmers at a competent level:
Comment Correctly
Structure Efficiently
Document Cleanly
I once overheard a co-worker say "I've always been very logical and rational minded. I think that's why I enjoy developing"
That in my opinion, is the mind of an average programmer. One who sees the world in terms of rules and logic and ultimately obeys those rules when designing and writing a program.
The expert programmer, understands the rules, but also their context. This ultimately leads to them coming up with new ideas and implementations, the mark of an expert programmer. Programming is ultimately an art form.
Succinctly put, a good programmer's code can be read and understood.
In my opinion, a good programmer's code is language-agnostic; well-written code can be read and understood in a short amount of time with minimal thinking, regardless of the programming language used. Whether the code is in Java, Python, C++ or Haskell, well-written code is understandable by people who don't even program in that particular language.
Some characteristics of code that is easy to read are, methods that are well-named, absence of "tricks" and convoluted "optimization", classes are well-designed, to name a few. As others have mentioned, coding style is consistent, succinct and straight-forward.
For example, the other day, I was taking a look at the code for TinyMCE to answer one of the questions on Stack Overflow. It is written in JavaScript, a language that I've hardly used. Yet, because of the coding style and the comments that are included, along with the structuring of the code itself, it was fairly understandable, and I was able to navigate through the code in a few minutes.
One book that was quite an eye-opener for me in the regard of reading good programmer's code is Beautiful Code. It has many articles written by authors of various programming projects in various programming languages. Yet, when I read it, I could understand what the author was writing in his code despite the fact that I've never even programmed in that particular language.
Perhaps what we should keep in mind is that programming is also about communication, not only to the computer but to people, so good programmer's code is almost like a well-written book, which can communicate to the reader about the ideas it wants to convey.
Easy to read
easy to write
easy to maintain
everything else is filigree
Good code should be easily understood.
It should be well commented.
Difficult parts should be even better commented.
Good code is readable. You'd have no trouble understanding what the code is doing on the first read through of code written by a good professional programmer.
Rather then repeat everyone else's great suggestions, I will instead suggest that you read the book Code Complete by Steve McConnell
Essentially it is a book packed full of programming best practices for both functionality and style.
[Purely subjective answer]
For me, good code is a form of art, just like a painting. I might go further and say that it's actually a drawing that includes characters, colors, "form" or "structure" of code, and with all this being so readable/performant. The combination of readability, structure (i.e. columns, indentation, even variable names of the same length!), color (class names, variable names, comments, etc.) all make what I like to see as a "beautiful" picture that can make me either very proud or very detestful of my own code.
(As said before, very subjective answer. Sorry for my English.)
I second the recommendation of Bob Martin's "Clean Code".
"Beautiful Code" was highly acclaimed a couple of years ago.
Any of McConnell's books are worth reading.
Perhaps "The Pragmatic Programmer" would be helpful, too.
%
Just wanted to add my 2 cents... comments in your code -- and your code itself, generally -- should say what your code does, now how it does it. Once you have the concept of 'client' code, which is code that calls other code (simplest example is code that calls a method), you should always be most worried about making your code comprehensible from the "client's" perspective. As your code grows, you'll see that this is... uh, good.
A lot of the other stuff about good code is about the mental leaps that you'll make (definitely, if you pay attention)... 99% of them have to do with doing a bit more work now to spare you a ton of work later, and reusability. And also with doing things right: I almost always want to run the other way rather than using regular expressions, but every time I get into them, I see why everybody uses them in every single language I work in (they're abstruse, but work and probably couldn't be better).
Regarding whether to look at books, I would say definitely not in my experience. Look at APIs and frameworks and code conventions and other people's code and use your own instincts, and try to understand why stuff is the way it is and what the implications of things are. The thing that code in books almost never does is plan for the unplanned, which is what error checking is all about. This only pays off when somebody sends you an email and says, "I got error 321" instead of "hey, the app is broke, yo."
Good code is written with the future in mind, both from the programmer's perspective and the user's perspective.
This is answered pretty well in Fowler's book, "Refactoring", It's the absence of all the "smells" he describes throughout the book.
I haven't seen 'Professional ASP.NET', but I'd be surprised if it's better than OK. See this question for some books with really good code. (It varies, of course, but the accepted answer there is hard to beat.)
This seems to be (should be) a FAQ. There is an ACM article about beautiful code recently. There seems to be a lot of emphasis on easy to read/understand. I'd qualifier this with "easy to read/understand by domain experts". Really good programmers tend to use the best algorithms (instead of naive easy to understand O(n^2) algorithms) for any given problems, which could be hard to follow, if you're not familiar with the algorithm, even if the good programmer gives a reference to the algorithm.
Nobody is perfect including good programmers but their code tend to strive for:
Correctness and efficiency with proven algorithms (instead of naive and adhoc hacks)
Clarity (comment for intent with reference to non-trivial algorithms)
Completeness to cover the basics (coding convention, versioning, documentation, unit tests etc.)
Succinctness (DRY)
Robustness (resilient to arbitrary input and disruption of change requests)
i second the recommendation for uncle bob's "clean code". but you may wish to take a look at http://www.amazon.com/Implementation-Patterns-Addison-Wesley-Signature-Kent/dp/0321413091 as i think this deals with your specific question a bit better. good code should leap off the page and tell you what it does/how it works.
Jeff Atwood wrote a nice article about how coders are Typists first reference:
http://www.codinghorror.com/blog/archives/001188.html
When being a typist you always need to be elegant in your work, having strucutre and proper "grammar" is highly important. Now converting this to "programming"-typing would catch the same outcome.
Structure
Comments
Regions
I'm a software engineere which means during my education i've come across many different languages but my programming always "feel" the same, as my writing does on fekberg.wordpress.com, i have a "special" way for typing.
Now programming different applications and in different languages, such as Java, C#, Assembler, C++,C i've come to the "standard" of writing that i like.
I see everything as "boxes" or regions and each region has it's explaining commenting. A region might be "class Person" and inside this Region i have a couple of methods for properties, which i may call "Access Methods" or such and each property and region has it's own explaining commenting.
This is highly important, i always see my code that i do, as "being a part of an api", when creating an API structure and elegance is VERY important.
Think about this. Also read my paper on Communication issues when adapting outsourcing which explains in rough, how bad code can conflict, Enterpret as you like: http://fekberg.wordpress.com/2008/12/14/communication-issues-when-adapting-outsourcing/
Good code is easy to understand, easy to maintain, and easy to add to. Ideally, it is also as efficient as possible without sacrificing other indicators.
Great code to me is something that is simple to grasp yet sophisticated. The things that make you go, "wow, of course, why didn't I think of it that way?". Really good code is not hard to understand, it simply solves the problem at hand in a straight-forward way (or a recursive way, if that is even simpler).
Good code is where you know what the method does from the name. Bad code is where you have to work out what the code does, to make sense of the name.
Good code is where if you read it, you can understand what it's doing in not much more time than it takes to read it. Bad code is where you end up looking at it for ages trying to work out wtf it does.
Good code has things named in such a way as to make trivial comments unnecessary.
Good code tends to be short.
Good code can be reused to do what it does anywhere else, since it doesn't rely on stuff that is really unrelated to its purpose.
Good code is usually a set of simple tools to do simple jobs (put together in well organised ways to do more sophisticated jobs). Bad code tends to be huge multi-purpose tools that are easy to break and difficult to use.
Code is a reflection of a programmer's skills and mindset. Good programmers always have an eye on the future - how the code will function when requirements or circumstances are not exactly what they are today. How scalabale it will be? How convenient it will be when I am not the one maintaining this code? How reusable the code will be, so that someone else doing similar stuff can reuse the code and not write it again. What when someone else is trying to understand the code that I have written.
When a programmer has that mindset, all the other stuff falls in place nicely.
Note: A code base is worked on by many programmers over time and typically there is not a specific designation of code base to a programmer. Hence good code is a reflection of all the company's standards and quality of their workforce.
(I use "he" below because this is the person that I aspire to be, sometimes with success).
I believe that the core of a good programmer's philosophy is that he is always thinking "I am coding for myself in the future when I will have forgotten all about this task, why I was working on it, what were the risks and even how this code was supposed to work."
As such, his code has to:
Work (it doesn't matter how fast code gets to the wrong answer. There's no partial credit in the real world).
Explain how he knows that this code works. This is a combination of documentation (javadoc is my tool of choice), exception handling and test code. In a very real sense, I believe that, line for line, test code is more valuable than functional code if for no other reason than it explains "this code works, this is how it should be used, and this is why I should get paid."
Be maintained. Dead code is a nightmare. Legacy code maintenance is a chore but it has to be done (and remember, it's "legacy" the moment that it leaves your desk).
On the other hand, I believe that the good programmer should never do these things:
Obsess over formatting. There are plenty of IDEs, editors and pretty-printers that can format code to exactly the standard or personal preference that you feel is appropriate. I use Netbeans, I set up the format options once and hit alt-shift-F every now and then. Decide how you want the code to look, set up your environment and let the tool do the grunt work.
Obsess over naming conventions at the expense of human communication. If a naming convention is leading you down the road of naming your classes "IElephantProviderSupportAbstractManagerSupport" rather than "Zookeeper", change the standard before you make it harder for the next person.
Forget that he works as a team with actual human beings.
Forget that the primary source of coding errors is sitting at his keyboard right now. If there's a mistake or an error, he should look to himself first.
Forget that what goes around comes around. Any work that he does now to make his code more accessible to future readers will almost certainly benefit him directly (because who's going to be the first person asked to look at his code? He is).
It works
It has unit tests that prove that it works
The rest is icing...
The best code has a certain elegance that you recognise as soon as you see it.
It looks crafted, with care and attention to detail. It's obviously produced with someone with skill and has an art about it - you could say it looks sculpted and polished, rather than rough and ready.
It's consistent and reads easily.
It's split into small, highly cohesive functions each of which do one thing and do it well.
It's minimally coupled, meaning that dependencies are few and strictly controlled,
usually by...
Functions and classes have dependencies on abstractions rather than implementations.
Ironically the better the programmer the less indispensable he/she becomes because the code produced is better maintainable by anyone (as stated by general consent by Eran Galperin).
My experience tells the opposite is also true. The worse the programmer the more difficult to maintain his/her code is, so more indispensable he/she becomes, since no other soul can understand the riddles produced.
I have a good example :
Read GWT (google web tookit) Source code, you will see that every fool understand it (some english books are harder to read than this code).