There is a tension in the problem of naming things: Do you name something for what it is? Do you name it for what it does? Or do you name it for how it is used?
Previously, we saw std::
, which is named after what it is. One reaction was that the class should have been named something like std::
, which names it after how it is used: To prevent template type deduction.
template<typename...Args>
void enqueue(
std::function<void(std::non_deduced_t<Args>...)> const& work,
Args...args)
{
enqueue([=] { work(args...); });
}
We have the opposite problem with std::
: The in_place
types are named after how they are used, rather than what they are. They are tags that are used by some constructors of variant-like types to indicate what they should hold.
in_place
: Hold the primary thing (as opposed to nothing, or the alternate thing)in_place_type<T>
: Hold the thing of typeT
in_place_index<I>
: Hold the thing at indexI
But when we used it as a tag type in our example, it was used not to indicate what the class itself should hold, but rather what the class should hold a reference to. Perhaps it could be named after what it is: std::
and std::
.
Though what about std::
? Maybe we leave that one alone?
And then we have std::
, which is named after what it is, rather than how it is used. In other languages, this type goes by the name unit
, which to me feels like a name chosen with category-theory-colored glasses. (Also, the name unit
could be misinterpreted as having to do with systems of measurement.)
Bonus chatter: Note that none of the examples are named after what they do, because none of them do anything!
TabTheTextOutForWimps()
BozosLiveHere()
PrestoChangoSelector()
BearNNN (where NNN is the ordinal of the export from USER)
BunnyNNN (likewise, for the kernel)
Could be worse. They could name things that provide no actual indication of anything useful (what it does, what it represents, etc). Entra comes to mind…
Could be worse still, wasn’t it called Azure Active Directory while having nothing in common (nor possible to interoperate) with “real” AD?
All I care is that they are named in Pascal Case otherwise it’s not much easier to read than assembly language. That was always the big problem I had with the C/C++ world, their naming conventions are like every byte costs big money and it is always unnecessarily difficult to quickly see what a chunk of code is doing.
Actually C++ these days have ridiculously long identifiers spelt in full in its standard library like and , and they're all in snake_case, which costs more bytes than PascalCase.
The C standard library on the other hand is still stuck with short, abbreviated symbols (), which ironically makes less sense in C than in C++ because C doesn't have namespaces and is much more prone to naming conflicts. The broader C community makes more sense...
I’ve met many programmers in my life, and each one of them assured me that THEY know how to name things. It’s everybody else who doesn’t know what they’re doing.
Naming things is one of the two hard problems in computer science.
Alongside cache invalidation and off by one errors, right?
container .empty() / .clear() are one of my workmate’s favourite gripes about naming.
libc++ marks its
vector
‘sempty
method as nodiscard, so you’ll get a warning if you mistake it forclear
. I haven’t checked other containers or other standard library impls.if only we were still using LISP we’d know for sure the function should have been named emptyp, and ….
caarnilmap ?
😉
just kidding mostly, but adding p to all predicate functions was a good, almost Hungarian convention.
Fun pairing I’ve seen in two parts of a big codebase: one group of collections used
as its naming convention, while another group used
.