I know I'm in the minority in the Java world, but I prefer prefacing member variables in Java with m_.
I know there are myriad arguments about the editors being smart enough now to keep you from making the foo = foo instead of this.foo = foo mistake, but I just grew up on it and I like the clear obvious separation of 'that variable is a member variable' that m_ provides.
The rest of Hungarian notation though, never used it.
Oh and save the flames on m_, I've debated it to death, you aren't going to change my mind now. :)
I agree with you that the notation can be helpful. My problem, at least in the java world, is that prefixing is inconsistent across the board. Even within the same file you will find mixed notation.
I have to say that I have enjoyed ruby's variable conventions which are enforced by the language and seem to be much less abused.
No, agreed, and is my one reservation on continuing to use m_ in the Java world since there is such a huge body of code that has decided not to. (this was less of an issue 15 years ago when I started) If I'm working on an existing body of work I take on whatever convention is used of course.
As for mixed in a file, there's just no excuse for that. If you are the kind of religious zealot that thinks her rightness in bracketing style or naming convention is so superior that it should override the convention used in a file then you have no business coding on a team.
If I tag variables, it's usually as a suffix rather than a prefix. It just feels better to me that way. Two related variables can show up alphabetically near each other that way where the suffix tells them apart (often with a _ separating them: uname_clean).
For me anyway if I have so many member variables in a class or local variables in a method that it becomes a challenge to keep them straight then I will take that as an indication to refactor.
Each language has its own conventions. I try to use the dominant convention for each so as to be more readable to the community of developers in that language.
So, snake_case in Python and camelCase in JavaScript (with classes being initial Capital in both).
Consistency and familiarity would both be good reasons to me.
Non camelCase variables and CamelCase classes in Java for instance would really feel out of place to me, whereas using the same case conventions for some ruby code would feel equally 'wrong'.
When it comes to conventions like this, I don't think there's a substitute for having a "when in Rome" attitude.
If you're writing some greenfield code, Rome is all the other projects in your language of choice.
If you're adding some functionality to an existing piece of code, that existing piece of code is Rome.
It's always very painful if a codebase is not internally consistent.
I usually try to find some sort of dominant naming scheme to follow and clean up old code left and right, but yeah, sometimes starting anew can be the only sane thing to do.
But then again, I have no problem going into a badly formatted hunk of code and fixing it. I have, on occasion, reformatted entire source directories because the original sources were so terrible.
Ditto, with the exceptions of class names, projects not my own where I have to follow certain conventions, and in a Lisp-like languages. Dash beats underscore and I love question marks at the end of functions that return bools. I've also sucked long on the teat of dynamic type languages, so I've found that I care more about being able to decipher code's intent from reading it than what specific types are. For me, Python code is still more readable than C++ code no matter how many stylistic conventions on your C++ variables you make up.
I thought all these years that Hungarian's job wasn't to communicate the data type i.e. int vs float, but to convey things at a more semantic level - pixels vs em ( when not using a richer data type to encapsulate them )
If you ever need a semantic naming convention for closely related variables that are crucial to use correctly (encryptedCustomerInformation vs decryptedCustomerInformation), make up your own ad hoc.
Why is that? The only time I've ever seen 'Hungarian' notation cause maintenance problems is when a dev changed the type of a variable without adjusting the name accordingly. That's a problem with the developer, not the convention.
The problem as it appears is the abuse, not the notation itself!
Too long prefix? Keep it shorter!
Too hard to pronounce? Then don't pronounce, at least don't pronounce the prefix, pronounce it's name and (optionally) the long title that that prefix stands for!
Too vague? Include then a commented "dictionary" in the headers that clarifies things.
Getting out of date? This isn't actually a Hungarian Notation problem, that's a codding style problem. Choose then your prefixes more carefully (more generic maybe), to cover future changes!
It's just plain stupid to dismiss something because of your problems! Solve YOUR problems (naming, pronouncing, etc.), because these aren't gone simply by dismissing a notation.
I use some kind of Hungarian notation in which I do not describe the type of a variable in its name but instead its unit. Since I do a lot of medical image processing I have to deal with a lot of different coordinate system. For example, one is the "real world" which is measured in mm and one is the image as an array which unit is given in pixel. By appending _pix and _mm to variable you can see that some things are just wrong. For example
pos_x = curr_pos_x + diff_pos_x
is not clear, but from
pos_x_mm = curr_pos_x_mm + diff_pos_x_pix
it is clear that something is very wrong in this line.
edit: I just saw that this is basically what [1] is about.
If you are using C++, you can make the units (dimensionality) compile-time checked using templates. See: http://learningcppisfun.blogspot.com/2007/01/units-and-dimen... (that isn't where I came across it, but the code looks basically the same.) It's easy to add more dimensions for any units you care about (pixels for example).
Thanks, that looks very interesting! I wish I would have used this years ago, but (un)fortunately I switched over to Python (and some C for extensions).
The later statically typed languages like Haskell make it relatively easy to create a type which is internally stored as some base type, like an Integer, but at the type system level is treated as a distinct type. Thus one can not accidentally multiply a Pixel by a Millimeter when trying to compute an area on the screen, while under the hood pixels and millimeters are still just Ints (or whatever). "Real" Hungarian is a good hack for languages lacking that.
I think using hungarian prefixes for the language types in a statically typed language is absurd.
For semantic differences (eg Joel's absolute vs relative coordinates example) I think it's more reasonable, but I still dislike it as an idiosyncratic abbreviation. For example, why not just RelativeOffset vs relOffset. Or for locals, I prefer ruby style: relative_offset, though that's more of a nitpick.
I think well chosen names really limit the usefulness of abbreviated prefixes.
I don't quite follow -- in Joel's case, it's assumed that you're tracking the position of all sorts of things -- there isn't one variable that's the relative offset, but a whole host of them that you'd want to give particular semantic names. Prefixing them all with "relative_offset" would be unwieldy, so a concise, consistent prefix makes a lot of sense.
Google "lParam vs wParam". And yes, you're feeling lucky.
Long Version:
Sometimes what I'm suggesting is equal to unabbreviated Hungarian. But sometimes there's a nice semantic bonus, where from context it's clear what we're talking about.
For example, in a game you might have objects at some position that can move around in space, be organized in hierarchies, etc. So you're dealing with a lot of vectors. Sometimes these are vectors from the origin, sometimes vectors from one object to another, sometimes unit vectors.
Assume we're working in a language or library situation where we'd really prefer to just keep all these vectors the same type, say a vec3f type with 3 float members, xyz.
We could decide that hungarian notation would be a good way to avoid making mistakes due to interpreting a vector wrong. So we use the prefixes ov, rv, uv to indicate vectors from the world origin, vectors from one object to another, and unit vectors.
Imagine some actual typical variables we might have, say Position, Parent and SurfaceNormal.
Is ovPosition, rvParent, uvSurfaceNormal really superior?
In each of these cases, the semantic content of the hungarian prefix is redundant. Position vectors are always from origin. Parent vectors obviously relate one object to another. Surface normals are always going to be over the unit sphere. So it's not really adding any comprehension.
But it gets worse. Let's say that we implement some more complicated scene tree to our game, like to do articulated animation of a robot. Now our position vectors are actually relative vectors. If we were being hungarian, ovPosition would be a lie, so we have to change all instances. Which is great if we can just let Eclipse do it. But what if we've published a library or otherwise are committed to a name?
Oops.
This is one of the reasons why pseudo hungarian for parameter names in web services is a HORRIBLE idea.
The questions like this are the reason why your first job should be working on large scale very-well maintained projects and not some small startup.
By working on these kind of project you will understand that there is a clear need to have good nomenclature and naming standard for a project and modules which, in many cases, reassemble Hungarian notation (describing method's or variable's purpose, portability, performance implication, etc.).
I think the people railing against 'Hungarian' notation have never had to deal with BSTR, std::string, and TCHAR* all in the same function, along with a BOOL and a bool. I will happily name variables simply and according to their true meaning, but as soon as I start mixing in different variations of similar types, 'Hungarian' is my go-to convention.
36 comments
[ 5.3 ms ] story [ 79.8 ms ] threadI know there are myriad arguments about the editors being smart enough now to keep you from making the foo = foo instead of this.foo = foo mistake, but I just grew up on it and I like the clear obvious separation of 'that variable is a member variable' that m_ provides.
The rest of Hungarian notation though, never used it.
Oh and save the flames on m_, I've debated it to death, you aren't going to change my mind now. :)
I have to say that I have enjoyed ruby's variable conventions which are enforced by the language and seem to be much less abused.
As for mixed in a file, there's just no excuse for that. If you are the kind of religious zealot that thinks her rightness in bracketing style or naming convention is so superior that it should override the convention used in a file then you have no business coding on a team.
Although I don't agree with them :)
So, snake_case in Python and camelCase in JavaScript (with classes being initial Capital in both).
For identifier 'camelCase' use '驼写'
Non camelCase variables and CamelCase classes in Java for instance would really feel out of place to me, whereas using the same case conventions for some ruby code would feel equally 'wrong'.
When it comes to conventions like this, I don't think there's a substitute for having a "when in Rome" attitude. If you're writing some greenfield code, Rome is all the other projects in your language of choice. If you're adding some functionality to an existing piece of code, that existing piece of code is Rome.
Yeah, this is a good point. I come across as gung-ho in the parent but I have to admit I do submit to the "when in Rome" effect.
That said, if Rome is an absolute shambles, I might feel empowered to start anew ..
I usually try to find some sort of dominant naming scheme to follow and clean up old code left and right, but yeah, sometimes starting anew can be the only sane thing to do.
But then again, I have no problem going into a badly formatted hunk of code and fixing it. I have, on occasion, reformatted entire source directories because the original sources were so terrible.
(EDIT: Oops, I answered you before seeing it's on the accepted answer on the article)
2) It's ugly.
If you ever need a semantic naming convention for closely related variables that are crucial to use correctly (encryptedCustomerInformation vs decryptedCustomerInformation), make up your own ad hoc.
Why is that? The only time I've ever seen 'Hungarian' notation cause maintenance problems is when a dev changed the type of a variable without adjusting the name accordingly. That's a problem with the developer, not the convention.
It's ugly.
That's purely subjective.
It may be trouble to determine what the prefixes mean. To have no pattern at all, IMO is not at all an improvement.
edit: I just saw that this is basically what [1] is about.
[1] http://www.joelonsoftware.com/articles/Wrong.html
For semantic differences (eg Joel's absolute vs relative coordinates example) I think it's more reasonable, but I still dislike it as an idiosyncratic abbreviation. For example, why not just RelativeOffset vs relOffset. Or for locals, I prefer ruby style: relative_offset, though that's more of a nitpick.
I think well chosen names really limit the usefulness of abbreviated prefixes.
Google "lParam vs wParam". And yes, you're feeling lucky.
Long Version:
Sometimes what I'm suggesting is equal to unabbreviated Hungarian. But sometimes there's a nice semantic bonus, where from context it's clear what we're talking about.
For example, in a game you might have objects at some position that can move around in space, be organized in hierarchies, etc. So you're dealing with a lot of vectors. Sometimes these are vectors from the origin, sometimes vectors from one object to another, sometimes unit vectors.
Assume we're working in a language or library situation where we'd really prefer to just keep all these vectors the same type, say a vec3f type with 3 float members, xyz.
We could decide that hungarian notation would be a good way to avoid making mistakes due to interpreting a vector wrong. So we use the prefixes ov, rv, uv to indicate vectors from the world origin, vectors from one object to another, and unit vectors.
Imagine some actual typical variables we might have, say Position, Parent and SurfaceNormal.
Is ovPosition, rvParent, uvSurfaceNormal really superior?
In each of these cases, the semantic content of the hungarian prefix is redundant. Position vectors are always from origin. Parent vectors obviously relate one object to another. Surface normals are always going to be over the unit sphere. So it's not really adding any comprehension.
But it gets worse. Let's say that we implement some more complicated scene tree to our game, like to do articulated animation of a robot. Now our position vectors are actually relative vectors. If we were being hungarian, ovPosition would be a lie, so we have to change all instances. Which is great if we can just let Eclipse do it. But what if we've published a library or otherwise are committed to a name?
Oops.
This is one of the reasons why pseudo hungarian for parameter names in web services is a HORRIBLE idea.
By working on these kind of project you will understand that there is a clear need to have good nomenclature and naming standard for a project and modules which, in many cases, reassemble Hungarian notation (describing method's or variable's purpose, portability, performance implication, etc.).
2) less wrongness (when type has changed but the hungarian was not updated)
3) more readability and all that falls from that (although, this is an opinion and I'm sure others believe that hungarian is more readable)
4) better(faster to unique) tab completion
5) discovering the disease that hungarian was just a symptom of. That is a bad type system. There's only two good ones Strong and Duck.
Proly more but that's enough for me.