|
Mike Winiberg wrote: For the avoidance of doubt, these were not functions created by me! 8)
Thought as much, your post made that pretty obvious.
Mike Winiberg wrote: if the language isn't type-safe , then no amount of attaching prefixes etc is going to prevent some library assigning a string to the integer variable you just passed it silently and hence subtly altering the results etc.
I beg to disagree. Prefixes or suffixes can be rather helpful in spotting semantic errors in places where no amount of type safety can prevent them. Consider this example:
class Box {
public:
double height();
} box;
double size = box.height();
This is perfectly fine with regards to the types being used, and there is no apparent reason to use different types. But what if the box is defined in meters, and the size you need expects millimeters? The code above will not so much as hint at a potential problem!
Now look at this code:
class Box {
public:
double height_m();
} box;
double size_mm = box.height_m();
The use of appropriate suffixes makes the error imediately obvious, without the help of comments.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
I don't disagree with you, or the use of helpful hints like you suggest. But whilst your suggestion (and indeed hungarian notation etc in general) provides useful prompts and hints to the coder it doesn't address type safety and in fact can be counterproductive in non typesafe languages:
I hit this kind of thing a lot in an elderly VBA codebase that I maintain and develop for a client. GUIDs can be represented (validly) as either a string (in 3 different formats FFS!) or as a BYTE array. When reading a GUID from SQL Server into a table and thence into a form and onwards into code you usually get a string, but sometimes (I presume depending on the temperature of Bill Gates' shower at the time the code runs) you get a BYTE ARRAY - all of these can appear in the variable you assign them to if it's a Variant, and you can only find out which one you get by testing the type of the variable after assignment, or when an exception is raised on use! However, if you are attempting to assign the GUID to a string and it arrives as a BYTE array it doesn't cause an exception, instead you silently get a GUID consisting of '??????' 8)
I have spent many many hours tracking down strange bugs caused by this behaviour.
If (as I have discovered in code I inherited) errors have been disabled so that (unless the error is actually fatal) code continues with the statement after the one where an error occurs, you are falling down a rabbit hole with no bottom!
Note that although you may get a BYTE array GUID, this cannot be assigned to a GUID column in a table, so you have to convert it to a suitably formatted string (and the formatting acceptable depends on whether the table is local or on the SQL server).
Working on code like this when it is full of incredibly long-winded, supposedly 'typed' variable and function names is just adding insult to injury! 8)
|
|
|
|
|
I know what you mean. I've seen my share of legacy garbage. And it doesn't stop in front of the big names. I still remember one project where I tried to put a thin layer between our embedded application and embedded Windows (back then still called CE), in an attempt to port it to another embedded OS. I stopped when I realized just how full the Windows APIs were with inconsistencies, including a couple of obvious bugs (well they became obvious when I worked on it - they weren't obvious at all when you looked at the individual parts of the API in isolation )
Everybody makes mistakes, and the older the systems are, the more mistakes you'll find. That's just the way things are, and my own code is no exception.
That doesn't invalidate my statement though: if used in the way I presented above, even if used inconsistently, it will increase the likelyhood of discovering semantic errors.
That said, I wouldn't use hungarian notation for any of the examples you brought up: I agree with you that in those cases it served no meaningful purpose.
I've found the article that was at the back of my mind all the time when posting here: Making Wrong Code Look Wrong – Joel on Software[^] I really like how Joel explains the do's and don'ts of hungarian notation, and how to use it correctly.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
Thanks for that link - I've read a few of his articles in the past and found them helpful.
So much to read - so little time!
8)
|
|
|
|
|
And having read the paper - I once again agree with what he says!
I was a fervent adopter of C++ in its early days, but as the language developed and got harder and harder both to use effectively and read I gave up using it. (The fiasco of manipulators between versions 1,2 and 3 didn't help either!) (Neither did a commercially produced database library 'accidentally' passing parameters by value and not by reference - as per the documentation - which caused an amazing array of problems until I tracked down just what was going on! 8) )
Joel's example of what appears to be a simple multiplication is one of my pet peeves about C++ and the fact that in a complex class you can end up with what are effectively class globals that can be accidentally hidden by local variables if you are not very careful is another. Once it became harder to use C++ effectively than it was to solve the programming problems I was using it for, I gave up.
As for exceptions, tracing back through 12 layers of exception handling to find out what is causing it is a nightmare - like he says useful for stuff that isn't mission critical, but a bottomless pit in difficult stuff.
|
|
|
|
|
grralph1 wrote: I love and respect Sander. Love you too man #nohomo #bromance 😘
|
|
|
|
|
Haha
"Rock journalism is people who can't write interviewing people who can't talk for people who can't read." Frank Zappa 1980
|
|
|
|
|
I did respond to the previously mentioned post, as one who does use silly names.
Perhaps a new topic, but I also leave silly (funny?) comments in the code for whomever receives the punishment of having to fix modify my code later.
if (...) {
-
-
} else {
}
Nothing succeeds like a budgie without teeth.
|
|
|
|
|
Yes I do remember your bravery and your pride.
I do like the idea of silly or humorous comments.
You only live once.
And it may cheer up someone who is reworking your work.
Weirdly though I hardly ever do it.
(Probably because no one else usually ever sees my source code.)
For the past 10 years I have been commenting for others. Prior to that it was only ever for me.
Thinking about this whole thing I have discovered that I appear to be most creative (not silly) when making up names for functions.
Less so for subs and variables.
However I recently noticed that in some legacy code that I had a public boolean variable called TheWhiteZone. The comment said "The white zone is for loading and unloading only".
This was exactly what the Var was indicating, loaded or not, and it wasn't aloud to park there. No Way.
"Rock journalism is people who can't write interviewing people who can't talk for people who can't read." Frank Zappa 1980
|
|
|
|
|
Indeed. I still remember that, when thinking how to properly initialize a boolean, rather than deciding whether to initialize it with true or false, I literally did initialize it with true||false
But that's decades ago, and I don't recall having done something silly as that ever since.
Although... I once caught a run time error in my code that I was convinced could never happen. Consequently, the error message stated something along the lines of "this should never happen - please contact {my name}". The client I delivered this to did have a laugh, but I was still happy to hear that it was caught in acceptance test and never went out to the real clients...
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
I use "result" or "response" when it is really a throw away variable for debugging purposes. Using "ewww" or "blurpp" is crossing the line. We are working, not joking with friends. Even if it's a personal project, bad habits get carried to other things.
|
|
|
|
|
Agree.
"Rock journalism is people who can't write interviewing people who can't talk for people who can't read." Frank Zappa 1980
|
|
|
|
|
I have used and will continue to use "temp" for a temporary variable that lives for one or two lines of code.
|
|
|
|
|
I always use something meaningful, even if it is a throwaway variable. I work hard to make my code readable and think of whether the name will help or hinder me six months from now. I have worked in way too much legacy code that took forever to figure out and understand maintenance is where the bulk of programming time gets spent. (much to my dismay!)
|
|
|
|
|
I learned from this series of posts to utilize "str" for strings. I never liked using "string" since it conflicts w/ std::string. I always use "using namespace std;"
I favor descriptive names however I would rewrite doubleCalculateOffsetForWaveFunction(intScaleFactorForWaveFunction,floatWaveFunctionSeedValue)
as
Offset_forWaveFunction(scale_factor, seed_value)
I don't believe in Hungarian notation as it is merely another source of error and of course the return value is already documented. "Calculate" is redundant since we know that's what functions do. I find it helpful to distinguish prepositions in the name. "ForWaveFunction" is not needed since the variable is in context. If this method was of a class WaveFunction then all that would be needed would be Offset(scale_factor, seed_value). My local variables are always lower case. Capitals I reserve for global or public objects.
I am fascinated by naming notation conventions. I like the notation to say something about the method and variable e.g. to distinguish public methods from private e.g. camel for public and snake for private though I am conflicted as I like snake as it is easy on the eyes with no capital letters shouting at me though I am currently utilizing all capitals for statics and terminate all lambdas with "_LAMBDA". I am eager to learn of other's techniques and preferences. - Cheerio
modified 23-Apr-21 11:16am.
|
|
|
|
|
Thanks for that it is very interesting.
Quote: doubleCalculateOffsetForWaveFunction(intScaleFactorForWaveFunction,floatWaveFunctionSeedValue)
Gee.
I can read your rewrite easily.
The original is like a the name for a Welsh town and the only person who could read that would be the OriginalGriff.
I have never used ALLCAPS for anything. No reason, just never even thought about it. Therefore no titleCASE case either.
I usually use camelCase now but used to use CamelCase. I sometimes but rarely use snake_case or a cross between it and one of the camel styles just for some emphasis.
For Public variables I always distinguish these with a g prefix. Like gWaveVal. The g indicates Global.
It is fascinating to hear what other peoples preferences are and also the reasons for their preference.
Thx
"Rock journalism is people who can't write interviewing people who can't talk for people who can't read." Frank Zappa 1980
|
|
|
|
|
I once came across a function whose purpose was to send a message to the Sales And Marketing application. The developer had amusingly but appropriately named the function TelegramSAM. Unfortunately, they had then got a little carried away:
The author was listed as M. Bolan
The variables were named "jungle", "faced", "jake", "make", "no" and "mistake".
|
|
|
|
|
This made me laugh.
What a great name for the function.
Almost the perfect name but in retro case.
It may fly completely over the head of younger developers though.
I like the idea of having a theme though.
However easy to get carried away.
"Rock journalism is people who can't write interviewing people who can't talk for people who can't read." Frank Zappa 1980
|
|
|
|
|
Hands down the 3 hardest problems in programming:
-naming stuff
-off-by-1-errors
For throwaways, I usually pick my repertoire of Result (for holding something that'll get returned) and Scrap (generic temporary).
For stuff like responses from dialog boxes, I either take my old-and-tried Scrap, or give it some meaningful name like "SerialNo" when the user is prompted for a serial.
|
|
|
|
|
Never heard of Scrap before so this is a new one for me.
I like naming stuff though and find this the easiest part.
Mind you have regretted some of my names.
"Rock journalism is people who can't write interviewing people who can't talk for people who can't read." Frank Zappa 1980
|
|
|
|
|
Some people have called my code idiosyncratic.
i , j , k for loop indices with scope inside the for loop.
rc for any numerical function return code with a small scope.
val for many kinds of value, as a formal argument name.
that for the argument of a copy constructor.
My input variables tend to have real names.
I mostly store results in variables instead of using the rvalue result because it's typical that I have to test them more than once.
|
|
|
|
|
Short and sweet is OK.
I detest super long naming. I am Lazy.
I will usually use i, j and k for loops but I also use n.
Preference order is i, n, j and then k.
I have no idea of why n became the second choice.
But it sort of just makes sense, as we can use it and it is a number.
"Rock journalism is people who can't write interviewing people who can't talk for people who can't read." Frank Zappa 1980
|
|
|
|
|
For decades I too used i,j,k for loops, but over the last years I increasingly switched to more telling names, so I wouldn't need to constantly check and doublecheck whether or not I'm referencing the right index within a triply nested loop. It's much easier to accidentally use "i" and "j" incorrectly than "row" and "column"!
This change of mind was caused mainly by having to read so many nested loop codes and constantly stumbling over the problem that code containing such nested loops would often do this not just once, but several times, but not always use the same index variables for the same index
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
I'll admit having switched more recently to row and col instead of i and j for some loops. I have to say that a triply nested loop is very uncommon in my experience, except for performance testing.
Gotos are a thing I don't understand. I haven't written a goto in 20 years. I just don't need them. Gotos are for people who don't understand C++ well enough.
|
|
|
|
|
Does Nicola Sturgeon[^] like like a younger version of Angela Merkel[^].
Maybe it's a Lady-Prime-Minister thing . . . or a cloning experiment gone wrong?
Ravings en masse^ |
---|
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein | "If you are searching for perfection in others, then you seek disappointment. If you seek perfection in yourself, then you will find failure." - Balboos HaGadol Mar 2010 |
|
|
|
|