I'm reading Hackers and Painters, and as much as I enjoy the general idea of most of the essays, Paul Graham seems to pull certain things out of the ether for no apparent reason.
In the essay "Hackers and Painters" (online version, slightly different), he says:
Many a hacker has written a program only to find on returning to it six months later that he has no idea how it works. I know several people who've sworn off Perl after such experiences.
The way to make programs easy to read is not to stuff them with comments.
Strangely, I agree with Graham's point. Sparse, on-point comments are wonderful. Code that's too tricksy to grok should be rewritten. From my own experience, I find that my perl vocabulary has shrunk while making the programs easier for me to pick up months later. Also, debuggers work on code, not comments. That's to say, a reader needs to grok the code not what the comments say about the code. And the debugger is an excellent way to understand how the code really works. I recall exploring both Tk and DBI using this technique.
It's an obvious point, I know, but what I'm after is clean code that's only as complicated as it needs to be. So while I'm not against commenting, I am against making a fetish of them.
Re:comments suck
Dom2 on 2004-12-19T22:04:46
I don't find anything wrong with large comments outlining intention. What I (and I think Paul Graham) objects to is something like this:$a = $a + 1; # Add one to $a.-Dom
Re:comments suck
Smylers on 2004-12-20T00:14:17
What I (and I think Paul Graham) objects to is something like this:
$a = $a + 1; # Add one to $a.I also agree with Graham, and I don't think that was quite what he had in mind, especially since he mentioned Perl, and the above type of commenting can crop up in any language.
One of the main reasons I love Perl is because of its expressiveness: the fact that the language is so malleable that you can craft the code to closely map to the underlying process that it's implementing. And that's what I always try to do.
But there are other programmers who, for whatever reason, don't aim to do this; some are merely happy that their code runs at all and just go for the first thing that works. This is where Perl's flexibility gives it a bad name (and hence gets cited in Graham's article): people carelessly drifting towards a working program without being bothered by its form will probably end up with something that is convoluted, and hard to read. This couldn't happen to anywhere near the same extent in a language such as Java, which is so rigid that multiple programmers write almost identical code to each other (that is, even the good programmers are restricted from writing code that is anywhere near as expressive as a carefully written Perl program would be).
At work I've had to add features to some Perl code that I've found incredibly hard to read. Once I've finally grasped what the code is doing (and why) I feel I should put the knowledge to good use before it gets lost again. One option is to put a comment in the code explaining it.
Another option is to re-arrange the code (“refactor”, if you like) so that it better reflects the underlying business logic. That's always my preferred option (time permitting): why have hard-to-read code with a comment attached, when instead you can have code that's sufficiently clear it doesn't require a comment?
I believe that is the point Graham was making.
SmylersRe:comments suck
brian_d_foy on 2004-12-20T03:54:14
Either point is fine, but I don't see how they are connected. Unreadable Perl code and bad comments don't seem to support each other's validity.Re:comments suck
Ovid on 2004-12-20T05:23:32
Code that's too tricksy to grok should be rewritten.
Sometimes code needs to be complicated. Some tasks are tough and impossible to oversimplify and that can justify comments. That being said, shoving that code into an appropriately named subroutine should make it easier.
However, there is one thing that code frequently cannot reveal and that is why something is being done. Maybe it's easy to see that the clone of the customer object does not include their Social Security Number, but that doesn't tell you why. Is it a bug, something to help protect privacy or just not bothering to clone unecessary fields? Any of those reasons could be valid, but the code could be useless as a point of explanation.
Re: $_
Smylers on 2004-12-20T10:00:45
When it comes to Perl, I find that using implicit $_ often obscures the code. Not using an explicit variable means a missed opportunity to self-document the code by naming the variable properly.I think the exact opposite.
$_
has a meaning in Perl: “the current ‘thing’ being operated on”. That's a well-defined convention, and it has the advantage of being the same in every program.In other languages when people want a temporary variable they often use
i
orn
ors
, but they aren't more readable than$_
.If you've got an
@server
array of objects, and perhaps a$server_num
variable too, and you want to iterate over each server, you could call the iterator variable$server
, but then you have several variables with very similar names. Far better to use the form offoreach
that doesn't explicitly name an iterator variable to avoid having to synthesize an artificial name, and use the standard name that Perl already provides.SmylersRe: $_
jplindstrom on 2004-12-20T16:33:03
Using $i as a loop variable doesn't increase readability unless it is to communicate that "it's just a loop variable" and that's seldom the case since the Perl foreach is so much more useful than the C-style for loop.
If the code block is very brief, like inthen I agree that it isn't necessary to alias it to a new name. But if the code block is longer than a few lines, it's indeed very useful to have an actual name connected to the entity you're dealing with.dostuff($_) for(@servers);
Consider the following piece of code:Note how the my $oReply line doesn't stand alone since you have to backtrack to the loop to find out what $_ is.for ($oPost->aCommentLast($no)) {
sleepMinutes(rand(2));
my $oReplier = Snacks::Subscriber->oGetRandom;
my $oReply = Snacks::Message->new(
oPoster => $oReplier,
oReplyTo => $oMessage,
text => $_->{text}
);
$oReply->send($oSender);
}
Comments make Perl unreadable, says Paul Graham
I'm not fond of seeing such misleading attributions. I'll try to give you the benefit of the doubt and assume that you actually think this is what he is saying, but I have a difficult time seeing how you (or anyone) can come to that conclusion.
If Paul had stated,
The way to get rid of the stench of spoiled food in an apartment is not to spray a bunch of air freshner.
Would it make sense to summarize it as follows?
Air freshner makes apartments stink, says Paul Graham
That is just poor logic.
Re:Misleading Subject
brian_d_foy on 2004-12-20T03:51:46
His comment is that Perl is unreadable, and the end note to support that says that comments are an abomination. As I said in my post, I don't see how he connects the two. Either statement is fine by itself, but not together: hence, the title.
Indeed it is poor logic, but it is what he uses to support that Perl is unreadable. I don't know why he connected those two. What do you think it means when he connects those two things?Re:Misleading Subject
shiflett on 2004-12-20T04:54:05
His comment is that Perl is unreadable, and the end note to support that says that comments are an abomination.I don't think that's what he's saying at all (neither point, in fact). His point is that comments don't guarantee programs that are "written for people to read, and only incidentally for machines to execute."
Indeed it is poor logic, but it is what he uses to support that Perl is unreadable.I meant that your summary was poor logic. It's the classic logic problem. If A, then B. Does this mean if B, then A? How about if not B then not A?
In a footnote, he states, "The way to make programs easy to read is not to stuff them with comments." Regardless of whether you agree, clearly it is a logical fallacy to equate this statement with, "Comments make Perl unreadable." A logical conclusion would be, "Comments don't make programs readable." See the difference?
I also happen to think that Paul intends to be discussing programming as a craft, not programming languages.
Re:Misleading Subject
brian_d_foy on 2004-12-20T08:03:22
I understand logic so you don't need to explain it. I think Paul makes a leap in logic. That's my point. That's what I discuss in the post, and that's why I chose the title. It's ironic. See the title in the context of the post. It's not what he says, it's that he connects them. It's very clear in the post that I don't know what he's actually trying to say.
The two statements I pulled out do not connect with each other, but Paul specifically and on purpose connects them. He's using one to support the other. He's not talking about programming languages in general. He's talking about Perl. If he were talking about languages in general, he didn't have to single out one.
Whatever he's saying is unclear, and it's only something he knows.
I don't think that Perl code needs comments more than any other code.
This is where you're getting tripped up.
Here's my version of Graham's logic:
I'm going to guess that you two disagree on the last point.
But it's hard to know for sure.
Re:Perl code needs more comments...
brian_d_foy on 2004-12-20T09:32:10
I guess that could be that point, even if I don't agree with it.
As I've been thinking about this and trying to get into his mind, and I have the feeling he may be talking about people who tried Perl for a couple of days and then stopped. Six months later they can't remember anything from those two days. That's not surprising.
Or, he's talking about people who tried to understand somebody else's code and gave up after a couple of days. Well, I have that problem with a lot of code no matter the language.
Maybe I should just ask him what he meant.
Knowing Paul's background is as a lisp hacker, I would hazard a guess that the readers he's talking about are not people deeply steeped in Perl, but people who will dabble with Perl on occasion, and not get too deeply attached to any language other than Lisp. From that perspective, Perl is a little befuddling, what with all of the special variables and contexts. For example, it may make total sense to you today that $|++ is the magic incantation to turn off output buffering, but six months from now, deleting that seemingly innocuous do-nothing assignment actually changes the behavior of the program in a way you would not have predicted.You need to have empathy not just for your users, but for your readers. It's in your interest, because you'll be one of them. Many a hacker has written a program only to find on returning to it six months later that he has no idea how it works. I know several people who've sworn off Perl after such experiences. [7][7] The way to make programs easy to read is not to stuff them with comments. I would take Abelson and Sussman's quote a step further. Programming languages should be designed to express algorithms, and only incidentally to tell computers how to execute them. A good programming language ought to be better for explaining software than English. You should only need comments when there is some kind of kludge you need to warn readers about, just as on a road there are only arrows on parts with unexpectedly sharp curves.
Perl is like that, because Perl is optimized in different axes. If you are comfortable with C, sh, awk, or other languages that are more popular than Lisp, the syntax will be somewhat comforting and easy to pick up. If you spend enough time with it to consider yourself a Perl programmer (rather than a programmer who hacks on the odd Perl script now and again), the little idiosyncracies will be simple concise statements of purpose (like the difference between $count=@list vs. ($first)=@list).
Perl is different in this respect. It's not unique, because there are some dark corners in C++ that I wouldn't want to visit even if Aragorn and the entire army of Middle Earth was on my side leaving comments along the way as they prepared to battle the compiler. And, no offense to John McCarthy, but Lisp only starts to make sense once you've drunk deeply from the magic bowl of Lambda flavored Kool-Aid and convinced yourself that the smell is much worse than the taste.
Add all that up and what do you get? Comments won't save you, and if you're not interested in joining the church of Perl, you may need more comments than average to Perl's context and special variables straight in your head.
It thought what he was saying was quite clear, if pretty silly. He's saying that Perl tempts people to write confusing code, which they usually react to by adding comments to hopefully later remind themselves of their mental pirouettes.
To which I reply “You are correct, sir, but it's a poor craftsman who blames his tools.”