From Wikipedia:
mutations in influenza occur frequently because the virus' RNA polymerase has no proofreading mechanism, providing a strong source of mutations Replication errors are the most common source of mutation. This means accidental insertions, deletions, and alterations. If the flu virus were only losing data we could expect it to be completely bastardized and ineffectual over time, whereas the observation is it continues to become increasingly resistant.
And I'm in no way arguing that it's a bad idea. But it's ubiquitous among many C++ programs, and Windows C++ programs especially because all the tutorials use it (which is ironic because hungarian was designed for a language that didn't contain distinct data types). But what that means is it's still a good idea to learn to read it, so when you see lpszName, you think to yourself, "long pointer to zero-terminated string", not, "my God, what the fuck is that guy on?"
Is this what old earth creationism says? Or is this just scientific ignorance? You can't accept a theory based partly on a wealth of modern-day evidence and then say it doesn't exist anymore.
Evolution is not how life came into being. It's how life came to be what it is, and how it will come to be what it will be in the future.
there has never been in observable science an example of a gain of different DNA information within any species I'm sure the influenza virus begs to differ.
Would it not make sense for said designer to give the designed the ability to adapt, evolve, grow, and change as conditions require it? And, since this ability is all it takes for one form to eventually give rise to a more complex form, would it not make sense for said designer to create a couple viruses in a mineral-rich pond and then sit back, have a cigar and watch what happens?
intelligent design ID is just doublespeak for Genesis-Account-6-Day-Young-Earth-Creationism. Why else would the Flying Spaghetti Monster offend so many creationists?
There's no real such thing as de-evolution. It doesn't have a direction. There's no "more evolved" or "less evolved". We just evolve.
Evolutionary niches are like depressions in rough, jagged terrain -- natural pressures just ensure the puddles tend to collect there. We evolve to become better at reproducing. That means evolution favors Catholics.
Overuse of hungarian makes for unreadable code. There is no need to type your index variables. Just nitpicking. If you're going to use a bad practice, at least use it well.
And that's why not everyone writes good code. Mod parent funny.
Most likely a good compiler would have caught that and fixed it in the assembly. It's not an excuse for bad code, but its significance may not be as critical as you believe.
Sure, but once you've abstracted out enough that you can safely add two integers or look up a slot without everything blowing up, it doesn't look at all like C any more, and the extra layers remove any performance advantage C has, so what's the point? On the contrary, you can easily get polymorphism in C through use of function pointers. You can get encapsulation by defining a library of functions designed to operate on instances of a struct. Inheritance between structs is sloppy, but you can do it by including a struct instance as a first member then tacking more on at the end, then casting back and forth between pointer types. Hardly any performance is lost.
Sure, it's possible to write crap in any language. But can you give an example of an algorithm that can't be expressed clearly in a high-level language? I'd be curious to see it. I'm talking more about the business logic aspect when code gets segmented out into lots of little functions. Great for reducing code duplication, but it can be hard to grasp the big picture when you're looking at individual functions in isolation.
But as for algorithms where the intent is not clear from the code... How about the algorithm for calculating an MD5 sum, for one?
And some languages are better at expressing certain algorithms than others. Ever see a red-black tree sorting algorithm in Java? And then one in Lisp? Two guesses as to which one is easier to read. Ah, but you've already discredited Java.
you end up using object-orientation for a lot of syntactic things as well Not sure how you think this makes code less intuitive.
Java -- that's basically C with a GC ...and its own runtime assembly code, a virtual machine, a threading pool, dynamic linking, implicit pointers, type safety,...
If you can't handle people who don't think like you breaking the third commandment perhaps answersingenesis is a better forum for you to be commenting in.
C has enough goodies like callback pointers and structs that you can make it behave in a more abstract fashion if you want. You can still achieve encapsulation and polymorphism in C, it's just a little trickier.
But forest-for-trees crops up even in languages like Java and Ruby. You simply can't just take a piece of code, no matter how well-written, read it like a book, and instantly know exactly how it works.
I'm not even sure what that value would be if the ball were under water and buoyant. Since weight is the net gravitational force acting on it, same as if it were suspended in air or sitting on a table at the same elevation.
I would actually consider writing a superclass or mixin called MassiveObject that knows how to calculate mass-based forces between it and other MassiveObjects. Separation of concern, you know.
That's not well written code, I'm afraid. Eye of the beholder, my friend. Within its context it could make perfect sense. I myself hate hungarian notation but I let it slide as a matter of taste. Overly verbose variable and method names don't solve everything.
Let me ask you, what's the best option out of the following three?
1.
// Does something complicated // NOTE: foo must be greater than zero private int someComplicatedFunction(double foo) {... }
2.
private int someComplicatedFunctionOnValuesGreaterThanZero(double foo) {... }
This, in fact, is one of my biggest pet peeves. Give that variable a name. Really not the point of my argument, although I'm sure getting reamed for it;) It was just an example off the top of my head and it didn't come from a real piece of code, so those variables really didn't mean anything. Had I used metasyntactic names, perhaps this whole thing could have been avoided?
In any case, when you're doing iteration in Ruby, it's fairly common to use single-letter variable names:
User.find(:all).collect{|u| u.id}
It's quite clear from that context that "u" is a user. It doesn't necessarily help to change that "u" to "user".
In the case above, "i", "j", and "k" are common loop indices. Mathematicians make do with single-letter variables all the time (although some are known to be slightly insane). An abbreviated variable name is OK if its context is well-established.
The reason Agile people lean away from documentation by default is that documentation is by definition redundant. And redundancy is a Bad Thing because? Yes, code duplication is undesirable. Clarification where it is needed is not. Structural engineers would tell you redundancy is a very, very Good Thing.
For an agile team coding like that, I'd expect them to be doing test-driven development, working in a team room, doing pair programming, and swapping pairs every few hours. And scrumming twice a day? Just messing with you. You seem to be describing an XP environment... XP is known to be an unstable methodology, both in theory and practice. Heck, the flagship XP project at Daimler Chrysler floundered until the day it was decommissioned, even with the big XP cheeses at the helm. Change management software where everyone is required to read the commit logs seems to work better at fostering a team code environment than pair programming. There is something to be said for an employee having their own space. In my own experience, the only time pair programming has ever worked is in an EXTREMELY small (read: three people) team. It just doesn't seem to scale. Usually someone sits back and watches the other one code, going, "huh?" until they either give up and do something else or have to switch.
That said, XP has some good ideas (I test-driven development, refactoring) that when combined with the good ideas of the more traditional methodologies (story cards be damned; formal initial design and modeling are important!) create a more flexible development environment.
Every time I get the urge to document something, I first try to make it clearer, so the documentation isn't necessary. When I can't, I document. I would agree with you. Documentation is not a substitute for poorly written code.
To put it more succinctly: Quality comments enhance the readability of quality code. In other words, the art of comment writing is just as important as the art of code writing: there are good comments and there are bad comments. A few well-designed comments can go a long way towards elucidating a block of tricky code.
If you've got good unit test coverage, nobody should be afraid of deleting anything. If the tests fail, you just hit undo. Except when you have a function that's not called anywhere except from its unit test... then if you delete the function the unit test fails! You have to delete the test AND the function and then suddenly you have the same situation of fear of removing two things instead of one.
I'm sure the staunch agile supporter would posit that that is NOT well-written code, since it needs a comment. Of course, I would challenge them to come up with a "well-written" alternative.
You're not executing the code. It's still read left-to-right, top-to-bottom. Hell, that can be even more confusing than reading the code the way a computer would.
But I'm saying that well written code does not need clarification. When it's well written there's nothing more that can be said in any other language that hasn't already been said directly in the code. I disagree. Languages differ in their expressiveness, and sometimes human language can be used to succinctly clarify what may take 200 lines of disjoint, complex code to specify in a computer language.
I think we're saying essentially the same thing. I'm arguing for better commenting and learning what kinds of comments are unnecessary.
I'm griping about comments that triple the size of the source code and disrupt the code's readability, yet say nothing that can't be discerned immediately from the code.
Comments should describe "what" in only very high-level terms, which is why "what" comments are better suited to method and class level. Beyond that, they should primarily talk about "why", and to a lesser extent, "how" (if the how isn't plainly obvious).
I think the "if in doubt, comment" suggestion is actually bad advice. It leaves people thinking, "God, I really should write a comment here, but I just don't know what would make this line any clearer." Crap like "// create an integer and add two to it" comes about as a result.
>> It's said comments are like sex - even when they're bad, they're still pretty good.
I would suggest over-commenting is like having sex while watching a porno -- great at first but after a while it becomes a distraction. When comments are well written, it really becomes a case where less is more.
This is a false analogy. Human language is symmetric in that it is designed to be produced and consumed by a human. Programming languages, on the other hand, are asymmetric in that regard. As such, reading a computer program requires a certain amount of aptitude that's better suited to a computer -- for example, tracking the entire program state at any given time. Granted, you only have to track the state that's relevant to the current context, but recursively switching contexts (see function call, go look up function, finish reading function, go back to function call, keep reading previous function) is something a computer does well and a human doesn't do well.
Also, humans tend to read left-to-right, top-to-bottom. Any worthwhile program is filled with loops, branches, conditionals, calls, recursion, etc. As the program size grows, it becomes very difficult to sit down with the uncommented code and just read it, and actually take away the general gist of what was just read. To do so requires several sessions of hard concentration and focus, and time to reflect on and digest how it all works together. Well-structured, well-written code can only go so far.
Comments, in many cases, make up for that lack of aptitude. It's not restating, it's clarifying what the code does so as to make it less likely for the reader to get lost and help speed up the learning curve.
Over-commented code (the kind where there's 2-3 lines of comments for every one line of code -- not every closing brace needs a reminder that we're exiting a code block, thanks!) is pretty awful too. I've met people of the agile variety who insist that well-written code needs no documentation: that if you carve your code up into small, tight, appropriately named classes and methods it becomes obvious what your code does and your code becomes "self-documenting", and I've met people who won't even look at code unless every single line is commented telling them precisely what it does, so "int i = a + 2;" has to have a comment above it saying "// create a signed 32-bit integer variable, i, and assign it two more than the value of a".
The former is wrong because while it's great that we now know what each little piece of your code does, it's still a challenge to see the forest for the trees in all but the most trivial cases (it also means that after several refactors you end up with a whole lot of miniature orphaned functions littering up your code that are never called and that do nothing but that everyone's afraid of deleting). A good method name doesn't tell the reader why the method is there or what its intended usage is. The latter is wrong as well, because suddenly naturally flowing code is broken up to the point where comments become a distraction and make the code harder to read (incidentally, this is why I started using justified end-of-line comments... it helps with the distraction).
You should always comment your classes (or your data structures if you're using a non-object-oriented language) -- state the reason they exist, what requirement they fulfill, their role in the application, and any caveats to using them. Comment your constants, class and instance variables if it's not bleedingly obvious from the class description what purpose they serve.
Comment your public methods! Your public methods are essentially the exposed API into your code, so if you want your successor reusing code you wrote rather than writing his own that does the exact same thing, it had better be absolutely clear how it is to be used. At a minimum, this should include what the method is there to do, a detailed description of each parameter to the function, and any constraints on the parameters, side effects of invoking the method (Does it write to any files? Set any external variables? Allocate or free any memory?), the range of values that can be returned, a description of any special return values, and any exceptions that can be raised when calling the function. Comment your private methods as well, though with your private methods you may be justified in just explaining why the method is there.
And for the love of God, don't comment your private variable accessors unless they get or set in an unusual manner. And you don't have to comment constructors that just assign parameters to instance variables.
Finally, while those agile guys are right in that your code really should have a natural flow and speak for itself, you should still comment your runtime code. Longer functions should be divided up into "paragraphs" with comments stating what's about to happen and how the current state contributes to the overall goal of the function. If your functions have extremely clean divisions of functionality, consider breaking them up into smaller private functions unless you're concerned with every last ounce of performance and can't afford the 10-20 cpu cycles necessary to do a function call (or declare the methods as inline). If you're doing something in a manner that's unorthodox or not immediately readable or that will make someone reading your code go, "what the hell?", either rewrite it (=D) or comment it to justify why you feel it was necessary to do it that way.
Automated unit tests can also be a good supplement to well-documented code, as they give natural examples of code usage and can serve as tutorials for people trying to learn your code. Often this displays intent a lot better than comments can, since doing is often more effective than saying.
I find people are more concerned with whether code is commented "enough". I think it's better to be concerned not with the amount, but the quality of comments.
And I'm in no way arguing that it's a bad idea. But it's ubiquitous among many C++ programs, and Windows C++ programs especially because all the tutorials use it (which is ironic because hungarian was designed for a language that didn't contain distinct data types). But what that means is it's still a good idea to learn to read it, so when you see lpszName, you think to yourself, "long pointer to zero-terminated string", not, "my God, what the fuck is that guy on?"
Is this what old earth creationism says? Or is this just scientific ignorance? You can't accept a theory based partly on a wealth of modern-day evidence and then say it doesn't exist anymore.
Evolution is not how life came into being. It's how life came to be what it is, and how it will come to be what it will be in the future.
How convenient: a theory about God that doesn't require looking through a telescope. Get back to work!
There's no real such thing as de-evolution. It doesn't have a direction. There's no "more evolved" or "less evolved". We just evolve.
Evolutionary niches are like depressions in rough, jagged terrain -- natural pressures just ensure the puddles tend to collect there. We evolve to become better at reproducing. That means evolution favors Catholics.
Survival of the horniest.
Most likely a good compiler would have caught that and fixed it in the assembly. It's not an excuse for bad code, but its significance may not be as critical as you believe.
But as for algorithms where the intent is not clear from the code... How about the algorithm for calculating an MD5 sum, for one?
And some languages are better at expressing certain algorithms than others. Ever see a red-black tree sorting algorithm in Java? And then one in Lisp? Two guesses as to which one is easier to read. Ah, but you've already discredited Java. you end up using object-orientation for a lot of syntactic things as well Not sure how you think this makes code less intuitive. Java -- that's basically C with a GC ...and its own runtime assembly code, a virtual machine, a threading pool, dynamic linking, implicit pointers, type safety,
If you can't handle people who don't think like you breaking the third commandment perhaps answersingenesis is a better forum for you to be commenting in.
except in your hungarian that would be:
range_t rngI = m_rngI, rngJ = m_rngJ;
Of course, not everyone writes in C++...
It's amazing how liberating it can be when we shed our assumptions that compilers behave exactly the way we were taught in CS 101 ;-)
C has enough goodies like callback pointers and structs that you can make it behave in a more abstract fashion if you want. You can still achieve encapsulation and polymorphism in C, it's just a little trickier.
But forest-for-trees crops up even in languages like Java and Ruby. You simply can't just take a piece of code, no matter how well-written, read it like a book, and instantly know exactly how it works.
I would actually consider writing a superclass or mixin called MassiveObject that knows how to calculate mass-based forces between it and other MassiveObjects. Separation of concern, you know.
Let me ask you, what's the best option out of the following three?
1. 2. 3. Refactor the code
In any case, when you're doing iteration in Ruby, it's fairly common to use single-letter variable names:
User.find(:all).collect{|u| u.id}
It's quite clear from that context that "u" is a user. It doesn't necessarily help to change that "u" to "user".
In the case above, "i", "j", and "k" are common loop indices. Mathematicians make do with single-letter variables all the time (although some are known to be slightly insane). An abbreviated variable name is OK if its context is well-established.
That said, XP has some good ideas (I test-driven development, refactoring) that when combined with the good ideas of the more traditional methodologies (story cards be damned; formal initial design and modeling are important!) create a more flexible development environment. Every time I get the urge to document something, I first try to make it clearer, so the documentation isn't necessary. When I can't, I document. I would agree with you. Documentation is not a substitute for poorly written code.
To put it more succinctly: Quality comments enhance the readability of quality code. In other words, the art of comment writing is just as important as the art of code writing: there are good comments and there are bad comments. A few well-designed comments can go a long way towards elucidating a block of tricky code. If you've got good unit test coverage, nobody should be afraid of deleting anything. If the tests fail, you just hit undo. Except when you have a function that's not called anywhere except from its unit test... then if you delete the function the unit test fails! You have to delete the test AND the function and then suddenly you have the same situation of fear of removing two things instead of one.
I'm sure the staunch agile supporter would posit that that is NOT well-written code, since it needs a comment. Of course, I would challenge them to come up with a "well-written" alternative.
I think we're saying essentially the same thing. I'm arguing for better commenting and learning what kinds of comments are unnecessary.
I'm griping about comments that triple the size of the source code and disrupt the code's readability, yet say nothing that can't be discerned immediately from the code.
Comments should describe "what" in only very high-level terms, which is why "what" comments are better suited to method and class level. Beyond that, they should primarily talk about "why", and to a lesser extent, "how" (if the how isn't plainly obvious).
I think the "if in doubt, comment" suggestion is actually bad advice. It leaves people thinking, "God, I really should write a comment here, but I just don't know what would make this line any clearer." Crap like "// create an integer and add two to it" comes about as a result.
>> It's said comments are like sex - even when they're bad, they're still pretty good.
I would suggest over-commenting is like having sex while watching a porno -- great at first but after a while it becomes a distraction. When comments are well written, it really becomes a case where less is more.
This is a false analogy. Human language is symmetric in that it is designed to be produced and consumed by a human. Programming languages, on the other hand, are asymmetric in that regard. As such, reading a computer program requires a certain amount of aptitude that's better suited to a computer -- for example, tracking the entire program state at any given time. Granted, you only have to track the state that's relevant to the current context, but recursively switching contexts (see function call, go look up function, finish reading function, go back to function call, keep reading previous function) is something a computer does well and a human doesn't do well.
Also, humans tend to read left-to-right, top-to-bottom. Any worthwhile program is filled with loops, branches, conditionals, calls, recursion, etc. As the program size grows, it becomes very difficult to sit down with the uncommented code and just read it, and actually take away the general gist of what was just read. To do so requires several sessions of hard concentration and focus, and time to reflect on and digest how it all works together. Well-structured, well-written code can only go so far.
Comments, in many cases, make up for that lack of aptitude. It's not restating, it's clarifying what the code does so as to make it less likely for the reader to get lost and help speed up the learning curve.
Comments of the every-single-line variety have a tendency to simply restate what the upcoming line does. Not terribly helpful.
So you write in assembly then?
Over-commented code (the kind where there's 2-3 lines of comments for every one line of code -- not every closing brace needs a reminder that we're exiting a code block, thanks!) is pretty awful too. I've met people of the agile variety who insist that well-written code needs no documentation: that if you carve your code up into small, tight, appropriately named classes and methods it becomes obvious what your code does and your code becomes "self-documenting", and I've met people who won't even look at code unless every single line is commented telling them precisely what it does, so "int i = a + 2;" has to have a comment above it saying "// create a signed 32-bit integer variable, i, and assign it two more than the value of a".
The former is wrong because while it's great that we now know what each little piece of your code does, it's still a challenge to see the forest for the trees in all but the most trivial cases (it also means that after several refactors you end up with a whole lot of miniature orphaned functions littering up your code that are never called and that do nothing but that everyone's afraid of deleting). A good method name doesn't tell the reader why the method is there or what its intended usage is. The latter is wrong as well, because suddenly naturally flowing code is broken up to the point where comments become a distraction and make the code harder to read (incidentally, this is why I started using justified end-of-line comments... it helps with the distraction).
You should always comment your classes (or your data structures if you're using a non-object-oriented language) -- state the reason they exist, what requirement they fulfill, their role in the application, and any caveats to using them. Comment your constants, class and instance variables if it's not bleedingly obvious from the class description what purpose they serve.
Comment your public methods! Your public methods are essentially the exposed API into your code, so if you want your successor reusing code you wrote rather than writing his own that does the exact same thing, it had better be absolutely clear how it is to be used. At a minimum, this should include what the method is there to do, a detailed description of each parameter to the function, and any constraints on the parameters, side effects of invoking the method (Does it write to any files? Set any external variables? Allocate or free any memory?), the range of values that can be returned, a description of any special return values, and any exceptions that can be raised when calling the function. Comment your private methods as well, though with your private methods you may be justified in just explaining why the method is there.
And for the love of God, don't comment your private variable accessors unless they get or set in an unusual manner. And you don't have to comment constructors that just assign parameters to instance variables.
Finally, while those agile guys are right in that your code really should have a natural flow and speak for itself, you should still comment your runtime code. Longer functions should be divided up into "paragraphs" with comments stating what's about to happen and how the current state contributes to the overall goal of the function. If your functions have extremely clean divisions of functionality, consider breaking them up into smaller private functions unless you're concerned with every last ounce of performance and can't afford the 10-20 cpu cycles necessary to do a function call (or declare the methods as inline). If you're doing something in a manner that's unorthodox or not immediately readable or that will make someone reading your code go, "what the hell?", either rewrite it (=D) or comment it to justify why you feel it was necessary to do it that way.
Automated unit tests can also be a good supplement to well-documented code, as they give natural examples of code usage and can serve as tutorials for people trying to learn your code. Often this displays intent a lot better than comments can, since doing is often more effective than saying.
I find people are more concerned with whether code is commented "enough". I think it's better to be concerned not with the amount, but the quality of comments.