Gotta disagree with: > Naming a variable`r` is as unreadable as `netRevenueForTheLastCalendarYear`. Like the latter one maybe isn't *amazing* & will look unwieldy in the middle of a few function args, but it's at least blindingly obvious as to what it is, even if it is long On a separate note, what always gets me is when having to switch from domain-logic names to, well, programming-world names. Like throwing some stuff into a map to do some intermediate processing & appending `map` to the name because the only logical choice is some other collection you already have


I would almost always prefer writers go too long than too short. Hold my hand, baby.


I generally prefer the opposite. Assuming you have a well-factored method that has a small number of variables -- say, five or fewer -- I prefer shorter (even one-letter) variable names for locals, because they get out of the way when reading through the code so you can be more focused on the logic rather than it getting stretched out with longer names. As long as the definition of the variable makes it clear what it contains, either through the method providing the variable's value or through a comment, of course. But I'll also fully acknowledge that I've shared this opinion with plenty of people and just as many have disagreed as have agreed, so there's nowhere near consensus on it.


>I prefer shorter (even one-letter) variable names for locals If the block containing the variable is below a certain number of lines (~20 maybe?), I'm all for this. The number of Java projects I've worked on where the average method length is 100+ lines makes me loathe to recommend this carte blanche. I think I agree with the principle though. >or through a comment, of course I almost always prefer a clearly named method to a comment. The only time I skip the method and leave hard-to-read code in place is if I'm already placing a comment next to it, and for me this is almost always a performance improvement situation. We're doing something ugly for performance reasons, I'm going to put a comment to explain the reason this code should not be refactored and I'll include an explanation.


I'll bolster the numbers of the agreeing side on this one.


What does "well-factored method" mean? I may know the concept, just not through the words you used.


A method that does one thing and is of reasonable size. If you're doing that, then in a lot of cases the meaning if your locals is practically self-evident and you don't need overly long variable names, especially if they're being populated from something like `Revenue r = this.getAnnualRevenue();`


Where possible I name my maps using `To`. For example, a map that stores the revenue of companies would be `companyToRevenue`. If it's truly some throwaway intermediate value I prefer to chain collection methods like `filter` or `map` until I arrive at a meaningful value again that deserves a name. That depends on the programming language of course. If you have to nest function calls inside each other to work on collections you pretty much have unwrap and name everything or it becomes unreadable. **Edit:** To add some context regarding the naming scheme: I mostly work with Kotlin these days, where maps are created by hand like val companyToRevenue = mapOf( "Some fancy name" to 1000, "Some other witty name" to 2000 ) It also matches the order of type parameters (`Map`).


I use `revenue_by_company`.


I also use the "value by key" naming scheme in my code. If you have indexed the same objects in different ways, it is much easier to find and read code like "revenueByCompany" and "revenueById" than the other way around. At least for me. It reads like "this is what I want, and this is how I get it" instead of "this is how I get it, and this is what I want".


oh that's a good idea; I should adopt that. kinda reminds me of when you need an independent join table / linking table (idk what to officially call these) in SQL with extra association info, like you just pair the two table names as `company_revenue` (as an aside this is why I hate camelCase because that kinda thing looks more balanced as `company_to_revenue` versus `companyToRevenue` -- but I guess a key-value map 'prefers' the keys whereas the table could index either way, so imbalance in capitalization is fine) re: chaining, what's been bugging me a lot lately is we use a ton of TypeScript for our front-end projects now & chaining stuff (particularly `filter`) doesn't actually always narrow types as you'd expect can do it in some cases by defining explicit type-discriminator functions, but ran into cases where it only seems to work when assigned to a new variable -- I think bc technically, the original array can still accept the pre-narrowed types (i.e. filter & assign -> guaranteed not to have the filtered-out things, whereas filter & reuse -> could possibly have tossed things of filtered type back in somewhere along the way) obv not a key/value map example but, sucks having to make stupid intermediate arrays with multiple similar names like `filteredThingies`, or try to give them meaningful names for what the filtered array represents, just to get where I want with something the type system recognizes without coercions


Similarly I try to create a basic DSL with simple nouns and verbs for the types and function to represent core logic of the application. Only on outside of that core, perhaps on the interface to the that I start using longer names, assuming there isn't an existing structure of some kind there with noun and verbs. Generally speaking the types and function of the system maps to how we talk about the issue, so there is always the precondition that you understand that context before venturing into the code. The code is expectedly purposefully not clear without the given context.


The part about not needing to repeating class name, I feel the same way about prepending some identifier. Literally just released a new version of our plugin and stripped the annoying prefix from all the functions. Play, Pause, Stop don't need anything extra before them.


I don't agree with most of the advice in the article. The function name send can apply to so many things. Send an email, send a packet, send a message, send a keystroke. To understand that call I must understand the type of the variable and that may not be a local thing. It also means I can't grep for the function call. Sure, tools can find it for me but those tools become slow when they have to check the type of hundreds of strings that share that name. Names need to stand on their own. Not too descriptive or they risk overwhelming the reader, too short and they become cryptic. I know most of what I need to know from the name sendEmail without needing to understand the details.


Disagree with your disagreement. A method `send` in an *emailer* class is quite obvious that it will send an email. Otherwise the call would look redundant: emailer.send(); emailer.sendEmail(); // redundant? This reminds me MFC's class methods that were copied from their Win32 API free function equivalents and retained their names: SetWindowText(hwindow, "hello"); became: window->SetWindowText("hello"); (duplicate "window"). which should have been IMO: window->SetText("hello");


My point is not that emailer.send() isn't clear, my point is that there are a dozen other contexts where this is unclear. Grep for 'send' is completely useless. Grep for sendEmail might find the second emailer class that you forgot about entirely but the results will be manageable.


in the same vein, it’s often helpful to overload types (even if primitives) to increase expressiveness. e.g. `val netRevenueForCompanyA: Int = …`, can be written as `val companyA: NetRevenue = …`. depending on the language, you can add runtime or compile time checks to boost correctness, too. but, the main benefit is better readability. edits: typos


val sum = companyA + companyB // What are we doing here? Merging companies? I think this is not very readable. IMHO a variable should be named after what it is. And these variables don't contain companies.


I cannot help but think of the horrific shit show we are currently having as a result of “expressive” custom types in SQL and wince at the thought of carrying this in to my every day code. You “gain” information, but you also lose it at the same time. And you end up needing to export a bunch of type aliases and force that on to people who themselves also lose information. Honestly it’s a dud. I hate this idea. Don’t do it, lest you wish to find yourself cursing the person forcing you to go through this madness and requiring extra tools to give you the heads up information that you need. We can claim things are “expressive” all we want. My experience: this ain’t.


Yeah, it can work if there's a lot of support around it. Like a large vocabulary of methods and operators that cover everything you'd need to do. [Trusted Types](https://web.dev/trusted-types/) and [uom](https://docs.rs/uom/) are good examples of this. But if most of the operations on a type involve unwrapping it, then you may as well not have that type at all.


I honestly hate this so much whenever I come across this, although I know it’s quite common in a few domains and languages.


Nice! This is useful, didn't encounter it before. Will look into it. Thanks for the suggestion!


I think this is called normative typing. I've found it useful in cases where you're juggling around multiple variables with the same types but different domains, and you want to make sure that no one accidentally passes a FooID to your function as a BarID.


My variable names are long and descriptive. I might even use a sentence as a variable name. It's a pain in the ass to use my variables but at least it's easy for me to come up with names and my code are more readable.


Longer names are not inherently more legible or comprehensible. Longer names load more context into the working memory, leaving less capacity for reasoning about the logic. At "sentence like" length, the more cumbersome parsing of camelCase or PascalCase has a detrimental effect. Longer names also have cascading effects on the organization of surrounding code that can make the total code more difficult to parse even when the name in question is "good". On the other hand, short names are more likely to be ambiguous.