- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
So Hungarian Notation is a WTF these days?
There are good reason pro and contra, you can take it or leave it. But a WTF?
Admin
Admin
Only if you mimic Hungarion botation and don't get it right:)
Admin
Admin
It's usually a strong indicator of Cargo Cult Programming.
Admin
Yes. Hungarian Notation is, and always has been, a WTF. If you're using a strongly typed language, it means that you don't trust the compiler or aren't prepared to deal with compiler errors. If you're using a weakly typed language, it demonstrates that you're trying to enforce strong-typing-by-convention- which doesn't work. It provides a false sense of type safety ("the variable is named strFoo, it must hold a string" is a statement of hope, not reality).
In the name of being "self-documenting", it favors knowing what prefixes mean over knowing what the code does ("Oh, gStrFoo", it's a global, so I know to be careful about touching it. I don't know what or how this variable is used, but I know it's global! Self documenting!")
What makes Hungarian Notation TRWTF, however, is popular it was. This I will never understand. I remember when I was a little n00b programmer, and on my first job, I was taught Hungarian Notation. Even then, I demanded to know, "Why?" The answer always was, "It's the standard. Do it."
Admin
Call me old-fashion, but I like to know the type of my variable without hovering over it with my mouse. People act like it's the devil, it's just a preference (mostly, depending how you use it).
Userid = ...well it' a user id, I have no idea what goes in it, but it's a userid
guidUserID = it's a userid, and it holds a guid....
I still prefer the latter, you say you don't? Well that's fine too, but why keep hammering on it when it's just preference...
Admin
Admin
In C++, pointers are occasionally used. Pointers point to memory locations, in other words: are integers. Prefixing them with a "ptr" like ptrMeaningOfLifeComputationResult makes it clear that an address in memory is meant - if you use meaningOfLifeComputationResult, you could be tempted to expect 42 instead of something like 12ab45ff.
It also comes in handy to differentiate between variables representing the same data in different types. Consider: var strDateIn8DigitFormat = '20130418'; var intDateIn8DigitFormat = parseInt(strDateIn8DigitFormat);
But in something like strTextForLabelFirstName = 'Firstname' the "str" prefix is clearly superfluous and should be avoided.
Admin
"What makes Hungarian Notation TRWTF, however, is popular it was. This I will never understand."
There was a time when IDEs were not able to use colors to mark keywords and when it was not possible to display tooltips when you hovered over a variable name with the mouse. (There actually even was a time when people had to read code from printouts...)
But I agree that nowadays it is a WTF, because it only adds information that is supplied by the IDE and that can be faulty onace a data type is changed.
Admin
Integers of type char* and so on though ...
Admin
Well to be fair, at least the comment warned about the 'Complete'. It would have been more evil of the original coder to just leave the comment out and watch the fireworks when some future schmuck changed that text string....
Now that we know that 'Complete' may have side effects, we know to be gun-shy about touching ANY text string in that monstrosity... :-)
Yazeran
Plan: To go to Mars one day with a hammer.
Admin
I'm tempted to flex on my "hungarian is evil" for the special case of pointers, only because pointers require a very different syntax.
Tempted, but I won't. And the main reason that I won't, is that if the purpose and meaning of the variable isn't clear from its context, then your context is broken. Hungarian notation remains a way for unclear, difficult to read code to pretend that it's not unclear or difficult to read.
I recognize that the real world makes it difficult to write short methods, keep variables scoped to very brief and easy to understand blocks. Hungarian notation is a great way to make 300 line functions readable. But maybe the problem is that you shouldn't be writing 300 line functions.
The only time I ever have to check what type a property or parameter has is when I am using an API I don't know. Hungarian notation wouldn't help much, since knowing the type still doesn't help me understand the meaning. I'm gonna need the docs anyway.
Also, your example of representing the same data with different types would make me cry if I saw that in actual code. 90% of the time, the prefix is noise- I don't need the prefix to understand the type of the variable. So I ignore it- but now you're naming variables the exact same thing, except for the prefix. Suddenly, the prefix ceases to be handy documentation, and now it's a vital indicator as to which variable I should use for which thing. That's taking Hungarian Notation and making it actively evil.
Admin
And does that mean that the company owner, who currently stands trial for sub-prime breast implants, is a secret undercover agent?
Admin
(1) Some folks like to use the prefix as the whole name. They deserve to be stabbed repeatedly.
AHN, on the other hand, encodes useful information about what a variable is contaminated with rather than what its programming language type is. So for example, imagine a system where string variables might contain some sort of raw text, or they might contain some sort of XML-safe or HTML-encoded text, or they might contain SQL-cleansed text (whatever that means. We impose a reasonable rule that a variable contains a maximum of one sort of text, and mark it with the sort of ill the variable is contaminated with:
We also provide conversion functions: The variable name warts align with the function name warts so that a code reviewer will be able to see that the first one is OK (passes raw-contaminated text to a "from raw" function that returns XML-safe text that is stored in an XML-safe variable) but the second is not (passes raw-contaminated text to a "from XML-safe" function that returns raw text that is stored in an XML-safe variable - a definite no-no).It's at best a very mild WTF, because it suggests a lack of confidence in the quality of the code. One specific advantage it gives (up to a point) is that you can use automated methods to validate the use of the correct type of contamination.
Contextual notations such as "g" for globals, various prefixes or suffixes for member variables, and "p" for pointers are neither SHN nor AHN, and their use is debatable. I personally favour prefix "m_" as a notation for members in languages that don't require this. / self. / this-> to introduce their use. So Python doesn't get m_ prefixes because all member variables have to be accessed as self.thingy, but C++ does because you are allowed to just access m_thingy from a member function without saying this->m_thingy. I'm indifferent on the use of a "p" prefix for pointers, and generally opposed to global variables, whatever the naming convention.
Admin
vi certainly does not impart type information to the developer that easily...
Admin
Here's the thing: I never use the IDE to check the type of a variable. I generally just look at the code, because the variable declaration is someplace convenient, like a few lines above where I'm using it. Or the variable is named something that semantically implies its type. "DueDate" is how we say it in English. "dteDue" or "dteDueDate" is not.
Admin
Admin
Sorry, but in that language a bit of Hungarian Notation can be extremely helpful because the automatic type conversion can really mess things up for you.
Admin
Admin
(1) Strictly speaking, x86 was prone to segmentation until the rise of x64, but in 32-bit systems nobody actually uses the full segmentation capability of x86 for anything more than allowing threads to access their Thread Control Blocks at a fixed location.
Even on systems where we don't have segments, and so don't have multi-part plain pointers, C++ pointer-to-member-function variables are, in general, not single integer-like values. They are more or less compelled to be miniature structs containing some complicated information. Have a long, long think about how you would implement a pointer-to-member-function that can point effortlessly to either a virtual member function or a non-virtual one without having to have the compiler generate an endless series of trampoline function stubs in case someone wants to form the address of a member function, and to also support comparing such pointers accurately. It's non-trivial - there are solutions, but they have severe complications when you introduce amusement like conformant return values.
Admin
Nope, JavaScript is even worse when you use Hungarian notation, because you have no way to guarantee that the type in the variable is the type the Hungarian notation claims it is, and it's trivially easy to make a mistake which causes JavaScript to change the type of a piece of data into something you don't think it should be.
Just because somebody hands you a variable called "strFoo" doesn't mean it contains a string. I once inherited code that had a variable named "intProjectNumber". The variable held things like "QR-1554-PL".
If there are no compile-time type checks, all Hungarian notation does is add noise to your code and a false sense of security.
Admin
And, once again, the real WTF is Javascript.
Admin
Do Not Double the Killer Delete Select All Complete!
Admin
You misunderstand. You can't declare war like that - the compiler won't stand for it! You will get all kinds of errors and warnings...
Admin
Admin
Ah, the Hungarian Notation rants...
What I'm going to say below is for C++. In other languages, YMMV.
First of all, C++ has lots of lovely implicit type conversions. This goes to the point you can substitute the type of a variable with another one, and nobody notices. So if you embed type in a variable, you make it much more difficult to switch type later on.
Secondly, templates. As soon as both conversion operators and templates get in the game, trying embed a "type" into your variables makes you pretty much screwed.
Third, for those who say "but it helps me remember the type!". If you need to scroll more than 50 lines up or down to see the type of your variable, you're doing something wrong.
Also, to those who complain their IDE does not have the least amount of prediction available: stop using Notepad. Pretty much any other editor or IDE has builtin support or plugins for some form of autocompletion. (That includes Vim, by the way).
Next, if the encoding is not semantically important, don't encode it. Usually your logic isn't going to change a lot whether you have a value, a reference, a pointer, a const reference, a rvalue reference, or a smart pointer. Either that, or it's obvious from context (e.g. a copy or move constructor).
If it's so important to know that userId is actually a GUID, why not call it userGuid?
That being said, if multiple objects with the same type but different meanings exist in the same context, (e.g. escaped and unescaped strings), go ahead. It might be even more clear to write unescapedInput and escapedInput instead of something like usInput and esInput, though.
Admin
typedef Int bool; typedef Double int; typedef Bool double;
Int ptrString = true;
Where's your IDE tooltip now?
Admin
And to get back to the somewhat contrived example from earlier on - is: var todaysDate = '20130418'; var dateToday = parseInt(todaysDate, 10); so much better?
var foo1 = todaysDate + todaysDate; var foo2 = dateToday + dateToday; still gives you different results for foo1 and foo2 but now I have to deduct from the context which variable has which type everytime I need to use one of them.
Can't really see how that makes my life easier in larger projects.
Admin
Secondly,
places cursor on Int presses Ctrl+] (go to declaration) Oh, some wiseass decided to typedef bool as Int. presses Ctrl+T (go back)
Admin
I prefer camelToe notation.
Admin
Admin
Hm, that is a very good example. In that case hungarian notation would help, but to be honest: any kind of violence against that idiot who wrote that would be an even better solution.
Admin
Hm, that is a very good example. In that case hungarian notation would help, but to be honest: any kind of violence against that idiot who wrote that would be an even better solution.
Admin
I don't know what editor or OS you use, but mine have these nifty features called "split windows", "multiple windows", "toggle header/source" and "go to declaration". Quite handy!
Admin
It may be a "project code" to you, but to the business users, it's a "project number". Variable names should always map to the domain as easily as possible.
Were I building your contrived example, it would look more like this:
Now, I know the role of every value in the application. Knowing what it is for is far more valuable than knowing what it's type is. I really don't care about its type- I mean, if I did, I wouldn't be using JavaScript, would I? I need to know what the value is for. If I know that, I also know what it's type should be.
Admin
I dunno, I constantly refer back to the class definition, so I always have that file open (except when using IDEs that can autocomplete). How would Hungarian notation help me recall the exact naming of every member? If I've already used the member in a method, then I obviously knew what the type was when I used it- I can easily tell at a glance what the type is (if I've accessed it, I've either gotten its value or set its value- and I should know the type of the get/set target).
It seems like your main argument for using Hungarian notation is that it allows you to write code which will probably compile and may do what you want, without ever actually reading any of the code around it.
Admin
Do you really think you can print a pointer using %ll? Go away, you are living in a state of sin. On a typical 32-bit platform, it will hoover up 32 bits of assorted garbage along with the bits of the pointer. You probably meant %p, which is the standards-conformant way of formatting a pointer, and which takes care of all the varied oddities of your platform.
If you try to printf anything using format specifiers that don't match the types passed in, you are in for a surprise. On 16-bit platforms, int and long aren't the same size, so trying to match %d versus a long variable will go wrong. Some platforms have pointers that don't match the size of int, so printing an pointer with %d or %X will go wrong. And the behaviour of a program with this kind of mismatch is undefined, so running it on a DeathStation 9000 will cause millions of unwitting citizens to die in nuclear explosions. (All joking aside, if the idea of your code having undefined behaviour doesn't scare you ****less, there's something wrong with you.)
Clear?
Admin
Yes it's a WTF. There's no real reason to use it. If you need to indicate that a particular variable is a string, you probably need a better name for it in the first place.
strCustomerName is redundant. CustomerName should indicate that it's a string by virtue of being a name.
About the only place I don't mind seeing Hungarian Notation is in the UI, since txtFirstName seems better than FirstNameTextBox.
Admin
All the XXX in here is making me want to start pron mode and surf me some pron ...
Admin
i'M tRYING tO lEARN tO lOVE cAPSlOCK nOTATION.
Admin
I would love to use hungarian notation, but brainfuck does not have variable names.
Admin
Yes, it always was, although at one time I dare not speak out. I feel the same way about XML today (although I think the tide is finally changing).
Microsoft heavily promoted it, in all documentation, sample codes etc. If you were working for a Microsoft shop, you would almost certainly be using it.
Admin
Yes, the type information HN carries can be wrong, but people who do not clean up their code after changes that invalidate the type information inherent in a variable that adheres to HN will usually produce hard-to-maintain code even in an HN-free environment. Ternary bools like true/false/file_not_found in C++ or Javascript? Some people will be so lazy or so pressed by deadlines that they simply don't care.
And as an aside: postings about today's article seem rather rare so far... Hungarian Notation seems to hit a nerve or two :-)
Admin
In other words: for me, "integer" in that context meant "a number from N" and not the data type "int".
Admin
All the rants on hungarian notation .... I thought GOTO's where considered harmful
Admin
I was going to say something along these lines. Hungarian notation should ONLY be used in strong type languages. I think in most cases it is an unnecessary verbosity but I don't consider them a WTF. If you like the style I am totally okay working with your code and using it. I also recognize there certainly are cases where it makes reading and understanding faster; and also cases where it might reduce errors by calling attention to implicit type casts that are allowed but might have undesired consequences. It might lead you to questions like "I am dividing an integer by a float, do I also need to use something like floor or ceiling to get an appropriate value for what I am trying to implement?"
If you use it though make darn sure its correct. If you name something intFoo I expect foo to be an integer; not a double, float, char, unsigned, long, or string representation.
Admin
It was useful back when IDEs did not have tooltips.
Also, a primary purpose of such notation was to expand the possible range of variable names without having to worry about issues such as reserved words, etc. I am surprised that so many people never realised this.
Admin
Just because one type of wart might be useful in some circumstances doesn't validate the use of other types of warts or HN in general.
Admin
There's a lot of 'gstr'ings also being shown.