[webkit-dev] Terminology for giving up ownership: take, release, move
mjs at apple.com
Tue Sep 6 16:48:32 PDT 2016
I thought about why release() seems subtly wrong to me for collections, but not for smart pointers. Specifically, release() puts the focus on giving up ownership, but the in the case of a collection, the most important thing is removal from the collection, where giving up ownership is a detail of the removal. In particular, it doesn't leave a hole, like swap() on spot in the collection with a default-constructed value would, or like release() on a smart does. For this reason, I think move() is also wrong in the collection case).
For similar reasons, having a zero-argument remove() on a smart pointer would read a little weird. Sure, you can think of a smart pointer as a collection of one item, but our actual smart pointers either have clear() or no non-returning removal operation.
Therefore I wonder if consistency between smart pointers and collections is really the most important factor. Smart pointers and collections are different enough that their operations don't have to be named the same.
That said, I do have a proposal that I think is semantically OK for both smart pointers and collections, and also has the correct subject in all cases.
accessor | remove-only | remove+get
get() | erase() | remove()
This has the additional advantage of somewhat more consistency with std:: containers, which name the plain removal operation erase() rather than remove(). A downside is that anyone used to remove() may call it when erase() would do, possibly resulting in slightly less efficient code.
STL smart pointers have a 0-argument reset for non-returning remove instead, and convention seems to be to use swap() or move() for the returning remove on a smart pointer. So an alternate possibility would be to use the above convention for collections, but make smart pointers have no remove+get operation at all.
For comparison, here is the status quo:
Non-removing | Smart pointer | Smart pointer | Container | Container
accessor | remove-only | remove+get | remove-only | remove+get
get() |N/A or clear() | release() | remove() | take()
> On Sep 6, 2016, at 11:07 AM, Geoffrey Garen <ggaren at apple.com> wrote:
> “take” grinds my gears too — though I’ve gotten used to it, more or less.
> I read “object.verb()” as a command, “verb”, directed at “object” (or sometimes as a question, “verb?”, directed at “object”). I think most APIs are phrased this way. And if I were Antonin Scalia, I would make the originalist argument that Smalltalk originally defined a method in object-oriented programming as a message to a receiver — not a message about a sender.
>> In the context of a container, take() sort of makes sense by parallel to get(). Though get() could be interpreted as either what the caller is doing or what the callee is doing.
>> In other words, you could say that in the code below, function something gets an item from the collection. In that sense, take() is a parallel construct. Of course, you could instead say that function something asks collection to get an item. That's what makes take() not make sense. But I am not sure release() makes sense either way, for a collection. It conveys letting go of the item but doesn't seem to convey fetching in the sake way get() or take() do. I don't think move() would be right in this context either.
>> function something(Collection& collection, Key& key)
> Though it is possible to read “get” in this context as “I get from collection”, I think it is more natural to read “get” as a command: “collection, get this for me”. Other access verbs on collections, such as “find”, “add”, and “remove”, establish this pattern.
>> Given that explanation, I think a possible direction is to rename the smart pointer release() operation to take(). Many of our smart pointers already have a get(). And the idea of taking the underlying value from a smart pointer kind of makes sense, even though it is caller-perspective.
> I’ve gotten used to “take", so I won’t call it pure applesauce, but it’s not my preference.
> My favorite suggestion so far is “move”. The C++ standard helps make this a good word because it introduces as terms of art std::move and “move” constructors. But perhaps it is bad for a function named “move” not to return an rvalue reference. For example, one might object to “std::move(collection.move(key))”. Why the double move?
> My second favorite suggestion is “release”. It matches a term of art in std smart pointers and it’s pretty clear.
> My third favorite suggestion is “remove”. For collections, “remove” is just plain clearer. But “remove” is worse for non-collection value types like smart pointers because we “move” values in C++ — we do not “remove” them.
> There are some good thesaurus words like cede or doff or discharge but they all lack familiarity as terms of art.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the webkit-dev