1
- - Feature Name: convert_identity
1
+ - Feature Name: ` convert_identity `
2
2
- Start Date: 2018-01-19
3
3
- RFC PR: (leave this empty)
4
4
- Rust Issue: (leave this empty)
5
5
6
6
# Summary
7
7
[ summary ] : #summary
8
8
9
- Adds an identity function ` pub const fn identity<T>(x: T) -> T { x } ` as
10
- ` core::convert::identity ` . The function is also re-exported to
11
- ` std::convert::identity ` as well as the prelude of
12
- both libcore and libstd.
9
+ Adds an identity function ` pub const fn identity<T>(x: T) -> T { x } `
10
+ as ` core::convert::identity ` . The function is also re-exported to
11
+ ` std::convert::identity ` .
13
12
14
13
# Motivation
15
14
[ motivation ] : #motivation
@@ -61,6 +60,10 @@ let concatenated = iter_iter.flat_map(identity).collect::<Vec<_>>();
61
60
assert_eq! (vec! [1 , 3 , 4 , 5 , 6 ], concatenated );
62
61
```
63
62
63
+ While the standard library has recently added ` Iterator::flatten ` ,
64
+ which you should use instead, to achieve the same semantics, similar situations
65
+ are likely in the wild and the ` identity ` function can be used in those cases.
66
+
64
67
### Using ` identity ` to keep the ` Some ` variants of an iterator of ` Option<T> `
65
68
66
69
We can keep all the maybe variants by simply ` iter.filter_map(identity) ` .
@@ -93,8 +96,8 @@ Here are a few examples of the identity function being defined and used:
93
96
+ https://docs.rs/tool/0.2.0/tool/fn.id.html
94
97
+ https://github.com/hephex/api/blob/ef67b209cd88d0af40af10b4a9f3e0e61a5924da/src/lib.rs
95
98
96
- There's a smattering of more examples. To reduce duplication, it
97
- should be provided in the standard library as a common place it is defined.
99
+ There's a smattering of more examples. To reduce duplication,
100
+ it should be provided in the standard library as a common place it is defined.
98
101
99
102
## Precedent from other languages
100
103
@@ -114,30 +117,6 @@ their standard libraries, among these are:
114
117
+ [ Agda] ( http://www.cse.chalmers.se/~nad/repos/lib/src/Function.agda )
115
118
+ [ Elm] ( http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#identity )
116
119
117
- ## The case for inclusion in the prelude
118
-
119
- Let's compare the effort required, assuming that each letter
120
- typed has a uniform cost wrt. effort.
121
-
122
- ``` rust
123
- use std :: convert :: identity; iter . filter_map (identity )
124
-
125
- fn identity <T >(x : T ) -> T { x } iter . filter_map (identity )
126
-
127
- iter . filter_map (:: std :: convert :: identity )
128
-
129
- iter . filter_map (identity )
130
- ```
131
-
132
- Comparing the length of these lines, we see that there's not much difference in
133
- length when defining the function yourself or when importing or using an absolute
134
- path. But the prelude-using variant is considerably shorter. To encourage the
135
- use of the function, exporting to the prelude is therefore a good idea.
136
-
137
- In addition, there's an argument to be made from similarity to other things in
138
- ` core::convert ` as well as ` drop ` all of which are in the prelude. This is
139
- especially relevant in the case of ` drop ` which is also a trivial function.
140
-
141
120
# Guide-level explanation
142
121
[ guide-level-explanation ] : #guide-level-explanation
143
122
@@ -151,8 +130,7 @@ defines it as:
151
130
pub const fn identity <T >(x : T ) -> T { x }
152
131
```
153
132
154
- This function is also re-exported to ` std::convert::identity ` as well as
155
- the prelude of both libcore and libstd.
133
+ This function is also re-exported to ` std::convert::identity ` .
156
134
157
135
It is important to note that the input ` x ` passed to the function is
158
136
moved since Rust uses move semantics by default.
@@ -162,7 +140,7 @@ moved since Rust uses move semantics by default.
162
140
163
141
An identity function defined as ` pub const fn identity<T>(x: T) -> T { x } `
164
142
exists as ` core::convert::identity ` . The function is also re-exported as
165
- ` std::convert::identity ` as well as the prelude of both libcore and libstd.
143
+ ` std::convert::identity ` -
166
144
167
145
Note that the identity function is not always equivalent to a closure
168
146
such as ` |x| x ` since the closure may coerce ` x ` into a different type
@@ -188,16 +166,46 @@ phrase. Meanwhile, `mem` does not relate to `identity` other than that both
188
166
deal with move semantics. Therefore, ` convert ` is the better choice. Including
189
167
it in ` mem ` is still an alternative, but as explained, it isn't fitting.
190
168
191
- The rationale for including this in the prelude has been previously
192
- explained in the [ motivation] section. It is an alternative to not do that.
193
- If the function is not in the prelude, the utility is so low that it may
194
- be a better idea to not add the function at all.
195
-
196
169
Naming the function ` id ` instead of ` identity ` is a possibility.
197
170
This name is however ambiguous with * "identifier"* and less clear
198
171
wherefore ` identifier ` was opted for.
199
172
200
173
# Unresolved questions
201
174
[ unresolved ] : #unresolved-questions
202
175
203
- There are no unresolved questions.
176
+ There are no unresolved questions.
177
+
178
+ # Possible future work
179
+
180
+ A previous iteration of this RFC proposed that the ` identity ` function
181
+ should be added to prelude of both libcore and libstd.
182
+ However, the library team decided that for the time being, it was not sold on
183
+ this inclusion. As we gain usage experience with using this function,
184
+ it is possible to revisit this in the future if the team chances its mind.
185
+
186
+ The section below details, for posterity,
187
+ the argument for inclusion that was previously in the [ motivation] .
188
+
189
+ ## The case for inclusion in the prelude
190
+
191
+ Let's compare the effort required, assuming that each letter
192
+ typed has a uniform cost with respect to effort.
193
+
194
+ ``` rust
195
+ use std :: convert :: identity; iter . filter_map (identity )
196
+
197
+ fn identity <T >(x : T ) -> T { x } iter . filter_map (identity )
198
+
199
+ iter . filter_map (:: std :: convert :: identity )
200
+
201
+ iter . filter_map (identity )
202
+ ```
203
+
204
+ Comparing the length of these lines, we see that there's not much difference in
205
+ length when defining the function yourself or when importing or using an absolute
206
+ path. But the prelude-using variant is considerably shorter. To encourage the
207
+ use of the function, exporting to the prelude is therefore a good idea.
208
+
209
+ In addition, there's an argument to be made from similarity to other things in
210
+ ` core::convert ` as well as ` drop ` all of which are in the prelude. This is
211
+ especially relevant in the case of ` drop ` which is also a trivial function.
0 commit comments