Skip to content

Commit 088860d

Browse files
committed
rfc, convert-id: move prelude inclusion to possible-future-work.
1 parent 1c8c20c commit 088860d

File tree

1 file changed

+48
-40
lines changed

1 file changed

+48
-40
lines changed

text/0000-convert-id.md

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
- Feature Name: convert_identity
1+
- Feature Name: `convert_identity`
22
- Start Date: 2018-01-19
33
- RFC PR: (leave this empty)
44
- Rust Issue: (leave this empty)
55

66
# Summary
77
[summary]: #summary
88

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`.
1312

1413
# Motivation
1514
[motivation]: #motivation
@@ -61,6 +60,10 @@ let concatenated = iter_iter.flat_map(identity).collect::<Vec<_>>();
6160
assert_eq!(vec![1, 3, 4, 5, 6], concatenated);
6261
```
6362

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+
6467
### Using `identity` to keep the `Some` variants of an iterator of `Option<T>`
6568

6669
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:
9396
+ https://docs.rs/tool/0.2.0/tool/fn.id.html
9497
+ https://github.com/hephex/api/blob/ef67b209cd88d0af40af10b4a9f3e0e61a5924da/src/lib.rs
9598

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.
98101

99102
## Precedent from other languages
100103

@@ -114,30 +117,6 @@ their standard libraries, among these are:
114117
+ [Agda](http://www.cse.chalmers.se/~nad/repos/lib/src/Function.agda)
115118
+ [Elm](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#identity)
116119

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-
141120
# Guide-level explanation
142121
[guide-level-explanation]: #guide-level-explanation
143122

@@ -151,8 +130,7 @@ defines it as:
151130
pub const fn identity<T>(x: T) -> T { x }
152131
```
153132

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`.
156134

157135
It is important to note that the input `x` passed to the function is
158136
moved since Rust uses move semantics by default.
@@ -162,7 +140,7 @@ moved since Rust uses move semantics by default.
162140

163141
An identity function defined as `pub const fn identity<T>(x: T) -> T { x }`
164142
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`-
166144

167145
Note that the identity function is not always equivalent to a closure
168146
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
188166
deal with move semantics. Therefore, `convert` is the better choice. Including
189167
it in `mem` is still an alternative, but as explained, it isn't fitting.
190168

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-
196169
Naming the function `id` instead of `identity` is a possibility.
197170
This name is however ambiguous with *"identifier"* and less clear
198171
wherefore `identifier` was opted for.
199172

200173
# Unresolved questions
201174
[unresolved]: #unresolved-questions
202175

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

Comments
 (0)