Abstract: In this, our most misunderstood newsletter, I wax lyrically about the poor quality of comments in code. Often the comments are not in sync with what the code does. Trust them at your own risk.
Welcome to the 39th edition of The Java(tm) Specialists' Newsletter, sent to over 2400 Java experts in 72 countries, with the most recent addition being Costa Rica. In this newsletter I am talking rather philosophically about commenting your code, looking at some examples from the JDK. The newsletter is a bit different to my normal ones, but didn't require less work (don't all unsubscribe at once, ok ;-)
javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.
Many years ago, my brothers and I clubbed together and bought ourselves a ZX Spectrum 48k. Nice computer, especially after I stuck it inside a DK Tronics keyboard, but the problem we had with our machine was that after a random delay, it would reset itself. My big brother subscribed to a computer magazine, which included listing for games, etc. for the ZX Spectrum. There was one particular game to do with some rocket, which wasn't too long, so I decided to type it in. Somewhere in the text it said that the game had been tested only on the 16KB Spectrum, but I thought: "What the hell, I'll try it out." After *many* resets, it was finally finished, and, guess what, it never worked! One day my brother was watching me type and noticed how I was typing in all the comments (prefixed by REM). I was of tender young age and couldn't understand how the computer could understand this English comment - maybe some internal fuzzy logic, or artificial intelligence? I was most disappointed when my brother told me that REM actually did exactly zilch. Nothing. Nada. Gar nichts. Tipota. At that moment, I developed a keen distrust of comments.
After spending some years programming in Basic (without comments) I enrolled in a university degree for Computer Science. One of the things the lecturers seemed to emphasize was that your code had to have comments. Infact, due to the meanness of their spirits, they used to give us bad marks if we didn't comment our code! So, after one or two pracs with bad marks we all learned that it was a good thing to have comments. Good to have them so we wouldn't get bad marks. We then proceeded to work like this: Hack, hack, hack, hack, hack, hack. Oh, deadline time. Rename variable names from f, g, h to interest, bond, currency. Add comments before every line of code. For example (we had progressed to C at this point):
/* Conter variabble for "for" loop. */ int i; /* Toatl of additions for calculaton */ int t; /* Indicidual number for calclatuion */ int d; /* "for" loop */ for (i=0; i<100; i++) { /* increment i by one until hunderd */ d = f(); /* get ghe calue for d */ t = t + d; /* ad it to t */ } return t; /* return the variable t */
all the spelling mistakes in that code were intentional
Our lecturers, who only knew an old version of Algol, could now at least understand what we had coded, and guess what, we were rewarded for our diligence with fantastic marks. Our marks were allocated like this: Does it work correctly? 50% Was it commented? 100%
As you might imagine, through it all, I couldn't shake the feeling that I was wasting my time. Let's pan forward a few years to when I, rather naively still, started using Java. In those dark days, we didn't have fancy tools like intellisense, so I relied very much on JavaDocs. I thought JavaDocs were manna from heaven - at least we didn't have to waste our time converting our comments to documentation. Quite a few times though, I got into real trouble because I believed what was written in the JavaDocs of various libraries.
Some time after JBuilder 2, I started browsing to the source code of a class whenever I wanted to know something about it. I still use JBuilder 3, since it suits my needs very well, and whenever I need to know how to do something, I use either intellisense to remind me, or I look at the source code. It would never occur to me to read the comments that geeks like you and I had written "because it was the right thing to do". Why don't I like comments? Here are some of my reasons:
Some of these reasons are quite controversial, but I am in good company with my opinions. Let's qualify them a bit further by looking at some source snippets that made me snigger over the last few weeks.
The first one that made me laugh was found in JDK 1.3.1 in the
java.awt.color.ColorSpace.getName(int)
method. It
had the classical computer programmer under pressure
comment of "REMIND - ..."
From JDK 1.3.1: java.awt.color.ColorSpace: /** * Returns the name of the component given the component index */ public String getName (int idx) { /* REMIND - handle common cases here */ return new String("Unnamed color component("+idx+")"); }
I went back to JDK 1.2.2 and there was exactly the same comment (didn't have source to earlier versions on my disk). I immediately opened up the source for JDK 1.4 beta, and had to chuckle even more when I looked at this:
From JDK 1.4 beta: java.awt.color.ColorSpace: /** * Returns the name of the component given the component index. * @param idx The component index. * @return The name of the component at the specified index. */ public String getName (int idx) { /* REMIND - handle common cases here */ return new String("Unnamed color component("+idx+")"); }
Wow! So that's what idx
meant! I thought it
was some abbreviation of "idiots do xml". Oh, and getName()
returns a name! Who would've thought that! Why didn't they rather
spend more time fixing the code?
Another one that made me chuckle is java.util.Locale.toLowerCase()
.
Again we had a magical reminder - this time it said:
"Look at optimizations later".
From JDK 1.3.1: java.util.Locale: /* * Locale needs its own, locale insenitive version of toLowerCase to * avoid circularity problems between Locale and String. * The most straightforward algorithm is used. Look at optimizations later. */ private String toLowerCase(String str) { char[] buf = str.toCharArray(); for (int i = 0; i < buf.length; i++) { buf[i] = Character.toLowerCase( buf[i] ); } return new String( buf ); }
Sure this is inefficient, isn't the whole Locale class though? Even hashCode is synchronized - generally not a good idea! Why did the programmers not simply make it more optimal in the first place?
So, when do I like comments? I like comments when they provide information that I could not glean from the name of the method, such as pre/post conditions, etc. A place where comments are absolutely essential is with interfaces, since I cannot guess what the message would really do unless there was a good comment.
That's all for this week, I'm running out of time. Next week I will give you a more conventional newsletter again.
Heinz
We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)
We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.