Fog Creek Software
Discussion Board




Hungarian Notation

Would be interesting in hearing what people are thinking about using Hungarian Notation in coding. That is putting a prefix that describes the elements type, eg. strName

I recently had a hell of a job changing someone's code who had started with integers but then needed to use long integers. All of a sudden hundreds of lines of code had  prefixes that need to be changed from intFoo to lngFoo.

This has made me think that it's not worth the trouble. And on reflection the least of my coding problems are forgeting the type of a variable.

Matthew Lock
Wednesday, October 31, 2001

I've found that it's especially helpful for pointers. So for example if you see

pch = 'c';

you know it's a bug, and should be

*pch = 'c';

because mentally you peel off the '*p' prefixes.

Hungarian is just another way to add information to code, making it easier to read because it conveys more information. In fact at Fog Creek we use Hungarian in databases too, to denote the type of columns, and it tends to be moderately helpful.

The biggest benefits of hungarian are in C code, I think, where the difference between an lpsz and a rgch is very subtle and important and the Hungarian makes wrong code LOOK wrong.

(rgch = array of chars, e.g. char foo[16], you can expect that rgch itself allocates space. lpsz = pointer to a null-terminated string, which probably points to a string someone else allocated or which was allocated with malloc/new.)

Microsoft programmers got so used to hungarian they evangelized it for Visual Basic programming, where it is much less important and useful.

Joel Spolsky
Thursday, November 01, 2001

In my experience Hungarian notation isn't all that useful in C/C++.  I could see why you might want to do it for a database, but in C/C++ it's pretty easy to tell from context whether a variable is a number, a structure, an array, or a string.  And frankly, changing intXXX to lngXXX is just anal, IMHO.  In my own code I borrow some Hungarian notation conventions from time to time, but I don't see any reason to be rigorous about it.

What *is* useful to me when I'm reading someone else's code is the ability to tell quickly what scope an identifier has; specifically, the ability to tell between a instance variable (m_foo or _foo) and a local variable (foo), or between an instance method call (this->foo()) and a function call in the global namespace (::foo()).  Knowing where something is declared makes it easy to look up the type if necessary also.

Alyosha`
Thursday, November 01, 2001

Wow, if your tools make search-and-replace from "int" to "lng" THAT tough, maybe it's time to investigate new tools. Though I don't think I'd do a global s&r in that case anyhow. Looking at every single place where intFoo is used and verifying that the code doesn't need to be changed for lngFoo is a good way to make sure you've thought through the effect of the change.

My experience on projects where I share code is that having shared standards is important. If the rest of the team uses Hungarian, learn that variant and use it. If you're starting a new project, figure out your coding standards up front. It's worth the time to remove the hundreds of little mental speed bumps that will otherwise make code review more difficult.

Mike Gunderloy
Thursday, November 01, 2001

>Microsoft programmers got so used to hungarian they >evangelized it for Visual Basic programming, where it is >much less important and useful.

Well, now that we have both VB and VBScript, I'm not sure what VB means anymore, but if you're talking about BASIC in general, I strongly disagree.

Because BASIC is a weakly typed language, and you can do implicit conversions between almost any types, I find it very helpful to use a variable prefix (and explicit type conversions, e.g. CInt) to keep track of my types.

The problem we're having (not using VB though) is that not everybody uses the same dialect of Hungarian, which results in some pretty ugly, inconsistent variable names. There is no "code master" at our company who oversees the application of this notation.

Sometimes I find Hungarian a bit overkill. In modern languages with stronger type checking, I find it mostly useful (like someone else said) to determine the scope of an identifier.

Johannes Bjerregaard
Thursday, November 01, 2001

Having just written a bunch of coding standards at my current gig, I pushed Hungarian notation - not because I wanted to, but it's the standard in the rest of the company.

The rule I've followed is to keep the conventions simple - TCL, for example, really only has a few types (actually, it's nearly typeless, since most specialised types are just magic strings).  The worst examples of Hungarian I saw were for VB - I'm sorry, but it does not make code more readable to have hundreds of strings to prepend, and the only real benefit I can see in Hungarian is to make maintenance marginally easier ("why am I getting a stack trace.... ahh, this variable was supposed to be a number, not a list!").

Rodger Donaldson
Thursday, November 01, 2001

I don't like it. In my opinion, in general, it shouldn't be necessary. I mean by this that, if you have a function so long that you can't see the declaration, you have a problem.



The biggest thing it comes down to: I just don't like it. It has all the visual appeal of..... something really ugly, like a spork or something. I admit it's mainly unbased prejudice, but I've always found easy to understand code to be easy to understand. And I can imagine code still can be obfuscated with hungarian notation.

Mike Swieton
Thursday, November 01, 2001

I think type notations were probably more important back when everyone was using plain C, so you had to worry about whether "filename" was a const char*, char* from malloc, char[256] on the stack, etc. Nowadays we hopefully have things like fully-encapsulated CString/std::string/auto_ptr<string>/etc, so this is no longer an issue. The compiler should be able to catch any misuses.

That said, there's probably still a place for typed notations in weakly-typed languages like Python... (Boy I wish it had some (optional) compile-time type checking...)

Dan Maas
Friday, November 02, 2001

I agree with Mike Swieton; I don't much care for HN either.  OTOH, I tend to mimic its themes to some extent...

I program primarily in Java nowadays, after doing C for many years.  I developed this habit of appending a little token to some variable names to denote something.  So arrays would be named pArr, or strArr, and so on.  The system I used would end up pretty precise, too.  I wouldn't merely name a variable trueAnomF for "true anomaly-float"; I'd name it trueAnomRad for "true anomaly in radians".  This is a BIG deal if you're having to deal with angle measures in both radians and degrees, as you might guess, and you can probably see how it goes one step further in the spirit of HN.

Some variables never get affixes.  i in a for-loop is always i.  There's never any misunderstanding for me; that what i is always used for.  Likewise for j, except that j's only used in a for-loop inside an i-loop.

This habit of mine carried over to Java.  Not as useful there.  As Dan says, it's most handy when your language is weakly-typed.  But the radians/degrees issue is still there.  In general, I see HN as a way of compensating for the semantic deficiency of a language.  It allows a programmer to catch more errors before compile-time rather than after.  An even better method for catching such bugs is to switch to OOP.  :-)

There is some great (though brief) discussion of the ups and downs of HN here:

http://ootips.org/hungarian-notation.html

(I hope URLs display correctly in this forum...)

Paul Brinkley
Friday, November 02, 2001

Anything that makes code easier to understand has got to be a good thing. I'm just not sure that hungarian notation is one of them. If you give variables sensible names like 'user_name' that allow you to quickly know what something is and what you might be using it for, then that's great.

If I give a variable a self-descriptive name then I know both what it is and what it does. And when someone else looks at my code, they'll have a better understanding of what is does also (I hope).

But changing intFoo to lngFoo all over the place? If I had to do that sort of thing I'd be considering a career in watching paint dry instead.

That's the trouble with religious arguments, there is no definitive answer.

John C
Friday, November 02, 2001

I appreciate your comments Paul... Actually the radians vs degrees thing might be solvable by defining them to be different types. (they are different units after all; adding a radians angle and a degrees angle, without converting either, is just as meaningless as adding a string and a file handle =). You'd have to write wrappers for the functions you use to work with angles, and there might be other problems with this approach, but I think the whole reason we have flexible, strongly-typed languages like C++ is so we can get the compiler to warn us about misuse of variables.

Dan Maas
Friday, November 02, 2001

The thing that put me off hungarian was that in a natural language like English the context of the word is enough to determine its type.

So when someone says "I like bananas", there's no confusion about what is the pronoun verb and noun. Similarly if you know a programming language you should be able to code it so that there's no confusion about types. eg in vbscript.

fullname = firstname & " " & lastname

Matthew Lock
Saturday, November 03, 2001

Concerning the degrees vs. radians issue:
It is best not to make them different types, but to
make *one* type Angle. Make all calculations with this
type Angle.

Then make another type, something like an AngleFormatter,
which handles the presentation of an Angle in a special format, e.g. rads, degrees, parts of pi or whatever you need. Use this only for I/O, not for calculations.

Or would you also like to
have different types for meters, centimeters, kilometers, miles, sea miles? They are all just distances.

Andreas Wicker
Saturday, November 03, 2001

If you are programming in assembly - hungarian notation makes some sense.
Otherwise it providese only harm    

Aleksey
Tuesday, November 06, 2001

Ah, I see the trolls are finally discovering this board. Pity.

Mike Gunderloy
Tuesday, November 06, 2001

What makes you say that, Mike?  Aleksey's message?  If so, I'm getting a strong impression that English is not his first language, and so he's only posting his main point, but can't easily explain it in-depth.  In which case, Alexsey, I hope you'll try a followup and flesh out what you mean.

I'm aware of the conclusions I'm jumping to here, and I'm aware that I could be quite mistaken.  If so, I apologize in advance.  I'm trying extend as much benefit of the doubt as I can here, so please be kind.  :-)

Paul Brinkley
Wednesday, November 07, 2001

I think the specifics of the notation are less important than the fact that you have a standard.  Maybe you want to use Hungarian in your private code but not in your public members.  Whatever...so long as it's documented and your team agrees you'll be OK.

Actually, I've found the mere exercise of getting your key people together and coming up with a standard is beneficial.  It allows you to practice consensus building without jeopardizing project artifacts.  This practice comes in handy when it's time to decide on something really important, like design.

Brent Rockwood
Thursday, November 08, 2001

Having variables named "intFoo" and "lngFoo" are missing the point of what Hungarian was supposed to do.

The wart at the beginning is supposed to provide some extra information - what does this variable actually do? Is it a number of Foos? Then it should be nFoo, not intFoo. Also, note that it doesn't matter if the type changes to long, since the usage of the variable doesn't change. The post above talking about the Deg vs Rad affixes does get it - that's exactly the kind of information Hungarian is supposed to portray.

That being said - Microsoft has been Hungarian's worst enemy, with it's ton of dwSomthingOrOther variables in the API calls. So what if it's a DWORD?

In my coding, I typically try not to use warts, with a couple of exceptions:

m_ prefix for member variables of classes.

If I'm doing COM code where I'm doing a lot of conversions (strings in particular have this problem in a COM interface) I'll use the same root and prefix a type onto the string, so I may have bstrFilename and lpszFilename just so I know that one is derived from the other, and what format they're in.

Chris Tavares
Thursday, November 15, 2001

I know I'm entering into this conversation very late, but I hope at least someone is still around to read this...

As for Hungarian Notation, I typically tend to prefer the guidelines of the last poster ('m_' prefix for instance members, 'lpsz' and 'bstr' prefixes where necessary, etc...), but I have once major question/concern which noone has brought up:

What about naming conventions for UI controls?  Say for example a textbox (either in an DHTML form or in MFC/VB/WinForms) for editing a user's name?

In the past I used to favor "txtName", but now I'm starting to wonder if "name" would be sufficient?  I've seen "nameBox" ("Name" + "TextBox"), "nameTextBox", and many others. 

What are your opinions on naming conventions for UI elements? 

Eric Kinateder (oh... neat font!)
Tuesday, November 20, 2001

I have gained my own experience with Hungarian notation in the last three years when working as a full time programmer (mostly C++).  I have been taught (and I was teaching later) that identifiers must be meaningful, chosen very carefully.  The more complex the project is and the more people is involved, the more important it is.

Hungarian notation is about attaching the identifier some special meaning via careful prefixing.  What is good on this idea, in my opinion, is to use prefix as a clearly visible part of the identifier to add some information.  But--as others already said--this is not necessary in the languages as C++.  In other words, some languages do not allow type identifiers to be equal to variable identifiers.  Here the prefixing helps you to choose the name.

All the questions about Hungarian notation are related to "how it can help" and "what are the bad consequences if I use it".  You should listen to the voice of those, who worked as developers in teams, and who have personal experience with the Hungarian notation. (I probably am not the one ;-)

One should always follow the team rules.  If it was decided that the team will use some flavour of the Hungarian notation, you should keep the rules -- until the team comes to another decision.

If you are the one who can set the rules, you should reexamine the reasons that lead to the rules from time to time.  Many people already asked the questions about Hungarian notation, many discussed the pros and cons.  Have a look at the following articles that I personally found useful:

    "Ottinger's Rules for Variable and Class Naming"
    http://www.objectmentor.com/publications/naming.htm

    "Conversations: Hungarian wartHogs"
    by Jim Hyslop and Herb Sutter
    http://www.cuj.com/experts/1911/hyslop.htm

I believe, that identifiers should be much more abstract-meaning related than the type-used related. 

I have personally decided to always use 'p' for prefixing pointers (in C++), because they are mentally different objects than the objects that they point to.  The second rule that I follow is to use 'm_' prefix for data members of the object (also for member objects, but *never* for methods, i.e. member functions).  This is because it help me to choose the name of the related method arguments and the local variables.

I admit that the 'm_' prefix was influenced by Microsoft, but I still think that using 'm_variable' is more visible than '_variable' (which is not recommended by some people because of the leading underscore) or 'variable_' (which is recomended by those who do not recommend the '_variable').  In the same time, I try to keep those variables private or at least protected.

As Matthew Lock wrote in the initial message...

    "All of a sudden hundreds of lines of code had prefixes
    that need to be changed from intFoo to lngFoo."

... this is one of the reasons used against Hungarian notation.  It is also discussed in the above mentioned articles.  Even the sophisticated search and replace features of your editor do not make any difference here.  Matthew would probably have the right to say that something was wrong with the code.

I was used to use the 's' prefix for std::string variables -- until my sId (the identification of whatever) became integers.  The prefix here said more than necessary.  The purpose of the variable to "identify" is the important fact here, not its type (in C++).

And the final remark.  Programmers are still human beings, not the machines.  They need to think in abstractions.  They do not need to keep extremely syntacticaly precise rules for identifiers to understand and manage the problem.  Being the programmer, enjoy the ability to decide obvious things that machines cannot do without precise syntax.  Being too precise also means being less abstract.  Being too precise makes the abstract thinking more difficult.

Petr Prikryl
Wednesday, November 21, 2001

I'm sorry to say, given my admiration for Joel and agreement with almost everything he says, that the use of Hungarian notation at Fog Creek would make it impossible for me to work there. It's kind of an emotional thing for me. I work with my own code so much that I need to control how it looks, and any function that gets long enough to need Hungarian to clarify it can be clarified in other ways, usually by breaking it up.

And I have put my money where my rather arrogant mouth is. Three years ago I turned down a lucrative contract job over this issue. I wanted to be treated as a professional who could decide his own notation. In that I am at one with Joel; at least he gets to decide, because he is the boss. I also like to decide for myself.

When I try to influence people on their notation and naming conventions I say:

* don't be afraid to use one-letter variable names in very short functions

* don't be afraid to use long variable names made from descriptive phrases if it's hard to understand what a variable is for

* in other words, decide on a case-by-case basis, and try to make everything as clear as possible

Everybody who has worked with my code - there are absolutely no exceptions I can think of - has said that they find it clear and easy to understand and modify. I must stress that I am most definitely not a loner who can do what he damned well pleases because no-one ever sees his code. On the contrary, I write as a member of two different teams, and we frequently fix each others' bugs.

I have been influenced to some extent by Donald Knuth, who is the best writer of comments I know, and one of the clearest programmers; although some of his names are a little whimsical for my taste, like 'noad' for a special type of node. But I don't go for the WEB system, if that's not a contradiction.

Graham Asher
Wednesday, November 21, 2001

Consistency is more helpful than conventions when naming variables.  Not that they are mutually exclusive, just that if you choose one then you ought to stick to it.

Edward Guiness
Friday, October 10, 2003

*  Recent Topics

*  Fog Creek Home