RFC 2349 proposing a new set of APIs to deal with types that cannot be safely moved around - especially generators and async functions. You can read more details of the design in the RFC. This thread is a sidebar to discuss the names of these types.
The names proposed in the RFC were arrived at ‘evolutionarily’ as several different previous APIs converged into the present one. So they’re not necessarily very good.
The relationship between the three items (review of the RFC)
The trait Move is an auto trait. Types which don’t implement Move restrict the functionality of Anchor and Pin. They are designed to guarantee that if a type is not Move, once its in an anchor or a pin it will never move again.
Anchor<T> and Pin<'a, T> are a lot like Box<T> and &'a mut T respectively - in fact, they each are just wrappers around those types. The difference between anchor/pin and box/mut ref is that when the type does not implement Move, Anchor and Pin do not provide APIs that allow you to move that type out of them.
Its important to consider how these types will be used, and how the length of their name impacts their ergonomics. All of these names want to be short
Anchor and Pin will both likely be used as method receivers. Being short makes this easier (especially Pin, because of its lifetime).
Anchor and Pin could be Pin and PinRef, or BoxFob and Fob. Move could be Slip, Slippery, or Slick, i.e. words that mean something can move while pinned.
The problem I find with Anchor and Pin is that they’re essentially synonyms, since a pin serves to anchor the pinned object. Either you’re creating a pin to hold the thing, and a pin reference to refer to it by, or you pin something and use a fob to access it, with a BoxFob being a particular kind of Fob that owns the pinned object.
I think Pin and PinBox are excellent names. If we want a shorter name than MovePinned for the trait, how about UnPin? That, in my opinion, while being short, nicely illustrates that the type can be “un-pinned”, or moved out from Pin.
Hmm, I sort of like Unpin (though I would capitalize it like so), but it also makes it sound as though you are “canceling” the pin, and yet the Pin value remains intact (it just offers weaker guarantees). OTOH, Unpin definitely feels like a more elegant name than MovePinned.
I don’t find MovePinned particularly clear. It should like you can move the Pin<T> around. If we were going to go for clarity, I think I would prefer MoveWhilePinned.
Compared to that, though, Unpin is looking better and better. =)
I’m also intrigued by Unpin. My only fear is this - will this trait end up showing up in bounds really distant from where the pinning is happening, and so users see something like trait Frobulate: Unpin before learning about Pin, and that name gives you no sense of what it means without the context of Pin.
The primary thing that has bothered me about Pin is that if you have a Pin<T>, that means to me that your object is pinned. But in my mind, a Pin<T: Move> was a misnomer because your T wasn’t pinned at all. Was Pin lying?
The alternative mental model I developed for Unpin was essentially what @GolDDranks was getting at, although I didn’t read their comment at first. get_mut() or DerefMut is like unpinning a Pin temporarily, allowing you to mess with what’s beneath it before putting the pin back (ending your borrow).
Think of taking a thumbtack out of a cork board so you can tweak how a flyer looks. For Unpin types, this unpinning is directly supported by the type; you can do this implicitly. You can even swap out the object with another before you put the pin back. For other types, you must be much more careful.
I think we can create this mental model on first contact with the trait’s documentation. It’s always going to be the case that when you see a new trait you don’t recognize, you won’t know what to think of it. If you don’t know what a Pin is, MovePinned and MoveWhilePinned are probably going to look just as cryptic to you as Unpin. And by definition, I don’t know of any object that can move around freely while it’s pinned down, so the longer names may be more confusing after all.
You seem to be referring to an older version of the RFC. In the current version, there is no StackPin
proposal, or anything called “pinned”.
I think the name Pin works by analogy to MutexGuard. The existence of a MutexGuard means the mutex is locked, but the guard value isn’t called a Locked. Analogously, then, the Pin serves as evidence that the inner value is pinned.
Also, the word “pinned” describes the inner value, not the outer reference. If a Pin was just a flat wrapper type representing the status of the inner value, naming it after the adjective describing that status would make sense. However, the Pin is a separate reference value, so it makes more sense for its name to be a noun, indicating that it is a thing rather than a status.
As for StackPin, in the event of a stack pinning proposal, I agree that it’s inconsistent. If the existence of a Pin is evidence that a value is pinned, and a StackPin is a reference to a stack value that isn’t pinned yet, then it isn’t itself a pin, making the name wrong. I’d suggest a name like StackHasp. I suppose “hasp” is a bit of a non-obvious name (like my above mentioned “fob” which hasn’t seen any love ), but it fits remarkably well, since a hasp is a fastener that needs to be secured with a pin, and a hasp that hasn’t been pinned isn’t secure yet, which perfectly describes the role of the intermediate value required to make stack pinning work.
I’m not sure about PinBox though. I get that it’s a pin which is also a box, but the name suggests that it’s a box for pins rather than a box which is also a pin. Alternatives would be OwningPin by analogy to OwningRef, or PinningBox. These are of course longer, but I’m not sure length matters as much as for Pin.
Also, PinBox makes me think of PMBOK® Guide, but that’s neither here nor there.
That works too. It sort of suggests it’s a pin for boxes, but that’s closer to reality than a box for pins. There was also discussion of PinMut, so would that be MutPin through symmetry?
Somewhere along the line a reversed adjective order was adopted, so I feel a bit like I’m reading a heraldic blazon, like “a lion passant guardant or, holding in its dexter paw a pin mutable”. The precedent for it is probably 'Fn' [ 'Mut' | 'Once' | 'Box' ]. Other examples in the standard library are actually describing operations, so the modifiers are adverbs which can be in a trailing position. There’s also a conflicting precedent with RefCell and RefMut, with the adjective order flip-flopping essentially within the same construct.