tags:

views:

660

answers:

20

Can any one suggest what is the best way to write good code that is understandable without a single line of comments?

+1  A: 

Use descriptive variable names and descriptive method names. Use whitespace.

Make your code read like normal conversation.

Contrast the use of Matchers in Junit:

assertThat(x, is(3));
assertThat(x, is(not(4)));
assertThat(responseString, either(containsString("color")).or(containsString("colour")));
assertThat(myList, hasItem("3"));

with the traditional style of assertEquals:

assertEquals(3, x);

When I look at the assertEquals statement, it is not clear which parameter is "expected" and which is "actual".

When I look at assertThat(x, is(3)) I can read that in English as "Assert that x is 3" which is very clear to me.

Another key to writing self-documenting code is to wrap any bit of logic that is not clear in a method call with a clear name.

if( (x < 3 || x > 17) && (y < 8 || y > 15) )

becomes

if( xAndYAreValid( x, y ) )  // or similar...
Alex B
I was with you up until xAndYAreValidForOperationJ22. It doesn't make sense to give your methods such long and verbose names just to reference some operation ambiguously named "J22." Something like areValidCoordinates(x,y) or areWithinBounds(x,y) makes much more sense.
Calvin
Also, the last two pieces of code seem like counterexamples for self-documenting code. You're unnecessarily obfuscating a very simple if() expression when a simple comment could both, show the comparisons being performed and state the author's intent. Instead, you're making the reader look up another function to see what is going on.
Calvin
Fair point. I was attempting to imply that there was some business logic with a name of "J22" that would be clear to other readers in the fictitious domain.
Alex B
+14  A: 

Read Code Complete, 2nd Edition cover to cover. Perhaps twice.

To give some specifics:

  • Making code readable
  • Eliminating code repetition
  • Doing design/architecture before you write code
Daniel Straight
good advice. But maybe provide some of the key concepts that the book will discuss in relation to @pang's question?
andy
+4  A: 

If you really want to then you would need to be very detailed in your variable names and methods names.

But in my opinion, there is no good way to do this. Comments serve a serious purpose in coding, even if you are the only one coding you still sometimes need to be reminded what part of the code you're looking at.

TStamper
I agree - comments are an important part of coding.
Paul Nathan
+10  A: 

I once had a professor when I was in college tell me that any good code should never need any comments.

Her approach was a combination of very precise logic split out into small functions with very descriptive method/property/variable names. The majority of what she presented was, in fact, extremely readable with no comments. I try to do the same with everything I write...

Justin Niessner
And that he why is was a professor
ojblass
I wish more of my professors were like that. Most of mine were comment crazy. I remember one requiring a large formatted comment section at the beginning of each source file, a minimum of a four line formatted comment section before each function and every line in the function had to have an inline comment as well. My fingers ached after each assignment.
codeelegance
@Kenneth And that's where we get stuff like i++; // Add 1 to i and store the result in i.
Adam Jaskiewicz
A: 

If you want to code entirely without comments and still have your code be followable, then you'll have to write a larger number of shorter methods. Methods will have to have descriptive names. Variables will also have to have descriptive names. One common method of doing this is to give variables the name of nouns and to give methods the names of verbal phrases. For example:

account.updateBalance();
child.givePacifier();
int count = question.getAnswerCount();

Use enums liberally. With an enum, you can replace most booleans and integral constants. For example:

public void dumpStackPretty(boolean allThreads) {
    ....
}

public void someMethod() {
    dumpStackPretty(true);
}

vs

public enum WhichThreads { All, NonDaemon, None; }
public void dumpStackPretty(WhichThreads whichThreads) {
    ....
}

public void someMethod() {
    dumpStackPretty(WhichThreads.All);
}
Eddie
+3  A: 

I think that the concept of Fluent Interfaces is really a good example of this.

var bob = DB.GetCustomers().FromCountry("USA").WithName("Bob")

bendewey
This adds a lot of coupling to your projet. If Customers from GetCustomers changes FromCountry(), then this code, located in a 3rd place will also fail. Minimizing impact of changes is crucial
Eric
@Eric, I can see your argument, but many frameworks are using this technique and the question is related to readability not coupling so I still think its a good example.
bendewey
A: 

Descriptive names is your obvious first bet.

Secondly make sure each method does one thing and only one thing. If you have a public method that needs to do many things, split it up into several private methods and call those from the public method, in a way that makes the logic obvious.

Some time ago I had to create a method that calculated the correlation of two time series.

To calculate the correlation you also need the mean and standard deviation. So I had two private methods (well actually in this case they were public as they could be used for other purposes (but assuming they couldn't then they would be private)) for calculating A) the mean, B) the standard deviation.

This sort of splitting up of function into the smallest part that makes sense is probably the most important thing to make a code readable.

How do you decide where to break up methods. My way is, if the name is obvious e.g. getAddressFromPage it is the right size. If you have several contenders you are probably trying to do too much, if you can't think of a name that makes sense you method may not "do" enough - although the latter is much less likely.

Ankur
+2  A: 

Clean Code by Robert C. Martin contains everything you need to write clean, understandable code.

Francois Perron
A: 

I don't really think comments are a good idea in most cases. Comments don't get checked by the compiler so they so often are misleading or wrong as the code changes over time. Instead, I prefer self documenting, concise methods that don't need comments. It can be done, and I have been doing it this way for years.

Writing code without comments takes practice and discipline, but I find that the discipline pays off as the code evolves.

Brian Genisio
+1  A: 

I'm not sure writing code that is so expressive that you don't need comments is necessarily a great goal. Seems to me like another form of overoptimization. If I were on your team, I'd be pleased to see clear, concise code with just enough comments.

le dorfier
A: 

It may not be comments, but, to help someone better understand what it going on you may need some diagrams explaining how the program should work, as, if a person knows the big picture then it is easier to understand code.

But, if you are doing something complex then you may need some comments, for example, in a very math intensive program.

The other place I find comments useful and important, is to ensure that someone doesn't replace code with something that looks like it should work, but won't. In that case I leave the bad code in, and comment it out, with an explanation as to why it shouldn't be used.

So, it is possible to write code without comments, but only if you are limited in what types of applications you are writing, unless you can explain why a decision was made, somewhere, and not call it a comment.

For example, a random generator can be written many ways. If you pick a particular implementation it may be necessary to explain why you picked that particular generator, as the period may be sufficiently long for current requirements, but later the requirements may change and your generator may not be sufficient.

James Black
+1  A: 

I like to 'humanise' code, so instead of:

if (starColour.red > 200 && starColour.blue > 200 && starColour.green > 200){
   doSomething();
}

I'll do this:

bool starIsBright;
starIsBright = (starColour.red > 200 && starColour.blue > 200 && starColour.green > 200);

if(starIsBright){
   doSomething();
}
ChristianLinnell
+1  A: 

In most cases, yes, you can write code that is clear enough that comments become unnecessary noise.

The biggest problem with comments is there is no way to check their accuracy. I tend to agree with Uncle Bob Martin in chapter 4 of his book, Clean Code:

The proper use of comments is to compensate for our failure to express ourself in code. Note that I used the word failure. I meant it. Comments are always failures. We must have them because we cannot always figure out how to express ourselves without them, but their use is not a cause for celebration.

So when you find yourself in a position where you need to write a comment, think it through and see whether there isn’t some way to turn the tables and express yourself in code. Every time you express yourself in code, you should pat yourself on the back. Every time you write a comment, you should grimace and feel the failure of your ability of expression.

Most comments are either needless redundancy, outright fallacy or a crutch used to explain poorly written code. I say most because there are certain scenarios where the lack of expressiveness lies with the language rather than the programmer.

For instance the copyright and license information typically found at the beginning of a source file. As far as I'm aware no known construct exists for this in any of the popular languages. Since a simple one or two line comment suffices, its unlikely that such a construct will be added.

The original need for most comments has been replaced over time by better technology or practices. Using a change journal or commenting out code has been supplanted with source control systems. Explanatory comments in long functions can be mitigated by simply writing shorter functions. etc.

codeelegance
Clean code cannot express reasons as well as comments can. Think of algorithmic selection and business rules like you think of copyrights. Frequently an overall description is useful. That being said, if a comment can disagree directly with the code, get rid of it.
David Thornley
+4  A: 

In some cases - yes, but in many cases no. The Yes part is already answered by others - keep it simple, write it nicely, give it readable names, etc. The No part goes to when the problem you solve in code is not a code problem at all but rather domain specific problem or business logic problem. I've got no problem reading lousy code even if it doesn't have comments. It's annoying, but doable. But it's practically impossible to read some code without understanding why is it like this and what is it trying to solve. So things like :

if (starColour.red > 200 && starColour.blue > 200 && starColour.green > 200){
   doSomething();
}

look nice, but could be quite meaningless in the context of what the program is actually doing. I'd rather have it like this:

// we do this according to the requirement #xxxx blah-blah..
if (starColour.red > 200 && starColour.blue > 200 && starColour.green > 200){
   doSomething();
}
Dima
I agree: comments should describe what is done and why. If you need to describe how it's done, then you need to refactor your code.
Joachim Sauer
Miquel
Comments dont accept code, see my answer below
Miquel
http://stackoverflow.com/questions/784250/is-it-possible-to-write-good-and-understandable-code-without-any-comments/803839#803839
Miquel
+3  A: 

Well written code might eliminate the need for comments to explain what you're doing, but you'll still want comments to explain the why.

Mark Ransom
A: 

I believe it's possible, if you consider the fact that not everybody likes the same style. So in order to minimize comments, knowing your "readers" is the most important thing.

In "information systems" kind-of software, try using declarative sentence, try to approximate the code line to a line in english, and avoid "mathematical programming" (with the i,j and k for index, and the one-liners-to-do-a-lot) at all costs.

Demian Garcia
+2  A: 

Yes, you can write code that doesn't need comments to describe what it does, but that may not be enough.

Just because a function is very clear in explaining what it does, does not, by itself, tell you why it is doing what it does.

As in everything, moderation is a good idea. Write code that is explanatory, and write comments that explain why it is there or what assumptions are being made.

Jeff Cuscutis
+1  A: 

You usually can turn your comment into a function name something like:

if (starColourIsGreaterThanThreshold(){
    doSomething(); 
}

....

private boolean starColourIsGreaterThanThreshold() { 
    return starColour.red > THRESHOLD && 
           starColour.blue > THRESHOLD && 
           starColour.green > THRESHOLD
}
Miquel
+1  A: 

I think comments should express the why, perhaps the what, but as much as possible the code should define the how (the behavior).

Someone should be able to read the code and understand what it does (the how) from the code. What may not be obvious is why you would want such behavior and what this behavior contributes to the overall requirements.

The need to comment should give you pause, though. Maybe how you are doing it is too complicated and the need to write a comment shows that.

There is a third alternative to documenting code - logging. A method that is well peppered with logging statements can do a lot to explain the why, can touch on the what and may give you a more useful artifact than well named methods and variables regarding the behavior.

Yishai