- There are few variables in the whole code block < 5.
- Amount of lines is < 25.
- Code is very functional in nature. ie. no a.getObj()
Sometimes I appreciate good variable names and sometimes I hate descriptive variable names. Short var names might be better where extra effort required to parse long names is not worth in terms of utility gained.
One example: variables are not meant to be used for long term just exist for next two lines....
i.e. filteredData = arr.filter(...) , noDateFilteredData = filteredData.filter(...), noNameDateFiltered = noDateFilteredData.filter(..)....
this would be easier to read when it's written like this
a = arr.filter(...), b = a.filter(...), filteredData = b.filter(...)
another situation...
data = arr.filter(n => n.flag === true);
// it's completely obvious what's happening here, n is iterable. calling it obj|arr|users|etc... doesn't add much value for this piece of code as is. you probably already know we are getting users. It's like not using pronouns "he"/"she" and just keep using first name: Mike wanted to come in because Mike had said that Mike needed to talk to Aniqa, Aniqa knows about the insurance stuff. Aniqa has worked in insurance....
There is inverse correlation between length of a variable name and the speed of understanding logic of the code. But smaller the name the more you need to remember what it is, and the longer it's carried over the more difficult it's to continue remembering it. So in situations where it doesn't need to be carried for a long time I prefer smaller names.
I'm sure of it from my experiences. I prefer short names generally when is less data massaging and more algorithmic in nature, because sometimes it's hard to name a var in a way that captures vague concept in algo, without making it downright misleading. i.e. i call something a sliding_window but then later don't use it as one. Reader would be like um... wait what??
TLDR: I guess correct name matters more and more, the farther you are from its declaration.
The strongest counter argument is that developers cannot be trusted to avoid building a house of cards if you let them use, even a single shortcut. And there is plenty of evidence, including my own experience, to back that up. But if you can prove you will re-factor when the time is right, it becomes a lot easier to make your case for brevity.
This should tell you something. Taking the time to name it nicely now costs almost nothing vs wasting your time trying to prove it can be refactored later and then doing that refactor later. Why? What are you getting out this? Taking 1 second to name it nicely vs the time it costs for everyone to listen to you "make a case for brevity", just please don't be that person. No one likes or respects that person more even when you are right.
Even in your example cases, though, compare these two lines:
a = arr.filter(n => n.flag === true);
a = arr.filter(user => user.flag === true);
Which one is more clear here?I hate ${JavaStyleVariableName}s that are so long that it takes extra mental effort to parse the names, so I'm fully with you if you argue for appropriate variable name lengths, but having any name at all (one character is typically not a name) can give some indication of what it is, even if abbreviated or otherwise terse. The variable 'n' sounds like a number, rather than an object that would have a .flag property. While not very confusing, it's also not the most intuitive thing to call it. I wouldn't flag this as "please fix" in a code review, but it's also not better than using any name at all.
One letter names are a code smell I associate with the nastiest bugs I've experienced especially when the git blame shows multiple authors on it.
The essence of a name is twofold: it identifies a thing, and distinguishes it from every other thing. Anything that achieves these two ends is a good name.
Where there is only one thing, its name doesn't matter: only language syntax demands it have a name at all. Shortest is best. In some languages, "_" is that name.
Where there are only two, you need two names visibly distinct. The easiest and cleanest way is two one-letter names.
Using longer names lets you provide documentation without adding a comment which could later become incorrect. That is the only value in a longer name. A longer name has a cost that has nothing to do with how long it takes to type: the reader has to read it to determine it is this thing and not that. It squanders readers' attention. It is worst if it is similar to another name.
If you want to use talking about names in code review to make code better, pay more attention to names that are too similar than to short names.
Ultimately, I think even the choice of naming something and using a single letter communicates your intentions. If you make something a single letter then you're telling the reader that do not even worry about this variable it is just passing through, but if you need something your communicating your intentions of using this variable in the future it is more permanent in a sense
Whitespace is such a choice. Used judiciously, whitespace and its absence can call attention to organizational choices. Used injudiciously, it loses all useful meaning. People who splatter whitespace everywhere -- a blank line above and below every line of code, every parenthesis with a space before and after -- communicate only their contempt for the reader.
Ah this is exactly why people dislike the short names.
If you ever have more than a few of them and they aren't even real words, common abbreviations, or hijack well known unreserved names I would immediately reject that during code review.
I think most people are fine with plain English 1 to 3 word names concatenated in whatever style of the language or other conventions.
i.e. "result" instead of "r", "re", or "res"
Why? Because "r" is familiar as a read permission, "re" is familiar as a regular expression, and "res" is familiar as a response object.
This is the bad kind of familiarity that drives people up a wall and wastes a ton of time.
In your example, noNameDateFiltered is most likely superfluous. If the filter function is short it's self-descriptive what it does. Adding long variables names makes the code harder to read and adds cognitive overhead. In this case, I would strongly prefer just re-using arr or a.
On the other hand, I have seen long complex function that use single-letter variable names and end up with 20 variables that mean different things. Keeping track of what's what in such a case becomes difficult, and you want something more descriptive.
Taking a step back, the goal of variable names is to make the code easily comprehensible by someone else or you at a later time. You have a few choices to do this, in order of preference:
- The code is self-explanatory, like a simpler filter function - use a short simple variable names. This is always the preferred method. Why make it harder than it needs to be? Reading over-the-top verbose code is just as bad as the opposite.
- The code expression may cause confusion - use a more descriptive variable name, but don't go overboard
- It's difficult to describe the result succinctly even with a variable name - use comments
Never overestimate this, there is no upside to the one time it isn't.
> Reading over-the-top verbose code is just as bad as the opposite
No it isn't, it is just as easy, and when can help it pays off, there is no downside.
> It's difficult to describe the result succinctly even with a variable name - use comments
This isn't an either or, if it deserves a comment by all means use one, but that doesn't negate the benefits of thoughtfully named vars.
Obligatory reference, given the aesthetic: https://archive.vn/mIwG0
My rule of thumb is to avoid variable names that are only used once. Instead, use something like pipeline operators, flow(), etc.
Another preference I have is to use initialisms. Might feel dumb at first, but eventually you realize (or I did, at least) that it matters more how things are "braided together" than having perfect names, and your editor prolly highlights all the uses of the variable where you have your cursor.
But, as always, prefer consistency with the rest of the team, even if you feel the rule is dumb. Don't proselytize. If the style really gets in your way to understanding the code, rewrite it and throw it away. There's something elucidating (and satisfying) in seeing a non-obvious piece of code in your native style.
Reply: "You're not alone. 3 to 5 letters works best for me."
I mostly agree with your comment, also the "prefer consistency with the rest of the team" part, but you are not proposing the same as what OP described.
Not 5 years later, and when it is someone else's code. Just don't. Initialisms are no better than single char var names. No one later is going to know you started naming "SmartFooProcessingThing" as "sfpt" and when they search for it in millions of lines of the codebase, they are gonna come up empty and waste time.
There is nothing you should be finding "satisfying" in a non-obvious piece of code. And if you are working on team, there should be nothing "in your native style". Don't be that person.
> Not 5 years later, and when it is someone else's code. Just don't.
That's precisely when you rewrite more: when the initial context is gone.
> Initialisms are no better than single char var names.
Correct.
> No one later is going to know you started naming "SmartFooProcessingThing" as "sfpt" and when they search for it in millions of lines of the codebase, they are gonna come up empty and waste time.
They're not meant to be grepped for. They're meant to be local, fleeting, names for something.
> There is nothing you should be finding "satisfying" in a non-obvious piece of code.
There is. When you understand it, it's satisfying. Or so has been my experience. There's also the frustration of "why was this left like this in the first place", but sometimes it's merely a matter of preference.
Please note that I'm advocating for rewriting and throwing away things you don't understand, not for leaving puzzles for others to relish on.
> And if you are working on team, there should be nothing "in your native style". Don't be that person.
Indeed.
That's worked well for me on a qualitative level
“When should you use single letter var names” feels like one of those style/preference calls that doesn’t ever have solid rules, other than “if you’re working on a collaborative project, pick a rule and enforce it, even if it’s not perfect”
list($maxTrophies, $positions, $winStreak, $lossStreak, $lastfetch) = $result->fetch_row();
(This is my own hobby code on a solo project; not for an employer where I would be more careful to make it clear for others.)Some are context-specific, like $positions being an array of how often you finished in which position (e.g.: [1,2,3]=[1 finish in 1st position, 2 finishes in 2nd position, 3 finishes as DNF]). Not all names will make sense if you're not familiar with the context, but given how often it's used, I think that's better than having to use onlineRaceFinishPositionArray. Maybe I could have used finishPositions, though. Not sure, it wasn't a choice I thought about very long, but I definitely am not using "p" as a "name".
For long names there is Ctrl+n, for example maxtr<Ctrl+n> will autocomplete to maxTrophies. Or for another example, "goldTime_ms": there isn't anything else starting with 'gold' than the gold medal time, and the underscore is annoying to type so this is nice to autocomplete.
Consider the fact that a sensible longer variable name can not be THAT MUCH longer.
This creates a problem where you have to manufacture a 10-20-30 character name that somewhat describes what the variable is.
Inevitably you end up creating a somewhat misleading name that badly describes what that variable is supposed to be. Probably leaving something out to avoid the name getting too long. You can't write an essay as the variable name.
If you accept the short single letter variable name instead you avoid this losing battle to manufacture a name for an abstract thing.
Instead you will have the ability to maybe describe what "a" is in a more elaborate code comment.
Let's say you have 2 lines of code where the variable a is used: a = expr, b = a.filter(...)
Now I have to do the mental effort to see what expr is doing, instead of going directly to the second line and see filteredDateData = filteredData.filter(...)
// get users older than 90
a = data.results;
b = a.filter(u => u.dob > 123456)
seniorUsers = b.map(x => {name: x.name, age: x.age})
// self contained
// comes out with one final var that is named to be used later on
// other vars are obviously meant to be ignored and just placeholders
// comment explains what is happening so each var doesn't need sacrifice comprehension speed
There is no excuse about "well maybe the controller/service/repository/whatever should have been named foo* in that case, I was just holding this temp var for 2 lines of code in helper function and it shouldn't matter".... just don't. Don't be that person. No one thinks you are smarter or cooler for that.
Also consider that if you are really using tiny-scoped vars so often, maybe you are doing something else wrong.
If you have "data = arr.filter(n => n.flag === true);" and it is so tightly scoped, why do you even need "data"? Maybe just return it... if you need to do some other operation on "data", maybe chain the call? If you need to do literally anything else (even just logging it), name it it something useful.
"n" is fine here. "arr" is not... wtf is contained in "arr", what are these types that have "flag"?
Sounds like you got slammed in a code review by someone who has had to debug this type of stuff more than you and you are looking for validation. Just stop being this way sooner than later.
But for temp vars in short functions or closures, I also use single letter vars because I want to see what is being done to the variables rather than the description. If a description is needed I'll use a comment.
Another pattern I find myself using is trying not to use `else`, instead using a function return (either returning early with an if, or a default return at the bottom of the function).
My loop iterators are mostly single letter. A coordinate is likely to be an x, y, or z. A unit vector aligned to an axis will be i, j, or k. A point is likely to be p. A vector data structure v. The first transformation of a variable x is likely to be x’, the second x’’, etc.
I think there's something to that - if it's a common enough convention they use it. But if not, don't make it up.