- Start Date: 2014-08-28
- RFC PR #: rust-lang/rfcs#199
- Rust Issue #: rust-lang/rust#16810
This is a conventions RFC for settling naming conventions when there are by value, by reference, and by mutable reference variants of an operation.
Currently the libraries are not terribly consistent about how to
signal mut variants of functions; sometimes it is by a
_mut suffix, and occasionally with
_mut_ appearing in
the middle. These inconsistencies make APIs difficult to remember.
While there are arguments in favor of each of the positions, we stand to gain a lot by standardizing, and to some degree we just need to make a choice.
Functions often come in multiple variants: immutably borrowed, mutably borrowed, and owned.
The canonical example is iterator methods:
iterworks with immutably borrowed data
mut_iterworks with mutably borrowed data
move_iterworks with owned data
For iterators, the "default" (unmarked) variant is immutably borrowed. In other cases, the default is owned.
The proposed rules depend on which variant is the default, but use suffixes to mark variants in all cases.
Immutably borrowed by default
foo uses/produces an immutable borrow by default, use:
foo_mut) for the mutably borrowed variant.
foo_move) for the owned variant.
However, in the case of iterators, the moving variant can also be
understood as an
for x in v.into_iter()
reads arguably better than
for x in v.iter_move(), so the convention is
NOTE: This convention covers only the method names for iterators, not the names of the iterator types. That will be the subject of a follow up RFC.
Owned by default
foo uses/produces owned data by default, use:
foo_ref) for the immutably borrowed variant.
foo_mut) for the mutably borrowed variant.
For mutably borrowed variants, if the
mut qualifier is part of a
type name (e.g.
as_mut_slice), it should appear as it would appear
in the type.
References to type names
Some places in the current libraries, we say things like
as_mut, and others we say
Proposal: generally standardize on
mut as a shortening of
Using a suffix makes it easier to visually group variants together, especially when sorted alphabetically. It puts the emphasis on the functionality, rather than the qualifier.
Historically, Rust has used
move as a way to signal ownership
transfer and to connect to C++ terminology. The main disadvantage is
that it does not emphasize ownership, which is our current narrative.
On the other hand, in Rust all data is owned, so using
_owned as a
qualifier is a bit strange.
Copy trait poses a problem for any terminology about ownership
transfer. The proposed mental model is that with
Copy data you are
"moving a copy".
See Alternatives for more discussion.
mut rather then
It's shorter, and pairs like
as_mut have a pleasant harmony
that doesn't place emphasis on one kind of reference over the other.
Prefix or mixed qualifiers
Using prefixes for variants is another possibility, but there seems to be little upside.
It's possible to rationalize our current mix of prefixes and suffixes via grammatical distinctions, but this seems overly subtle and complex, and requires a strong command of English grammar to work well.
No suffix exception
The rules here make an exception when
mut is part of a type name, as
as_mut_slice, but we could instead always place the qualifier
as a suffix:
as_slice_mut. This would make APIs more consistent in
some ways, less in others: conversion functions would no longer
consistently use a transcription of their type name.
This is perhaps not so bad, though, because as it is we often abbreviate type names. In any case, we need a convention (separate RFC) for how to refer to type names in methods.
owned instead of
The overall narrative about Rust has been evolving to focus on
ownership as the essential concept, with borrowing giving various
lesser forms of ownership, so
_owned would be a reasonable
On the other hand, the
ref variants do not say "borrowed", so in
some sense this choice is inconsistent. In addition, the terminology
is less familiar to those coming from C++.
val instead of
Another option would be
value instead of
suggestion plays into the "by reference" and "by value" distinction,
and so is even more congruent with
move is. On the other
hand, it's less clear/evocative than either