Comments are More Important than Code
CowboyRobot writes "I was going through some code from 2002, frustrated at the lack of comments, cursing the moron who put this spaghetti together, only to realize later that I was the moron who had written it.
An essay titled Comments Are More Important Than Code goes through the arguments that seem obvious only in hindsight - that 'self-documenting' code is good but not enough, that we should be able to write code based on good documentation, not the other way around, and that the thing that separates human-written code from computer-generated code is that our stuff is readable to future programmers.
But I go through this argument with my colleagues, who say that using short, descriptive variable names 'should' be enough as long as the code is well-organized.
Who's right?"
____
~ |rip/\/\aster /\/\onkey
How about Perl's POD Documentation? I do a lot of hacking of Matt Simerson's Mail::Toaster and Nictool projects, and I find that the Perl POD Documentation system, combined with well-named variables is easy on the eyes, and leads to it being well interpreted by an outsider.
May this post be indexed by spiders, and archived for all to see as my Internet epitaph.
This works for code I write that nobody else will ever maintain. Even then I can get tripped up, I'll have to lean back in my chair and try to remember what I was thinking when I wrote the code.
But if you write code you're getting paid for, or code for an organization, anything but personal stuff, write good comments. Variable names might give a good idea about what data the variable holds, but it does not tell us much about how it is used.
When I took my first programming class, the most frustrating part was the documentation. I thought it was retarded and stupid and a waste of time. But now I realize it is very important once you write something more significant than "Hello World".
Rosco: "If brains were gunpowder, Enos couldn't blow his nose."
In my opinion, comments are useful -- but literate programming is where it's at if you're looking for the best way to document your code.
Knuth did a lot of work in the area -- if I remember correctly, all of the sources to TeX are written in a style understood by the "web" literate programming tool.
There was also a good article by one of the Perl folks (Nathan Torkington? M.J. Dominus? Chromatic? I can't remember.) on POD, and how although POD wasn't literate programming, it was still useful. That article was great in that it showed a middle ground that may be more palatable to your non-LP-fanatic programmer.
That being said, I prefer full-on LP for large projects.
unixkb.com -- articles on practical Unix issues.
Well then, just employ a code comment moderation system.
Take off every sig. For great justice.
"Don't get suckered in by the comments -- they can be terribly misleading. Debug only code."
--Dave Storer
I want a new world. I think this one is broken.
"There's a subtle reason that programmers always want to throw away the code and start over. The reason is that they think the old code is a mess. And here is the interesting observation: they are probably wrong. The reason that they think the old code is a mess is because of a cardinal, fundamental law of programming:
0 69.html
It's harder to read code than to write it."
From Joel on Software
http://www.joelonsoftware.com/articles/fog0000000
Always comment.
I hope that after I die the one word people use to describe me is "resurrected."
You are absolutely right. Some of the better design processes (to me) have involved turning the initial documentation into skeleton code, then writing comments around all the functions and classes that describe exactly what the program is supposed to do. Not only does it provide for excellent commenting and understandable code, it is immensely helpful in the writing of these functions.
/*retrieves the key 'SS#' from row r*/ may seem like overkill at first, but people who go over my work later don't even have to read the function for the code (unless they suspect the function is the source of a bug). They know what it is supposed to do, and a written out comment is generally clearer than a pre:post: with the bare minimum of description that some people prefer.
Having a function named "getKey(row r)" with a comment saying
Thats why I love eclipse, auto-indenting (Ctrl Shift F) comes in handy when fixing other peoples' code
Emacs will also handle /sbin/init and could be a replacement for mister house, but not all of us want to install a such a behemoth onto our workstations.
If you're doing OO, invest some time in a good unit testing framework, like xUnit. I'm inclined toward the agile method of test-driven development (flame away), so I would prefer that any code I have to maintain was written *after* the tests were constructed; however, I've seen valuable unit tests which were clearly either automatically generated or manually written after the code under test was completed.
As long as you commit to maintaining your tests, refactor all you want and rest assured that as long as your tests pass you're in good shape.
Of course, there are always exceptions. When I was writing low-level code that manipulated hardware registers, I wrote a multi-line comment before each line of bit-fiddling code, complete with what the code did and a cross-reference into the hardware manual. Something like:
What a fool believes, he sees, no wise man has the power to reason away.
Surely commenting comes as a result of a good design practice.
You start with a functional spec, from which a design spec is derived.
The design spec is then broken into functional units, which are each divided further and further until the code itself seems obvious.
The final design is given a walk-through to verify with peers.
This design could pretty much be converted into a set of comments, each of which describes how the code should function.
The problem comes when coders just give it a go, write stuff on the fly and don't bother with design. It could be brilliant code, but most often it's just plugging local holes without reference to the overall design.
Comments are generally a good coding practice, and should fall naturally out of a good design phase.
Don't laugh. As an old school COBOL programmer in my youth, documentation was everything. Now that other languages have come along, you really need to document what you do, you can't just be lazy and not be willing to explain what your code does, This is what is happening to every program tha I see (C++. and M). Poor documentation, poorly written code, and very little commentary on what the particular function does.
My spin on this, your are a very poor communicator to your co-workers if you can not put a few simple words to a function in your program.
I've been the CTO and system architect for two software companies and have built some big software systems still in use today, after more than a decade of use and development across multiple, large teams.
I personally hate comments for all but the most complex blocks of logic. Why? Because no one ever updates the comments, and pretty soon you have code that doesn't match the comments, and you end up wondering what's really supposed to happen. Comments end up as little fossilized turds that usually contain color commentary from people working too late into the night.
What do I like? Use long, descriptive variable names; solve problems with the simplest approach possible; separate the problem into layers; etc., etc.
And generating code from comments? Please... for that to ever really work, the comment syntact has to be as strict as code!
Having RTFA, I can see what he's trying to get at, but as someone who has (unfortunately) found himself spending most of my 10 year career in programming cleaning up other people's poop. At first I thought it was because I must have done something wrong that I kept ending up being assigned this work, but as I came to realise, it was because I make the code better than I found it and I have a knack for fixing stuff other people give up on. I also had silly managers who assign work to the people least qualified to do it.
At any rate, some observations:
1. 20 lines of comments "documenting" your code before you write it (or even after you write it) is far less useful than writing the code COHERENTLY and CORRECTLY in the first place.
Last month, I had a 1200 (yes 1,200) line method with huge blocks of documentation before big pieces of code. I still can't quite tell you what it thought it was doing. The code was a for loop wrapping around code to handle 3 different and mutually exclusive situations. Instead of identifying which of the 3 situations it was and creating a method for each situation, the person just stuffed it all in with lots of comments documenting everything the article's author said. The code was still unmaintainable.
2. Comments are useless unless they are kept up to date
Part of the reason that code was so difficult to figure out was because most of those big verbose documentation comments referred to a completely different implementation. After the programmer had written the first case, she encountered some other bad cases and eventually had to completely change a block of code embedded in this 1200 line for-loop. The code was now correct, but the comments no longer had anything to do with that block of code.
3. Don't be clever when you can be clear
I have made a solemn vow to hunt down and hurt anyone who puts "clever" code in my project. I am so sick of trying to figure out what some obfuscated piece of code in C, C++ or even SmallTalk is doing. And find out it was just a "clever" way of doing something pretty straight forward like iterating over a list. There was no speed gain from the clever trick, and the code wasn't even a bottleneck to begin with. *sigh*
4. If you don't know how to solve the problem, write some experiment code in a separate app to figure it out. Then take the time to do the "right" thing in the production code.
3 days from final for a video game. The CD streaming library for the Sony Playstation was making this strange "hic-up" sound at rare moments. By this time, the original author of this code has long since gone to another company. So I plunge into the code and found that the original programmer didn't know how to write streaming code so he created this hack of a hack of a hack of a test (ad nauseum). The code was programmed by accident, not design. No amount of comment before coding could help this. If the author had dumped the code, wrote documentation describing everything he learned then wrote the code, things would have been a lot better.
5. Unrelated to comments, but use variable names that make sense. Don't name them arbitrarily or to amuse yourself!
That CD sound streamer code I mentioned above used quirky names for variables. Can you tell what "little_ninja" is supposed to be just from the name? When I confronted the coder about this quirk of his (in another library he wrote), he got all huffy and didn't understand why people didn't appreciate his little puzzles or his sense of humor. It galls me he still earns a paycheck in the industry.
The bitter lessons of a veteran coder: http://bitterprogrammer.blogspot.com
program.files.each do | class |
class.methods.sort.each do | method |
5.times { method.refactor! unless method.elegant? }
end
if problem_domain > current_language
choices << comp.lang.each
current_language = choices.best
project.restart
evangelise(current_language)
end
end
comments << intentions.remove(implimentation_details)
puts comments
def refactor!
method.split! unless method.size < Too_Big
method.rename! unless method.name.clear?
end
def evangelise(lang)
slashdot.comment.post
puts "#{lang} is the only real language"
end
goto (1.0/0.0) and $beyond
http://www.rubygarden.org/ruby?MoviesTheRubyWay
The true useful skill lies in reading sloppy and/or wizardly code. Some people think that they have job security if they write impenetrable code, but then they can just be fired and all their code rewritten. If you can read others' "unmaintainable" code, you enable your employer to save money by not having to rewrite everything the guy they just fired wrote. So they'll want to keep you around as they fire/downsize everyone else. I It doesn't really matter what kind of code you write, since you can read whatever. advise everyone to start reading up on the Obfuscated C Contest, and practice figuring out what evertyhing does. Then you can handle any kind of code thrown at you, and the code you actually write becomes of secondary importance.
My learning experience about commenting code was a difficult one. Like many, while in college I wrote the code and then went back to comment it so the profs were happy.
Then I did a co-op with an automated storage/retreival systems company in their software department. One of the processes involved in a communications system needed some work. The code was licensed from another company in another country. There was no documentation for this communications system. There was very little commenting in the code. Luckily it wasn't in a foreign language. Unluckily it was wrong, apparently the structure of this program was similar to that of another, which was mostly gutted and rewritten, but a few old-program comments survived to be the ONLY comments in the new program.
Sure, the sources could be reverse engineered to provide the documentation required. I did it. It took a few weeks.
After that, I didn't leave comments for last anymore. It's been a good thing. I now work for a semiconductor design company and often write perl scripts or skill-language scripts to automate tedious tasks. I think I'm abou thte only one in the office that comments such scripts in any way. It's nice to read what stuff does when I have to revisit code many months or years later. I hate having to revisit someone else's code because it's nearly guaranteed to be completely barren of anything human-readable.
Listen up kids! Commenting is GOOD! Your professors aren't just being jerks. Learn the easy way and hopefully save yourself a great deal of trouble with your own code. Other people's code will always suck, but your own shouldn't have to.
whose name escapes me at the moment. But the idea is that you write comments that are like "psuedo-code" but much more English-like than ordinary psuedo-code. Then you refine the comments down further and further until you replace the lowest-level comments with individual statements, and the higher-level comments stay in as documentation. I remember trying this once and, while overkill for the simple project I was doing, I wrote some damn fine (and readable!) code that way.
If it's not one thing it's your mother.
as a full-time student who worked part time during summmers coding a php/mysql/flash based website... i know exactly how important comments can be. last summer, i'd have to go back to code i wrote the year before in order to update it or something along those lines, and i'd stare at it for hours thinking... "wtf is the point of this? i know it has some point, but i can't put my finger on it!" since then, although i have done very little as i was replaced by an immigrant from india... (grrr).. i have pledged to make decent comments in my code that detail what in god's name is going on.
GRANDPARENT: Especially if you change the code and now the comments are wrong
PARENT: You're incompetent if you don't change the comments to match the code. You're equally incompetent if you come across incorrect comments and leave them in. You're supposed to the job, so do it...
PARENT: As Fred Brooks said, "There is no silver bullet."
A database backend would go a long ways towards providing a silver bullet, i.e. if instead of writing your code to an ASCII text file, you were writing to a document management system that kept doubly linked associations between the lines of code and the comments associated with those lines of code, and if code/comment pairs had dirty bits, so that if you changed one [e.g. the code], then the dirty bit wouldn't get changed to clean until you verified that the other [e.g. the comment] was correct, then that would go a long way towards solving the problem.
I think we are still in the infancy of code/documentation/database integration, however.
Hmm. If you have a picture in your brain, you should be able to describe it in plain language. If you can't do that, then the code that implements it is of questionable validity. It doesn't make the code bad, but it does imply that the code is going to be difficult to follow.
"People who do stupid things with hazardous materials often die." -- Jim Davidson on alt.folklore.urban
I have written programs in both raw and literate programming style, i prefer the latter. In fact, i wrote a literate-program pre-processor to write programs, and it made the program easier to write and more bug-free.
In literate programming, you rely on a pre-processor to make the output production, so you are free to put things together as you want. What this means, is that bracketing code (eg open, close files), can be written in the same block, which are invoked separately.
The main program then ends up looking like a rough scetch, full of commands to include other bits. With wing comments, it is easy to see what is going on.
One uses a folding editor to search for strings like "!topic". This will not show you a consolidated index, but you can use it to also show where you're are, and any missing bugs.
On the main, Jon Bentley's comments on Literate Programming are fair (that is, it creates a good environment for writing single-purpose code), but one needs to consider the context the program is written for.
The form i use was specifically designed to allow all sorts of text-output, so the same file can make as output, eg .CMD, .REX, .TXT and .HTM output, which means that when you run the script you get a perfectly matched set of files, all correctly pointing to each other.
OS/2 - because choice is a terrible thing to waste.
the classes in which I learned the most about programming was not so much writing my own code, but "here's a pile of code, it does this. expand it to do this and this and this other thing"
very very good learning experience, because you then learn the value of comments as well as extending a program.
I love telling this story...
// break
Last year I had a brief stint at a small software company that had just taken a project in-house that was developed by an outside contractor. My job was to take the code they'd just inherited (which no one there knew anything about) and add some features to it on a tight schedule. Documentation? What documentation?
The extent of all of the code comments it had was the following (and no, I'm not making this up):
if(...) {
break;
}
If that wasn't bad enough, I knew the original developer personally. She was a former professor of mine and I'd worked for her company only a few months before she had taken that contract.
As someone who has had to deal with code with descriptive names and no comments or docs to go with them: If you write such code, may you rot in the lowest level of hell along with traitors, used car salesmen, and people who answer cell phones during movies.
--GrouchoMarx
Card-carrying member of the EFF, FSF, and ACLU. Are you?
I'd tweak this rule a bit -- it's not as important that the function body be short and sweet as it is that function's header-declaration comment be short and sweet. That is to say, what the function does should be easily describable in one or two simple sentences. That is because most people won't need to look at the function body (looking at the header file should suffice), but they will need to call the function properly from their code (or at least understand why and how it is used in other code).
Or to put it another way: complexity in the implementation of your function, while undesirable, can at least be "hidden" from the rest of the code universe and safely ignored (as long as your function works as documented in the header). Complexity in your function's API, on the otherhand, is much worse, because it will lead to complexity, confusion, frustration, and bugs in all the other code that uses it. Not to mention that you can always rewrite your function's implementation later if you feel the need to, but changing the interface can be much harder (or even impossible) because of all the other code that has come to depend on its previous behaviour.
I don't care if it's 90,000 hectares. That lake was not my doing.
Comments, at ***BEST***, tell you what the author of the comment *hopes* was going on, at the time it was written. The code that follows may well not do anything of the sort; it may have, at one point, only to have been re-written by somebody else at a later date; it may still do what was stated, though that's no longer what's needed.
;)
Yes, it takes longer, trying to grok uncommented spaghetti code, but doing so on a regular basis will help you develop a reputation for being able to fix any bug, anywhere, any time. It even allowed me to track down a bug in a now-defunct version of Borland C's optimizer, that produced incorrect code when two seemingly unrelated options were selected. There ain't *NO* amount of commenting in the source code that would have helped there.
Learn to do your job right. Don't depend on what was written in any comments. The compiler ignores comments; so should you. However, as damned few programmers actually know how to debug other people's code, and many are too lazy to read it like a compiler, do add comments to your own code. It makes the stuff easier for PHBs to read.
For those who want to grok code the way it's executed, I'd suggest you start like I did, by reading old obfuscated C code winners, and running them in your head, comparing what you got with what the computer got. You'll burn up a lot of scatch paper, but eventually, you'll see what I mean.
Lemon curry?
At work, we are not allowed to use comments in the code.
Allowing comments would "encourage coders to use clever tricks" according to the technical director.
Document your application, requirements, constraints, and system interactions (what the engineer does). Then write the code (what the coder does). What you will quickly learn is that it's better to be the engineer than the coder.
Interestingly there are a number of formal languages to do this, some of them rather similar to programming languages. For example you can use an algebraic specification language like CASL - it provides a structured way to define datatypes, operations on datatypes, and the axioms that the types and operations need to obey for the requirements to be met (For the mathematicians out there: an implementation is then a (many-sorted) universal algebra, and a specification is a presentation). There are things like refinement calculus and theorem provers to help you refine your requirements into an ever more specific specifications. Once that is done the actual programming is pretty much monkey work: there are extremely specific bounds on every datatype, every function, to the point where it is merely a matter just doing what you're told. The interesting part happen with the initial requirements specification and the refinement and design of the specification.
I happen to like CASL, and chose it here because the the syntax is similar to programming languages, but it is far from the only, or even the most popular specification language. You could try Z, or VDM, or B-method, or OBJ3, or any of the myriad other languages out there. Formal specification languages ought to be far more widely used than they apparently are. Isn't it about time more "software engineers" started paying attention to them?
Jedidiah.
Craft Beer Programming T-shirts
#include <stdlib.h>
...
/* global variables */
int ix;
void some_small_function() {
char slartibartfast;
}
1. Comment each function
// My function does foo // arg1 documentation // arg2 documentation
...
// Function guts go here
- Function name
- what it does
- parameters
parameter name - what is is for and any restrictions on it (i.e., must not be null)
- return value (all possible return values)
****
I really hate having parameters documented in a comment block above the function declaration, because it seldom gets updated when the function signature itself is changed.
I worked with a guy who used to format his functions like this:
void my_func(
int arg1,
char * arg2,
)
{
}
The nice thing about this method, although the "look" of a function is broken up, is that when you add or change parameters, the programmer is a lot more likely to change the documentation as well.
When you're under the gun to get the code out, the less the developer has to do to change the docs, the more likely it is they will be changed.
I think you really mean:
...or...
As you wrote it, the combination of potion_a and potion_c would have been valid, because ! potion_a would have returned false. Of course, there's also the fun perl construct:
(If you don't like perl's postfix if shorthand, feel free to flip that back round "the right way" and add the braces.) (The word "potion" is one of those strange words that just always looks like it's spelled wrong. Maybe my brain is trying to read it as "option"! :))
I am surprised nobody has brought up literate programming yet. Completely flips over the relationship between code and comments. You are principally writing a document for human consumption. One in a while, you also toss in a little fragment of code for the computer's benefit.
The code should be written so that it is obviously WHAT it does.
:-) Like when I go "ok, it's doing that... But WHY?", I know that I should have put in a comment. But if I go "WHAT the f**k is it doing here", those lines should be rewritten.
The comment should explain WHY.
Not that I use that convention myself, but I often wish that I did
It's not just that the programs to write are small, it's that they're write-only. You write them once, get graded, that's it. We churn generation after generation of students who are taught that code is written once, then never ever maintained.
Sure, you learn lots of things about design, software engineering, etc, in university, but they're pure theory. And seemingly useless theory at the moment. There is _nothing_ to illustrate there why some code organization is good, and why spagetti code is bad. All those lessons about maintenance as wasted when you never have to maintain anything, nor ever write anything big enough.
So while I'll say your idea does have merit, I think it can be done better. Don't just give them 1000 lines of someone else's code. Make them keep building and expanding the same program until the last year.
E.g., ok, in introductory programming they had to write some 100 line trivial program. But don't throw it away. When the next course comes along, give them the assignment to change or expand that original program.
E.g., if at some point you also get a computer graphics course, make them add a graphics module to that program. GUI programming? Sure, add a GUI to it. Database programming? Sure, make it save the data in a database. YACC? Ok, make them add a small scripting language to it. Different language? Make them port it to that language. Etc.
Make it a part of the grade to explain _what_ had to be changed and _why_.
Eventually it _will_ grow to be 1000 lines, and then it will grow even larger. And more importantly it'll be example of why code has to be readable and maintainable.
A polar bear is a cartesian bear after a coordinate transform.
Obviously you didn't learn shit. NO MAGIC NUMBERS means:
I think the gp post is implying that the students didn't understand why "no magic numbers" was a problem, so they worked in magic numbers anyway without grokking why you would give a number a meaningful name.
That is they didn't understand:
MAX_VALUE = 17;
if ( x > MAX_VALUE )
vs.
SEVENTEEN = 17;
if ( x > SEVENTEEN )
Education is a better safeguard of liberty than a standing army.
Edward Everett (1794 - 1865)
I don't understand why people don't use more descriptive variable names. For something stupidly simple like a counter in a 'for' loop, the iterating variable could easily be 'ctr' instead of 'c'. There is zero performance hit and everyone understands the code more clearly. TWO LETTERS, come on man!
Going further... in c++ member functions and variables should be more descriptive. For instance, in a variable length array class, (mMaxArrayLength, mCurrentArrayLength) are much much better than (max, len) which is the common lexicon.
I feel (at least in c++) that documentation should only be used to explain high level functionality, the inner workings of a fucntion/method should be evident by the variable/method/class names. It doesn't add code size or decrease performance in any way. And, with the advent of copy and paste, it doesn't really slow development time either.
BUT.... Even more important than that is consistancy. Whatever coding/documenting style is chosen for a particular project, for god sakes, stick with it. Nine out of ten coding/documenting styles will be exactly the same, with little changes here and there. The most important thing is be consistant with the whole project.
end of rant
Fast Federal Court and I.T.C. updates
I find that the most useful comments clarify the underlying code by adding something that may not be possible to get from the code itself. For example the intention of the code may or may not be clear (the code may be incorrect or it could 'mean' several things given the context) but a comment can be explicit about the intention.
The point is you are not repeating the code statements- you are adding information to the source code. This makes it a lot less likely the comment is going to go out of date. In many cases you can change code and the comment will still remain the same (you are still searching a hash for the RequestItemId- just doing it faster/better/correctly).
Programming is about translating concepts from a problem domain (Billing, Accounting, CRM, Networking, Memory Paging) into code (be it C, C++, Java, Perl, Pascal..). We endeavour to build functions, methods and objects that map to the problem domain (so we can display a picture, act on a button click, add a charge to a customer's bill...). But this translation inevitably has some tricky bits that are not clear from the code (what format is the time in? why do we have to mask of the data retrieved from disk? why aren't we validating the customer's username?). So it can be useful to put the 'original' (our intention) in there and any useful translation notes (the tricky or non-obvious bits) so that we can make it clear where something is done or not done deliberately- and when it is simply an error.
Good comments add information not necessarily obvious from code. That makes it tricky to write good comments since you have to look at the code as if you had never seen it before and ask: what isn't obvious about this? Which is why writing the comments before you write the code can be much more effective. After you've written the code it just feels like you are stating the obvious. Which it is- to you, at that moment in time.
I'm a physicist, working on hardware design for MRI scanners. I do electromagnetic theory, power systems, and basic home wiring. What's wrong with that? I also do messing around with super glue, and coding computer simulations.
CS is not that useful, as a subject by itself. There are lots of us out here that design software, and code it, but we're not computer scientists. It's just a tool we use at get somewhere.
What's easier? To teach a computer scientist physics, or to teach a physicst to produce software? Exactly.
The comments from the TAs about near useless comments was interesting.
Getting people to do any comments is a conversation in itself.
However, the TAs brought up a good point. It is not enough to put ANY comments in a file, you need to put GOOD comments in, but who teaches people what good commenting is?
What works for me is
- putting a small paragraph at the top of file
explaining, in general, what the file is for
( sort of like labeling a jar with the preserves
you just put into it )
- putting a 1-2 line description above each
non-trivial function
- putting a sentence fragment above each
significant or non intuitive ( coding around a
quirk ) block of code
I get compliments on how easy it is to understand and maintain my code( often resulting in me getting to asked to write more code - versus the folks who intentionally obscure things in the pursuit of job security ). I can also go back to code I wrote years ago and understand what it is going on.
I put comments in as I write the code, mostly, so it doesn't feel like a burden.
If anyone has any other good idea, please do tell, someone somewhere is likely to give it a try.
I teach computer programming part time at a local college - when students sign-up :(. 50% of their grade is based on their comments. I have spent too many years in industry to dismiss that value of good comments in code. Commenting first helps you think through your solution then you stomp down your code and clean-up your comments. Time and again this will take you LESS time and produce higher quality code then just banging away.
What should be done is: Take this 1000 line programme. Add on 5 lines. Add on 20 lines. Add on 100 lines.
Maybe. My introduction to programming class I had to take at university used this approach (except with shorter programs). Things like "make this say 'hello world' instead of 'hello people'", and "add another button that does the same thing as all the others".
The end result was that most people simply couldn't write a program from scratch if their life depended upon it.
Maybe as a component for people who can already write thousand line programs it would be effective. But people that far along should already know how to write comments anyway.
To paraphrase Einstein: we should write as few comments as possible, but no fewer. The reason is that comments don't execute and therefore aren't constrained to tell the truth about the code. So anything about the code that can be said directly in the code ought to be because that makes what's been said inseparable from what actually happens when the program runs. If it can't be said in the code then it ought to be said in the tests. Tests don't force the code to conform to the properties that they describe but the do tell you if it doesn't. They are one step removed but still provable. The redundancy of saying the same thing in both the code and the tests is valuable because the difference in perspective forces a greater degree of precision and, therefore, a higher chance of correctness.
Saying the same thing again in comments is not useful from the perspective of correctness, so the value of redundancy in comments is limited to the value of redundancy in most communication: if it's done sparingly it adds emphasis, otherwise it's just a harmful distraction. The value of comments is that they can be used to say all of the things that couldn't be said in the code or in the tests. The best code expresses the vast majority of its important information in the code and the tests, but is not stingy about expressing all the rest of its important information in comments. Comments written in this way augment the code without distracting from it.
Remember:
I've seen cases where a fresh from school programmer turned 20,000 lines of complex, hard to understand code into 3,000. The complex code was written by a programmer with 20 years experience. (Hence my belief that you cannot be both a good programmer and a good musician)