![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 5-6-2010 10:25, Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> I think the same goes for putting "m" or "g" or whatever in for member or
>> global variables, etc.
>
> Why? When I started using those, my own code became much easier to
> understand to me months later. When I have code along the lines of:
>
> void Foo::doSomething()
> {
> mCounter += someValue;
> }
>
> or:
>
> void Foo::doSomething()
> {
> gCounter += someValue;
> }
>
> as opposed to:
>
> void Foo::doSomething()
> {
> counter += someValue;
> }
>
> the first two are much clearer than the third one. The third one doesn't
> make it clear at all where 'counter' might be defined, while in the first
> example it's clear that it's a member variable of the Foo class, and in
> the second one it's clear that it's not. In the third one it could be
> anything.
>
The objection is not to hungarian notation per se*. It is about using it
wrongly. Like any other method of (in-line) documentation, if it does
not match the source it is worse than no documentation at all.
*) though there is the danger that using it without IDE support to
enforce the correct use, will almost certainly lead to mismatches.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
andrel <byt### [at] gmail com> wrote:
> The objection is not to hungarian notation per se*. It is about using it
> wrongly.
That kind of complaint seems kind of moot. Of course if you use any naming
convention wrongly, the code becomes crap. If I do this:
int multiply(int x, int y)
{
return x + y;
}
then that code is crap, of course. It uses the wrong name for what the
function is doing.
Why object about wrong usage of hungarian notation in particular?
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 5-6-2010 16:24, Warp wrote:
> andrel <byt### [at] gmail com> wrote:
>> The objection is not to hungarian notation per se*. It is about using it
>> wrongly.
>
> That kind of complaint seems kind of moot. Of course if you use any naming
> convention wrongly, the code becomes crap. If I do this:
>
> int multiply(int x, int y)
> {
> return x + y;
> }
>
> then that code is crap, of course. It uses the wrong name for what the
> function is doing.
>
> Why object about wrong usage of hungarian notation in particular?
Darren seems to have found a nice collection of them that made his life
a bit less enjoyable.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Why object about wrong usage of hungarian notation in particular?
Because, as I said in the first post, the easiest way to maintain the
hungarian notation correctly is to use an IDE sophisticated enough you don't
need hungarian notation to start with.
It's the same reason people prefer "self-documenting code" over "comments".
And the hungarian notation isn't generally useful enough (especially in
something like C) to warrant going thru the code base to fix it by hand when
you change a declaration.
To be fair, this is the first time I've seen this happen so blatently, but
it's an excellent reason to avoid it in the future. :-)
--
Darren New, San Diego CA, USA (PST)
Eiffel - The language that lets you specify exactly
that the code does what you think it does, even if
it doesn't do what you wanted.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> I think the same goes for putting "m" or "g" or whatever in for member or
>> global variables, etc.
>
> Why? When I started using those, my own code became much easier to
> understand to me months later.
For the same reason. When you move it from being a member variable to a
function argument, or from a private member variable to a protected member
variable or a public member variable, you have to go and find and rename
them. And most of the time, it's visual noise.
I far, far prefer taking the 10 seconds at the start to come up with an
unambiguous name that is clear how global the variable is.
Maybe prefixing something with "g" to mean global (altho "s" to be static
might be better?;-) makes some sense, if your program has maybe two or three
actual globals. But for member variables vs arguments vs locals? No, that's
all right in front of you.
And "mCounter" is a member variable of... what class? I have
GameComponent -> DrawableGameComponent -> Boll -> StackableBoll ->
StackableScreen -> UIScreen -> MenuScreen -> OptionScreen -> PlayOptionScreen.
Where in that chain would something as poorly named as "mCounter" be found? :-)
For that matter, where in that chain would you find the static/global
"NextDrawAction"? (Hint, if you just think about what those names might be,
(and knowing that "Boll" is my name for what MVC calls "Controller") there's
really only two likely answers.)
> the first two are much clearer than the third one. The third one doesn't
> make it clear at all where 'counter' might be defined, while in the first
> example it's clear that it's a member variable of the Foo class,
Is it? Or is it a member variable of a base class of the Foo class?
Why would I do that, when I can hover the mouse over the name and have it
come up and say "int Bar::Counter instance variable"? Or click "Go to
definition" to change the type?
Anyway, I'm not saying it's necessarily bad. For one thing, C doesn't let
you invent your own scopes (static, global, member,auto, etc) etc, and
people don't encode the visibility (public, protected, etc) in those names,
so the likelihood of having to change from a function argument to a member
variable, or from a global to an auto is very low.
The other problem with the hungarian stuff is that people will typedef
things, so you have code like
DRM_RESULT result = DO_SOME_DRM_CRAP(pszName, i32Size, ...)
Why does "result" not get a hungarian flag? What flag would you put there?
The whole point of typedeffing DRM_RESULT is to abstract away the type.
As soon as you put hungarian on your variables, you've eliminated the
benefit of typedefs to control the type, which is a far better way of doing it.
--
Darren New, San Diego CA, USA (PST)
Eiffel - The language that lets you specify exactly
that the code does what you think it does, even if
it doesn't do what you wanted.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> I think the same goes for putting "m" or "g" or whatever in for member or
>> global variables, etc.
>
> Why? When I started using those, my own code became much easier to
> understand to me months later. When I have code along the lines of:
>
> void Foo::doSomething()
> {
> mCounter += someValue;
> }
Oh, also, I'd write this as
this.counter += someValue;
or
Foo::Counter += someValue;
if I thought it needed disambiguation at a particular point.
I often see people do
void SetStuff(int xxx, int yyy, char* zzz)
{
mXxx = xxx;
mYyy = yyy;
mZzz = zzz;
}
where I would either do
this.xxx =xxx;
or I'd give the arguments different names
void SetStuff(int newXxx, int newYyy)
{
xxx = newXxx;
yyy = newYyy;
}
I suggested that to someone who was in the habit of putting m_ and g_ and
such on the fronts of variables, and he started naming every argument with
the word "new" on the front. I don't think he got what I was saying.
The point is to give every variable, even arguments and autos, a name that
indicates their function. Then I almost never need disambiguation.
--
Darren New, San Diego CA, USA (PST)
Eiffel - The language that lets you specify exactly
that the code does what you think it does, even if
it doesn't do what you wanted.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
> Warp wrote:
>> Why object about wrong usage of hungarian notation in particular?
>
> Because, as I said in the first post, the easiest way to maintain the
> hungarian notation correctly is to use an IDE sophisticated enough you
> don't need hungarian notation to start with.
My IDE uses different colors for global variables and member variables.
No need for m_ or g_ if the colors say enough :)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Nicolas Alvarez wrote:
> Darren New wrote:
>> Warp wrote:
>>> Why object about wrong usage of hungarian notation in particular?
>> Because, as I said in the first post, the easiest way to maintain the
>> hungarian notation correctly is to use an IDE sophisticated enough you
>> don't need hungarian notation to start with.
>
> My IDE uses different colors for global variables and member variables.
> No need for m_ or g_ if the colors say enough :)
Yep. That's what I'm saying. By the time your IDE is smart enough that
changing the scope of a variable isn't a tedious process of hunting down all
the references and changing the name, it's probably already recoloring
things so you can tell without the prefix. All the prefix is doing is
putting into ASCII the stuff the compiler already knows, and making you
manage it by hand. (Which is true of an awful lot of C coding, come to think
of it. :-)
--
Darren New, San Diego CA, USA (PST)
Eiffel - The language that lets you specify exactly
that the code does what you think it does, even if
it doesn't do what you wanted.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> For the same reason. When you move it from being a member variable to a
> function argument, or from a private member variable to a protected member
> variable or a public member variable, you have to go and find and rename
> them. And most of the time, it's visual noise.
I have never understood this obsession some people have with "visual
noise". It seems that anything that exist to make a name more unambiguous
is always classified as "useless visual noise".
Something is "visual noise" when it makes the code *harder* to read
because the "noise" is interfering with your capability of easily
understanding the code.
Something which in some situations might not convey any additional
information to you is not "visual noise". You might use the word "redundant"
in the sense that it conveys the same information in more than one way (at
least in the context in question), but that's completely different from
"noise", which is something that is disruptive and makes it more difficult
to get the actual information.
For example, you might have something like this:
int Point::getX() { return x; }
If you follow a naming pattern like being discussed here, it might instead
look like:
int Point::getX() { return mX; }
That's not "visual noise". It's not any harder to read and understand. You
might call it "redundant" (at least in this specific context, as the function
is so short and straightforward), and that's fine, but it's not "noise".
You could even have it like this:
int Point::getX() { return this->mX; }
Now it's doubly-redundant because the same information (ie. that 'mX' is
a member variable of Point) is basically told three times, but it's still
not "visual noise". It's still pretty clear, readable and easy to understand.
Where the 'm' prefixes start helping is when you have much more complicated
member functions which refer to local variables, function parameters, global
variables and member variables, especially when the names of the variables
are much less obvious.
> I far, far prefer taking the 10 seconds at the start to come up with an
> unambiguous name that is clear how global the variable is.
A common naming convention makes it much easier and unambiguous. Readers
don't have to start guessing if it's really a global variable or not.
> Maybe prefixing something with "g" to mean global (altho "s" to be static
> might be better?;-) makes some sense, if your program has maybe two or three
> actual globals. But for member variables vs arguments vs locals? No, that's
> all right in front of you.
There may be dozens of member variables, and the place where the member
variables are declared may be far away from the place where they are used
(they may even be in a completely different file). Seeing right away when
a variable is a member helps understanding such code.
> And "mCounter" is a member variable of... what class?
If it's written as-is, without any reference or qualification, it's rather
obviously a member of 'this' (or whatever your language might call it). If
it has a reference or qualification, then it's obviously a member of that
class. One ought to know which class' member function one is reading and
trying to understand.
And since member variables are never in the public or protected parts of
classes, there can be no ambiguous usage in a derived class member function.
(Yes, I know some people put them in the public part of their classes,
and then write derived classes which refer to them directly without any
qualifications. But these are the same people who would use hungarian
notation in the wrong way, etc. Bad code is always bad code.)
> I have
> GameComponent -> DrawableGameComponent -> Boll -> StackableBoll ->
> StackableScreen -> UIScreen -> MenuScreen -> OptionScreen -> PlayOptionScreen.
> Where in that chain would something as poorly named as "mCounter" be found? :-)
Which class' member function are you reading? If it's an unqualified use,
it's a member of that class. (If it isn't, then you have breached good OOP
guidelines.)
> For that matter, where in that chain would you find the static/global
> "NextDrawAction"?
Same thing as with member variables.
> > the first two are much clearer than the third one. The third one doesn't
> > make it clear at all where 'counter' might be defined, while in the first
> > example it's clear that it's a member variable of the Foo class,
> Is it? Or is it a member variable of a base class of the Foo class?
If it's a member variable of the base class, then the OO design is crappy.
No member variables in the public (or protected) interface.
> Why would I do that, when I can hover the mouse over the name and have it
> come up and say "int Bar::Counter instance variable"?
You don't realize that you are actually acknowleding the problem: You
acknowledge that if the name of the variable is so ambiguous, you need a
specialized program to tell you where it might be defined because otherwise
it's very difficult to know. Hence the name is ambiguous, and it's not
possible to easily know what it's referring to unless you do some research
or use some program to find the declaration.
"I just use an IDE to tell me" is not a solution. It's an acknowledgement
that there is a problem.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Something is "visual noise" when it makes the code *harder* to read
> because the "noise" is interfering with your capability of easily
> understanding the code.
Yep, you got it. I have to mentally edit out the qualifiers as I'm reading
the code to understand what it's trying to do.
>> I far, far prefer taking the 10 seconds at the start to come up with an
>> unambiguous name that is clear how global the variable is.
>
> A common naming convention makes it much easier and unambiguous. Readers
> don't have to start guessing if it's really a global variable or not.
I don't have to guess. I read the code.
> (they may even be in a completely different file).
You're probably doing it wrong if they're in a different file. Or you're
using a language that unnecessarily makes it necessary.
> And since member variables are never in the public or protected parts of
> classes, there can be no ambiguous usage in a derived class member function.
I'm confused. You're telling me a subclass shouldn't refer to a superclass's
members? Why is there even the concept of "protected" if a subclass
shouldn't refer to a superclass?
> (Yes, I know some people put them in the public part of their classes,
> and then write derived classes which refer to them directly without any
> qualifications. But these are the same people who would use hungarian
> notation in the wrong way, etc. Bad code is always bad code.)
When you're using properties, that's what you're *supposed* to do. That's
what they're for.
>
>> I have
>
>> GameComponent -> DrawableGameComponent -> Boll -> StackableBoll ->
>> StackableScreen -> UIScreen -> MenuScreen -> OptionScreen -> PlayOptionScreen.
>
>> Where in that chain would something as poorly named as "mCounter" be found? :-)
>
> Which class' member function are you reading? If it's an unqualified use,
> it's a member of that class. (If it isn't, then you have breached good OOP
> guidelines.)
Nonsense. The menu title is as much a member of the Options screen as it is
a member of a StandardMenuScreen as it is a member of a MenuScreen. How are
you supposed to set it if there's no accessibility from outside the class?
How does the Options screen set the MenuScreen's title if the Options screen
can't access any members?
>>> the first two are much clearer than the third one. The third one doesn't
>>> make it clear at all where 'counter' might be defined, while in the first
>>> example it's clear that it's a member variable of the Foo class,
>
>> Is it? Or is it a member variable of a base class of the Foo class?
>
> If it's a member variable of the base class, then the OO design is crappy.
> No member variables in the public (or protected) interface.
What makes you think it's a variable? I use properties for all that sort of
stuff. And why are variables in the public or protected interface bad design?
Don't confuse "C++ is easier when I do this" with "Good OOP design in general."
> "I just use an IDE to tell me" is not a solution. It's an acknowledgement
> that there is a problem.
I disagree. It's an acknowledgment that automated maintenance of that
information is more effective than manually maintaining it. It's no more a
problem to use the IDE to do that than it is to declare something "const" in
C++ instead of how you would handle it in C. It's using the tools we have to
reduce the burden on the programmer.
I'm generally against redundancy in programs. Adding things to the code that
the compiler can already provide for me is something that I find has always
been problematic.
If I had no IDE, no syntax coloring, and I was using a language where
figuring out what file something is declared in is a difficult and
time-consuming problem, I'd probably suck it up and start labeling variable
names with information about where I declared them. (Except, of course, in
my work job, they can't even get the type declarations consistent, let alone
something as unenforced as "m" and "g" flags. I'm lucky if I can guess which
processor the code runs on.)
--
Darren New, San Diego CA, USA (PST)
Eiffel - The language that lets you specify exactly
that the code does what you think it does, even if
it doesn't do what you wanted.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |