I’ve talked about good names before but it only briefly touched on the importance of exactly which words you choose. Words have meanings and connotations. Pick the wrong word and people can get the wrong impression. However good your documentation is that won’t help if the developer thinks they already know how to use it.
std::remove
The C++ template library provides a lot of useful functionality. During my early years with C++ it hadn’t really been a feature but coming back to it later on it was much more extensive. The algorithm header deals with containers and iterators.
So, for example, we have
replace.
It goes through replacing anything matching old_value
with new_value
.
That makes sense.
So if we wanted to remove some values we would use… remove? Let’s quickly skim the documentation:
Removes all elements satisfying specific criteria from the range.
Removes all elements that are equal to
value
Sounds great but, no, this is only part of what you want. What remove really does is move all the values to be kept to the start of the range and all the values you want to erase to the end of the range. You’re actually need is something like this:
auto newEnd = pointers.remove(nullptr); pointers.erase(newEnd, pointer.end());
Functionally this is… okay.
You want to erase some things from a vector and you can.
It does require you to use the pointers
identifier three times so it is repetitive but
that’s another problem.
For me the real problem here is the name.
Surely remove
should remove something?
If you’re picking names you want to reflect what’s really going on.
Here, say, partition
would be a better fit.
The collection is being divided into two.
The first section will not have the given value, the second section will only have the given value.
Actually there is a partition and stable_partition as well. So what’s going on:
- In
partition
the order of elements is not stable. No guarantees about the order within each section. - In
stable_partition
the order of elements is stable. Within each section the original order will be preserved. - In
remove
the order of elements is partially stable. Within the first section the original order will be preserved but not within the second.
Functionally these are related but different.
It would make sense to reflect this in all of the names.
remove
not only doesn’t reflect the functionality it fails to signpost these other functions.
At this point I often jump to a
thesaurus.
For this we can start by looking up
remove and
partition.
I’m less keen on the former because it doesn’t reflect what the function does but
we can check both.
I would consider subdivide
, separate
and split
as possibilities.
As a nice bonus separate
is in both lists.
Thinking about it:
- I feel that
subdivide
means more than two sections. - I associate
split
with strings and it’s functional partnerjoin
. separate
andpartition
could both work as the core word for a set of functions.- For me
partition
wins out overseparate
. It feels more “algorithmy”.
We still have to distinguish between the functions.
I think stable_partition
is good and
that suggests unstable_partition
for the
opposite.
We could try renaming the remove
using a similar scheme,
semistable_partition
or partially_stable_partition
perhaps.
While the former might work the later feels far too long,
especially considering it’s probably the most used of the functions.
In the end I’d just stick with my original suggestion, partition
.
In the end
This might seem overly involved. Especially when I go off searching through a thesaurus only to end back at my original idea. However, for me names really do matter. It’s worth spending some time picking the right ones. If you pick the wrong one you may end up being stuck with it. A good name keeps the developer on track. The first time you read some code you want to be able to get the gist of what’s going on, even if the functions and classes are new.
Leave a Reply