Skip to content

Commit c083dca

Browse files
committed
Merge remote-tracking branch 'aturon/ownership-variants'
2 parents 8194815 + 1851c2f commit c083dca

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

active/0000-ownership-variants.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
- Start Date: (fill me in with today's date, 2014-08-13)
2+
- RFC PR #: (leave this empty)
3+
- Rust Issue #: (leave this empty)
4+
5+
# Summary
6+
7+
This is a *conventions RFC* for settling naming conventions when there
8+
are by value, by reference, and by mutable reference variants of an
9+
operation.
10+
11+
# Motivation
12+
13+
Currently the libraries are not terribly consistent about how to
14+
signal mut variants of functions; sometimes it is by a `mut_` prefix,
15+
sometimes a `_mut` suffix, and occasionally with `_mut_` appearing in
16+
the middle. These inconsistencies make APIs difficult to remember.
17+
18+
While there are arguments in favor of each of the positions, we stand
19+
to gain a lot by standardizing, and to some degree we just need to
20+
make a choice.
21+
22+
# Detailed design
23+
24+
Functions often come in multiple variants: immutably borrowed, mutably
25+
borrowed, and owned.
26+
27+
The canonical example is iterator methods:
28+
29+
- `iter` works with immutably borrowed data
30+
- `mut_iter` works with mutably borrowed data
31+
- `move_iter` works with owned data
32+
33+
For iterators, the "default" (unmarked) variant is immutably borrowed.
34+
In other cases, the default is owned.
35+
36+
The proposed rules depend on which variant is the default, but use
37+
*suffixes* to mark variants in all cases.
38+
39+
## The rules
40+
41+
### Immutably borrowed by default
42+
43+
If `foo` uses/produces an immutable borrow by default, use:
44+
45+
* The `_mut` suffix (e.g. `foo_mut`) for the mutably borrowed variant.
46+
* The `_move` suffix (e.g. `foo_move`) for the owned variant.
47+
48+
A consequence is that the iterator methods become: `iter`, `iter_mut`,
49+
and `iter_move`.
50+
51+
**NOTE**: This convention covers only the *method* names for
52+
iterators, not the names of the iterator types. That will be the
53+
subject of a follow up RFC.
54+
55+
### Owned by default
56+
57+
If `foo` uses/produces owned data by default, use:
58+
59+
* The `_ref` suffix (e.g. `foo_ref`) for the immutably borrowed variant.
60+
* The `_mut` suffix (e.g. `foo_mut`) for the mutably borrowed variant.
61+
62+
### Exceptions
63+
64+
For mutably borrowed variants, if the `mut` qualifier is part of a
65+
type name (e.g. `as_mut_slice`), it should appear as it would appear
66+
in the type.
67+
68+
### References to type names
69+
70+
Some places in the current libraries, we say things like `as_ref` and
71+
`as_mut`, and others we say `get_ref` and `get_mut_ref`.
72+
73+
Proposal: generally standardize on `mut` as a shortening of `mut_ref`.
74+
75+
76+
## The rationale
77+
78+
### Why suffixes?
79+
80+
Using a suffix makes it easier to visually group variants together,
81+
especially when sorted alphabetically. It puts the emphasis on the
82+
functionality, rather than the qualifier.
83+
84+
### Why `move`?
85+
86+
Historically, Rust has used `move` as a way to signal ownership
87+
transfer and to connect to C++ terminology. The main disadvantage is
88+
that it does not emphasize ownership, which is our current narrative.
89+
On the other hand, in Rust all data is owned, so using `_owned` as a
90+
qualifier is a bit strange.
91+
92+
The `Copy` trait poses a problem for any terminology about ownership
93+
transfer. The proposed mental model is that with `Copy` data you are
94+
"moving a copy".
95+
96+
See Alternatives for more discussion.
97+
98+
### Why `mut` rather then `mut_ref`?
99+
100+
It's shorter, and pairs like `as_ref` and `as_mut` have a pleasant harmony
101+
that doesn't place emphasis on one kind of reference over the other.
102+
103+
# Alternatives
104+
105+
## Prefix or mixed qualifiers
106+
107+
Using prefixes for variants is another possibility, but there seems to
108+
be little upside.
109+
110+
It's possible to rationalize our current mix of prefixes and suffixes
111+
via
112+
[grammatical distinctions](https://github.com/rust-lang/rust/issues/13660#issuecomment-43576378),
113+
but this seems overly subtle and complex, and requires a strong
114+
command of English grammar to work well.
115+
116+
## No suffix exception
117+
118+
The rules here make an exception when `mut` is part of a type name, as
119+
in `as_mut_slice`, but we could instead *always* place the qualifier
120+
as a suffix: `as_slice_mut`. This would make APIs more consistent in
121+
some ways, less in others: conversion functions would no longer
122+
consistently use a transcription of their type name.
123+
124+
This is perhaps not so bad, though, because as it is we often
125+
abbreviate type names. In any case, we need a convention (separate
126+
RFC) for how to refer to type names in methods.
127+
128+
## `owned` instead of `move`
129+
130+
The overall narrative about Rust has been evolving to focus on
131+
*ownership* as the essential concept, with borrowing giving various
132+
lesser forms of ownership, so `_owned` would be a reasonable
133+
alternative to `_move`.
134+
135+
On the other hand, the `ref` variants do not say "borrowed", so in
136+
some sense this choice is inconsistent. In addition, the terminology
137+
is less familiar to those coming from C++.
138+
139+
## `val` instead of `owned`
140+
141+
Another option would be `val` or `value` instead of `owned`. This
142+
suggestion plays into the "by reference" and "by value" distinction,
143+
and so is even more congruent with `ref` than `move` is. On the other
144+
hand, it's less clear/evocative than either `move` or `owned`.
145+
146+
## `into_iter`
147+
148+
For the case of iteration, at least, it would make some sense to
149+
signal ownership transfer by treating the owned version as a
150+
conversion, `into_iter`. The main downside is that it would go against
151+
the general convention for ownership variants (and cannot be used as
152+
the general convention, because not all cases can be seen as
153+
conversions).
154+
155+
Moreover, it's strange to see just the owning variant as a conversion
156+
-- why not `as_iter`, `as_iter_mut`, and `into_iter`?

0 commit comments

Comments
 (0)