Joel Spolsky wrote an interesting article which had a brief history of Hungarian notation, amongst other things. Cedric Beust’s picked it up and made the claim that We are all Hungarian Notation users. I’m not buying it.
I’ve got two disagreements with Hungarian notation.
The “information” encoded in the variable name is often irrelevant. This is the “dark side” of Hungarian notation that Joel points out. What possible meaning does, oh, having an ‘I’ at the front of a type name, give me, other than I can’t instantiate it? What about other types I can’t instantiate (such as classes with no visible constructor, or abstract classes)?
Condensing information into a couple of letters at the front makes it hard to work out what is meant. Why bother? Why not just spell out the information to get a meaningful variable name? After all, IDEs expand variables for us easily enough[1], so the extra typing isn’t an issue.
Another “disagreement” is that you should use the type system of the language to encode type information. This is only a pseudo-disagreement, because that’s a little awkward to do in C (you would keep needing to pull the primitive components of the type back out again). But guess what? I don’t write C code any more, and I’ll be damned if I want to write C code in Java.
Joel’s first example of the use of Hungarian notation is ‘rw’ and ‘col’ prefixes for, well, rows and columns. So what’s wrong with ‘row’ or ‘column’ prefixes? Is it still Hungarian notation if I spell the word out? I don’t think so. What if I use ‘Row’ and ‘Column’ types, and toss away the prefix?
Cedric’s first example (the use of ‘i’, ‘j, and ‘k’ for loop counters) isn’t an example of Hungarian notation. It’s an example of a coding idiom. ‘cnt1’, ‘cnt2’, ‘cnt3’ is Hungarian (and also an idiom, as well). ‘counter1’, ‘counter2’, ‘counter3’ work just as well, but is no longer Hungarian. Using a for-each loop is a different idiom that removes the entire problem, and it’s what I exclusively use since I moved up to Java 5.
Cedric’s second example, ‘the widget’, ‘the label of the widget’, ‘the callback of the widget’ is even easier to address. Give the widget a meaningful name. Then call ‘widget.getLabel()’ or ‘widget.getCallback()’ (where widget, obviously, gets replaced by the meaningful name). Works like a charm.
So, Cedric, no I don’t use Hungarian notation. Yes, I use meaningful variable names. Yes, in some occasions, I use idiomatic abbreviations, such as ‘i’, ‘j’, ‘k’. But this isn’t Hungarian in either sense put forward by Joel.
[1] If you’re an anti-IDE zealot, that’s your problem. Work out how to get your editor to expand variable names for you, by using a language-aware mode.
If you wanted to store widget.getLabel() and widget.getCallback() in variables, how would you name them?
I’d use <widgetname>Label. That’s not Hungarian, though. Hungarian would be lbl<widgetName>. Or possibly I’d use the text (or resource Id) of the label, as _that’s_ the identifying information of interest.
However, I wouldn’t bother until I was making lots of calls to widget.getLabel(). At that point, it’s probably worth arguing that what I should have is a method that takes a Label, do all the things involving the widget’s Label there, then move on.
Let’s be explict about this: Hungarian notation is the practice of embeding meaning into variable names via abbreviations and acronyms, to reduce overall variable length. I don’t like that. I do, however, prefer it to meaningless names inside of meaningless contexts.
Robert, you should re-read Joel’s article. Calling it Label is *exactly* Hungarian, and *exactly* what I am talking about.
<widget>Label is not Hungarian.To quote Joel’s article: “In Simonyi’s version of Hungarian notation, every variable was prefixed with a lower case tag that indicated the kind of thing that the variable contained.”
The suffix “Label” doesn’t indicate the kind; the type of the variable (being Label) does that. The prefix of the widget name indicates _ownership_. If I don’t care about ownership, I call it ‘label’. When it’s “widget’s label”, I call it ‘widgetLabel’ _if_ I don’t use ‘widget.getLabel()”. As I’m indicating ownership, not kind, it definitely isn’t Hungarian notation.
Essentially, I know it’s a Label. I don’t need to encode the kind or type in the name to remember it’s a Label (or a Row, or a Column). But who’s Label is it? That’s something to encode, and it’s _not_ Hungarian.
Java developers are the laziest developers ever. You say that extra typing isn’t an issue, yet arguments go on and on about getters and setters because they are so verbose. IDE’s generate these automatically too, right? Probably even vi or emacs would. 🙂
I’ve never complained about getters and setters because of extra typing; as you say, the IDE generates these. I complain about them because of the damage done to the design model due to broken abstractions.
I’ve blogged a little about this before: http://www.redhillconsulting.com.au/blogs/simon/archives/000118.html.
I find hungarian notation just one of the many smells indiciative of missing abstractions.
Gotta agree here, Simon. As I said earlier, Hungarian is about encoding ‘kind’ or ‘type’ information. This should be obvious from the local context in well-factored code with decent abstractions, because the declaration shouldn’t be far away!
Wether it is a suffix or prefix doesn’t count; I can make “labelWidget” mean the “label owned by widget”, or I can make it mean “a widget that is a label”. The first is not Hungarian notation. I do, however, find the suffix form more readable.
Cryptic abbreviations, OTH, are _not_ part of Hungarian but merely a legacy of the era when the form was derived.
Children, play nice.
Maybe you need to have your own IDEs convert from one standard to another as you open a file (and back as it is saved).