Against Names
steveklabnik.com
steveklabnik.com
Maybe not everyone gets the same benefit from the discipline as I do! It’s certainly possible. But I do have to wonder how much that’s the case.
For git, I'd never even considered it, but I often find myself renaming branches `thing-im-doing2` just because the first branch is broken, or having `abc-def` and `def-abc` branches accidentally...
The tooling needs to be wildly adopted though, and that's difficult. I gave up on graphite for exactly this reason.
It has kind of radicalized me against "pointless names". Names take up valuable space in the working memory of the reader. They need to carry their weight.
I've seen streams-like code with a variable for almost every step, immediately used the line below. I can understand when the reason is to "explain" the meaning of the intermediate step...but even so a comment is far better on my opinion.
I always try to inline every 1-use variable/method, unless there is a good reason for not doing so.
[0] https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus...
You only write code once, but if the software is long-lived, different people will read that code for years to come, doing support, maintenance, and adding features.
By naming something, we make it a Thing. It forms a shape in our minds. However small, it has a history and a purpose. It has relationships to other Things. Its identity is now something we take custody of, by continuously interacting with it. This can help in the smaller context but does not scale.
One example is organization of e-mail. The traditional inbox approach makes you create folders. You have to give name and meaning to each of these. Organize them into trees of subfolders. Contrast this with the search-based approach popularized by Google and notmuch - tags/labels are optional but in general you have "an ocean of mail" which you search on an ad-hoc basis[0].
I think the OPs point can be taken further. That there's an inherent human instinct to want to name and create Things and that it's beneficial to be aware of and overcome this instinct.
I have a bunch of useful code and scripts spread across a couple of libraries. I could hypothetically break out anywhere from a handful to dozens of focused individual repos with a fancy Name. Make them into npm packages, give them each a logo, maybe even separate websites and chat rooms[1].
At the extreme, look at the pathological Clueless-driven big-tech with a gazillion Projects, Initiatives, Frameworks, Processes, Working Groups, Epics, Task Forces, Swim Lanes, continuously churning through birth and death. The meta-abstractions start to run the show.
[0]: I happen to prefer the mailbox approach myself! Of course the taxonization and structuring is not all bad - here the history and meaning is inherent and useful. My point is rather that it should be applied consciously. And in my mailbox, as opposed to in much of the software I write, the Things and their forms are entirely self-inflicted (hello NSA) and not something hoisted on the minds of others.
[1]: This is apparently fashionable recently among 10x Open Source GitHub Rock Stars. It's also particularly a disease in crypto with all these "Protocol"s each spawning their own fractal universe of Things.
This is also an argument for micropackages, if done well. If you publish and import functions inpendently, there is no intermediary module and/or package. They are the same. This would need better platform integration to be something I'd argue for in practice, though.
Without reading any code, you can tell what "inputToFocus", "postalCodeIsValid" and "daysToEarliestAppointment" mean. Then you know what this variable represents in the real world, and also what your code is operating on.
I also prefer CSS class names that describe what the object is (".alert-box.warning" or ".button.primary"), and not what it should look like. I don't like updating dozens of templates because I want to change how some things look across the website. I know that I won't forget to update one and create a hard-to-find bug.
Those "CSS class names" are just HTML classes. They were invented for HTML, you write them in HTML, and they're part of the HTML spec.
It's become evident from comments on HN recently that people apparently think they're a CSS thing (because that's how they're taught CSS) but they're just an ordinary fixture of markup; they're for describing the class of something. Accordingly, stuff like class="alert-box warning" is the correct way to use classes (rather than e.g. class="3px-red-border" or whatever).
The CSS people didn't give us the class attribute (and the HTML people didn't put it in so that we could use CSS better). HTML had class attributes before CSS or JS ever existed.
But I feel like the two examples given don't really support the case against.
In git, branches are close to meaningless. You can use git without branch names quite well, it's just not as nice of an experience as jj. The only thing you can not do in git without having a named branch (or rather a ref of some kind, does not have to be a branch) is moving commits between local and remote repository.
In git, branches are only meaningful – briefly – when communicating with other people, in which case naming them really matters! For your own temporary use, sure, don't name then. For me that's more of a flaw of git. In most git workflows you're meant to destroy history, so it doesn't matter that the branches are also destroyed, which again results in their names being meaningless. For things that are not throwaway I'll stand by putting as much effort into naming them as is needed.
Utility CSS classes are names. They're an API. Although I understand the reasoning, Tailwind is actually a perfect example of terrible naming. Everything has a single letter name or a name composed of initials. As a beginner you have absolutely no idea what you're reading, until you learn all the cryptic names. I'll restate that I understand why it is this way, but again for me it's a flaw of Tailwind and maybe utility classes in general.
Then there's the final example of lambda functions, where supposedly everyone accepts that naming isn't important. I think this one is the best example of why naming is important. If each step here had a proper name, you wouldn't have to write out what the function does, the code itself would explain it. If I don't trust it I can verify that the code the name is given to matches the name. Once I've verified it I can forget the code and substitute it with the idea of what it's supposed to do. Or if I don't want to verify it I can just trust the name and still understand what it's supposed to do.
Good naming helps readability tremendously for me. I don't have to spend any brain processing power on parsing that `.filter(|i| *i % 2 == 0)` means `filter even numbers`, I can just read it.
PS. Actually there are already two good names there: `into_iter()` and `sum()`. I don't need to know how they're implemented to understand what they're meant to do there. It's the lambda that's the problem and shows why naming is important.
I've always hated the pattern where you have to declare a throwaway param name within a block for cases where the `::Symbol#to_proc` syntax won't work, like when the method you're trying to call needs some argument. They usually end up as nonsense single-characters anyway so they may as well just be numbers I don't have to think about!
irb(main):001> lol = [1337, 420, 69]
=> [1337, 420, 69]
irb(main):002> lol.map(&:to_s)
=> ["1337", "420", "69"]
irb(main):003> lol.map { |wow_this_sure_is_annoying| wow_this_sure_is_annoying.to_s(16) }
=> ["539", "1a4", "45"]
irb(main):004> lol.map { _1.to_s(16) }
=> ["539", "1a4", "45"]If I open a pull request on GitHub, the name of the branch is completely incidental. I already have textual descriptions for every commit. The pull request gets a title and a description. The branch name is there, but if it wasn’t (or if it was nonsense) don’t think anybody would notice. Once the branch is merged the branch name is lost to git. It might be recorded in the merge commit description but at that point it’s flavor text and not actually a pointer within git.
I have also fully converted to jj and yeah, it really does make you realize that branch names are often pointless for short-lived work in PR-based workflows.
The other is ROC (receiver operating characteristic) used in statistics and machine learning. The current usage is very divorced from its original meaning (related to radars as I understand) and it sounds very stupid when used in its current context. It is just a simple ratio of a few statistical measures. I think using such names actually makes things even less understandable.
On the other hand, definitions (ie, naming things) is very useful in math and other disciplines.