Code Advice #16: Don't Encode Symbol Type in Variable Names!


(See intro for a background and caveats on these coding advice blog entries.)



I came across a JavaWorld coding-advice article the other day. While the thread which led me there referenced the second point of the article, I couldn't get past the first one where the author argues that


...a reader needs to know which items are local variables, which are fields, and which are method arguments. [...] It's likely best to use a simple naming convention to distinguish between these three cases.




I couldn't disagree more!



His key argument seems to be that when you are reading code, it's important to know whether something is a field since when you read a method, you might suddenly see a reference to something you haven't seen before. To make his point he shows this graphic:







His improved version is here:







I have a couple of problems with this.



First of all, why encode this information in the symbol name when IDEs will show this information automatically? NetBeans will show fields in greens, and statics in italics - and it will always be right, whereas the code might lie. Just like comments can get out of sync with reality, you could inline a field without remembering to change its name (especially if another developer did it without realizing the meaning of the variable prefix). Or if you get in the habit of seeing an "f" prefix as meaning field, what about local variables that legitimately should start with an f, such as "focus" ? Sure, the second variable should be capitalized, but what about typographically similar symbols like lowercase l and uppercase I?



Here's how the same function looks in NetBeans:







In addition to showing us the fields in clear green, the IDE also pointed out that this method is overriding another method (I hovered over the overrides glyph in the editor margin). The yellow line is warning us that this override doesn't have an @Override explicit annotation on it.
Information about overrides is just as important as whether an identifier is a field.



Highlighting fields in green isn't specific to Java... We do this for many other languages - see some screenshots of
Ruby, PHP, Groovy, etc.



Here's a snippet of JavaScript - notice how we have a reference to a global variable in there shown in green:






The key point here is that you shouldn't write your code to target reading code in black and white on paper. You shouldn't print out your code at all! Reading code with an IDE lets you easily check any condition you encounter (and just like in a browser there is a little go-back icon in the editor toolbar which maintains a visit stack so you can easily pursue multiple ctrl-clicks to track something down and then easily go back).



There are some other conventions left over from the days of code written on tiny terminals and printed out on paper for review - such as the "maximum 72 characters per line" limit. There's no reason for that when using modern tools. If the code is more readable unwrapped at 100 characters, leave it that way rather than introduce arbitrary breaks in the middle. (Having said that, don't take this as an endorsement to write deeply nested methods, that's a sign of poorly thought out design.)


My second objection to the article is that it is not clear to me that knowing whether something is a field or not is the critical piece of information you need. I think the following questions are probably more important:


  • What is the meaning of the variable, and what is the intended use?
  • Can it be null? Can it be negative?
  • What is its type?
  • Where else is it referenced?

And so on. Just prepending an "f" on a field reduces readability in order to avoid a simple lookup, when I believe you in general
need to know more context anyway.
And again, a tool can help you here. In NetBeans, hold down the Ctrl key (Command on the Mac) and hover over a symbol and you get help like
this:







(As a side note: I heard that at a Scala talk in JavaOne, Bill Venners was showing NetBeans through most of his talk, but he switched
to Eclipse to show one feature: Pointing at symbols show the actual inferred types of scala identifiers. Scala is as you know a statically
typed language, but uses a lot of type inference so the types aren't obvious from looking at the source. That's a very useful feature,
and I thought I'd point out that NetBeans has this feature too -- using the exact same mechanism as the above; just hold the Cmd/Ctrl key
and hover over a symbol, and you will see its type.)



Finally, the article makes a point that you probably want to distinguish parameters as well. I agree with that, but again not by changing
the name of the parameters, but through color identification. In Ruby, JavaScript, Python etc. we do that automatically in NetBeans - parameters are orange by default. For Java, it's not enabled by default (at one point it was, but somebody determined that the source code just looked too colorful, so the default color scheme was dialed back. I was working on Ruby at the time so my colors flew under the radar... and
all GSF-based languages such as JavaScript, Python, Scala etc. now inherit that color scheme...)



You can turn this on for Java as well. Just open the preferences, and for Fonts and Colors choose the Java language, then customize the Parameter Use and Parameter Declaration values:







Some languages like Ruby use sigils, where fields start with @, globals with $, symbols with : and so on. I don't have a problem with that
since I don't think these are as obtrusive as -letters- in variable names.



If you are reading code on paper, or with an editor that doesn't support semantic highlighting, you are voluntarily handicapping yourself.


Comments:

Oh man, IDEs and text editors are already so advanced these days and yet somebody is still recommending Hungarian notation (while also saying that it isn't, but it IS) just so that it is readable in black and white but poisons your brain while reading it when you have no idea what is "f" and "a" and whatever else.

No wonder Linus Torvalds called it "brain damaged".

Posted by Hendy on June 17, 2009 at 03:01 AM PDT #

I have mixed feelings about that... I don't like Hungarian notation, but some notation to distinguish fields from local variable is OK for me (I use it, and it happens that code conventions at my job use it too). Arguments are just local variables (more or less) anyway.

As you point out, one problem is that everybody using this have different conventions (we use m_ for fields, s_ for static fields...), so you have to know the coding rules to use it.

Now, I disagree with you. B&W code on paper isn't the only case where this information isn't available readily.

At home and at work, I have rather old, slow computers without much memory. So instead of waiting for Eclipse to ruminate for dozens of seconds to display a popup I don't even need, I do most of my typing in a good editor (SciTE) but not smart enough to distinguish the various identifiers. It is fast and lightweight...

We also read lot of code on the Web: it is often just B&W, and if colored, it is rarely smarter than my editor...

I can also read a .java file out of an archive (no project set up), in an e-mail, etc.

In most of these cases, in the middle of a lengthy method, I am often confused by some identifier coming from who know where (given example isn't meaningful as short methods doesn't really need such conventions).

Of course, all this belong to holy wars (prefixes or not, tabs or spaces, braces in-line or on their own line, etc.), more matter of taste and choice than anything: we can argue endlessly!

I agree at least that when I use IDEs (I do! at least for checking code, navigating and debugging), they make my life easier...

Posted by Philippe Lhoste on June 18, 2009 at 01:19 AM PDT #

I couldn't agree more - may this coding style be forever banned.

Posted by Sven Reimers on June 20, 2009 at 03:51 AM PDT #

Personally, I agree with you and personally don't use that style.
However, the argument about an IDE is kind of misleading. It's true that with an IDE, all the extra coding is not needed as the IDE clearly shows what's going on.
But, as previous commenters have posted, there is lots of times when people need to look at code not in an IDE - either to take a quick look at a file or from a zip file or even looking at code in an online repository.

Posted by Yonatan Taragin on June 20, 2009 at 04:34 PM PDT #

Thank you for your comments everybody!

I still stand by my point. I don't think we should reduce the readability of our code in order to make it easily readable from an inferior web interface or a notepad clone.

If you need to look up code and you need to properly understand it, download the code and open it in an IDE. If you insist on reading it in notepad, or through a VCS web front end, then you're probably only trying to cut & paste something ("how do I convert a URL to a file?") or tweak something (update a typo in a message). To -really- understand code, you need to know about overrides, you may need to look up inherited fields and methods, and if you are modifying the code, you probably need to be warned about both syntax and semantic errors you are making.

Adopting a code convention which helps you distinguish fields from local variables doesn't in a meaningful way make your job outside of an IDE significantly easier.

Posted by Tor Norbye on June 21, 2009 at 03:43 AM PDT #

Post a Comment:
Comments are closed for this entry.
About

Tor Norbye

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today