Felienne Hermans: How patterns in variable names can make code easier to read
youtube.com
youtube.com
For example, left_foo and right_foo are little-endian, since the least significant word comes first, so they'll be a long distance away from each other in an alphabetized list.
But foo_left and foo_right are big-endian, since foo is more significant than left or right. So they will appear one after the other in an alphabetized list.
Common suffix words are _x _y _z or _min _max, or _left _right _top _bottom, of even singletons like _enabled _loaded _error etc.
But when you combine multiple dimensions together in names, you need to think of which dimensions are more significant, based on how the variables are used, so use foo_x_min foo_x_max, if the positions are important, or foo_min_x foo_min_y, if the ranges are more important.
Sometimes it's hard to decide or ambiguous, so just try to be predictable and the same as all the other code. Think of which variables should appear closest to each other in an alphabetical list.
And avoid middle-endian or random-endian (or sentence-grammar-order-endian) like the plague. A variable name should probably not be a grammatically correct sentence.
Another really annoying linguistic naming smell is "smurfing," where all of class Smurf's instance variables have smurf_ prefixes. Or where all the classes, methods, or instance variables have an "xyz_" prefix where "xyz" is the name of the project or library. Arrgh!!!
Also: eschew Bill and Ted's Excellent Postfix "_not", which inverts the meaning of the variable name. That's a most totally bogus code smell, dude.
Let's say you have some non-trivial class that includes, among others, some 2d rectangular data: An x, y, width, and height. They're all related, but they don't naturallly occur near each other without a little massaging:
coordX, coordY, sizeWidth, sizeHeight?
xMin, xMax, yMin, yMax?
coordXMin, coordXMax, coordYMin, coordYMax?
I generally agree with your sentiment, but there's a reason "naming things" is one of the hardest problems in computer science :)
IMO a big alphabetical list of everything in your project is not a useful or important thing. Use a language that has good support for hierachical namespaces, and use them.
It's the difference between taking, say, 2 seconds to read a method, and 10 or more.
I can only assume people who don't treat code formatting as a rule read every.single.thing.line.by.line.every.time.
That's why I assume too. I don't understand how one can code like that.
I find Rails' conventions are very good around this, for example datetime fields end with _at and dates end with _on. This way you end up with variable names like published_at or published_on depending on if you care about the time or not. It sounds so natural.
The idea of using ? to end a variable name for booleans is great too.
It's the opposite of cognitive load because you can glance at a name and know what it is without knowing more about it. If the implementer of a linguistic named function does bad things to break the expected behavior then you shouldn't blame the method -- that's a user error.
Personally I find consistent names more important for CLI tools, kubectl's CLI is good in this department for being consistent. You can predict how each command works by knowing the pattern. They went with a "verb noun" style. I don't think one is necessarily better than the other but being consistent does help for CLIs because you often need to recall what to run by memory, CTRL+r history or running the command incorrectly to get a help menu on what you can run. However a code editor gives you a lot more help with auto-complete or buffer-complete for function or variable names.
For naming things in programming, I'm not 100% convinced a hard pattern based standard makes sense because naming is very subtle, sometimes you want the emphasis on the "thing" or an emphasis on the "action" depending on the context -- basically which one is more important for that specific instance.
For her open question of "what would you name a variable for storing the maximum number of orders per month", that's an incomplete question. What's the context behind it? Is this variable defined as a constant somewhere? What other functions are in that module or class? How do you plan to use the variable? Will it be used in more than 1 spot? Is it part of a library that third party folks can use or limited to 1 code base? Will there be other similar variables, such as getting weekly or yearly orders?
As far as 'consistent' names go, there are multiple dimensions of sameness. Using the same word for all instances of the same concept, not using the same word for other concepts, using consistent pluralization. Using same adjective/adverb/gerund form for related concepts. You are telegraphing sameness in these cases, and difference in others.
We have tried things similar to what you describe before, we just have dialed it in wrong. New-ish, good ideas often fall prey to bad execution. Hungarian notation, for instance, dictates that the variable name stays the same when the sense of the data changes, but is supposed to change when the implementation details shift. Which is exactly the opposite of what we want. If I fix a Y2K bug or a 2038 bug in due_on, I'm going to end up with a slightly different structure, but the deadline it represents is still 12 midnight. And if it's not, well, maybe we need a different convention for calendar day versus business day deadlines.
If you think opening braces should go at the end of the line and I (incorrectly ;) ) think they should go on a line by themselves, our team style guide should probably pick exactly one of those. That’s a human choice after human debate, followed by machine enforcement.
The "big-endian naming mould" suggests naming it orders_per_month_max, since orders is the object (most significant), per_month is a count of orders (secondary significance), and max is a constraint of the order per month count (least significant).
Then you can use other parallel names in the same big-endian pattern, like orders_per_month orders_per_year orders_per_year_max orders_per_second_min refunds_per_year_average etc, and they will all sort next to their closely related names, instead of the "inline max" or "prefix max" scrambling the alphabetical order.
(createdonutc)
I once worked in a place in the 1990s that took it to such an extreme that every table name, column name, and variable name had to be approved by a naming standards committee before it could go into production. IIRC the committee met once a month, maybe twice? Which was not ideal for the developers but changes only went to production once a month during a "change window" anyway.
Naming conventions can help with code readability, but don't let the process become more important than the goals.
I wouldn't mind you poking holes in my logic here.
https://soft-wa.re/naming-conventions
To use her example. I would have chosen ordersPerMonthMax. Which would probably sort alphabetically nicely with ordersPerDayMin and ordersPerYearAverage.
Now that I know "name-mold" would be a good query, I might find something better than the Spanish name-mold.
Wide Scope Narrow Scope
+-------------+-------------
Function | Short Name | Long Name
+-------------+-------------
Variable | Long Name | Short Name
+-------------+-------------
I can’t quite explain why this works
I'll take a shot...The general principle uniting all 4 quadrants of the table is: "Use names just long enough to be clear, but not longer."
Here's an illuminating exception to the heuristics: The use of the very short global "DB" for database.
We are really trying to balance two competing goals:
1. Brevity -- Don't explain what I already know. You mention this in relation to a tight loop variable: "I bet you didn’t need me to explain dL stood for Drivers License. It might have even annoyed you if I had spelled it out."
2. Clarity -- Don't confuse me. Don't make me look something up to figure it out.
Maximize brevity while retaining clarity.
Clarity is related to frequency of use. This relates to your comment: "How come the jQuery constructor feels much more natural than the native version? document.querySelectorAll('#appContainer')". It is annoying because we use it all the time... we don't need or want a verbose description.
If the thing is used everywhere, and especially if it is a general convention, assume familiarity. Sure, someone might be confused by "DB" the first time they ever see it, but it will quickly become part of their lexicon and remain so through repeated exposure. However, the same cannot be said for "CGTAO" as a stand in for "cudaGetTextureAlignmentOffset". In that case, the long form is what I want.
We handle these principles effortlessly with our use of "he" vs "John" vs "John Smith" vs "the John Smith you went to highscool with" but for some reason have trouble with them when writing code.
The part where it gets tricky is when a concept is widely used, but is a complex concept. What if you have dozens of calls to cudaGetTextureAlignmentOffset in a function, and hundreds in a codebase? Heck, even CUDA is an acronym, Compute Unified Device Architecture.
There's a similar complication when you have several of these big names with slight differences. Made up example, say you also had cudaGetTextureAccessKey, cudaGetVectorAlignmentOffset, etc. I actually find these sometimes worse than the initialisms, as my eyes skip over these long names. The acronyms (CGTAO, CGTAK, CGVAO) have a higher ratio of different letters to total length. But then obviously the abbreviations are very opaque.
I like this framing.
> The part where it gets tricky is when a concept is widely used, but is a complex concept. What if you have dozens of calls to cudaGetTextureAlignmentOffset in a function, and hundreds in a codebase?
You have to predict the knowledge of the developers (current and future) working on the system, and let that guide what you can assume. This is necessarily an art and you'll miss the mark sometimes. One approach is to always be overly verbose, but this is too simple: it destroys readability when practiced without restraint.
> There's a similar complication when you have several of these big names with slight differences. Made up example, say you also had cudaGetTextureAccessKey, cudaGetVectorAlignmentOffset, etc.
One technique here is to introduce a namespacing object/module/<whatever you call it in your language>. So something like "cuda.textureAccessKey", "cuda.vectorAlignmentOffset", etc. Sometimes repetition of a long name is the least of all evils, sometimes it's not.
Alphabetically {a, b, c} × {Min, Max} is soo much nicer than the converse. Especially in lists dozens of items long.
If you think someone comes up with bad names, wait till they have to write a few sentences, or paragraphs.
It abuses the English language but makes code much easier for me to read. Most of the time I don't even realize I'm doing it.
But does it make the code easier for others to read? The first 2 steps I think so, and I've seen them in other projects. The last one probably not, and I try to avoid it and use more descriptive names (like "srcPath" and "srcData") when I spot myself making it.
But in practice $0 and Haskell’s point-free styles can be annoying to read, so maybe what I want is the IDE to insert obvious names.
Point-free syntax has a different kind of namelessness, where if you have a single thing, you don't have no name it. And the $0 is really a limitation of the language, nobody ever though it was a good thing.
Surely Perl programmers think a name like $0 is good, that’s their whole aesthetic.
The $0 syntax screams of somebody that don't use it since the 90's.
I wrote about it a few months ago:
https://dev.to/jmpavlick/hungary-for-the-power-a-closer-look...
Underscores are better for readability other kinds of things like unit test names or filenames. Because humans tend to shortcut, it becomes camelCase for everything, including other inappropriate attributes out of laziness, which is aggravating. It's too bad that distinction has not been properly subjected to rigor yet.
What Did Terrence Eat?
It's a system for semantic variable naming.
What evidence? Where?
http://www.art.net/~hopkins/Don/unix-haters/x-windows/motif....
TLDR:
s_CALLBACK_CUR_INSERT Lexical_Bindings_For_XmTextVerifyCallbackStruct XtPointer call_data XLTYPE_CALLBACKOBJ /* How long can this go on???? */ Set_Call_Data_For_XmTextVerifyCallbackStruct Wcb_Meta_Callbackproc XmAnyCallbackStruct doit newInsert XmCR_MODIFYING_TEXT_VALUE cdr car ep /* do nothing for most cases... */ Cvt_XmRXmString_to_LVAL GetValues_Union Resource_Instance WINTERP_MOTIF_111 XmStrings XtGetValues XtPointer_value cv_xmstring XmBulletinBoard XmNdialogTitle XmNnoMatchString XmNlabelString XmNtitleString XmRowColumn XtGetValues XmStringFree /* This is so totally ridiculous: there's NO WAY to tell Motif that any button can select a menu item. Only one button can have that honor. */ /* If this function looks like it does a lot more work than it needs to, you're right. Blame the Motif scrollbar for not being smart about updating its appearance. */ xm_update_scrollbar widget_instance Widget widget scrollbar_values pane_maximum widget_sliderSize new_sliderSize h_water l_water XtVaGetValues XmNheight XmNpaneMaximum XmNsliderSize widget_sliderSize XmNrefigureMode maximum minimum INT_MAX percent XmScrollBarSetValues ARMANDACTIVATE_KLUDGE DND_KLUDGE *dialog*button1.accelerators:#override Ctrl<KeyPress>m: ArmAndActivate() /* sets the parent window to 0 to fool Motif into not generating a grab */ USE_MOTIF xlw_unmunge_class_resize XlwMenuResize