-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Re-export Cow from prelude #2672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
- Feature Name: moooooooooooooooo | ||
- Start Date: 2019-04-01 | ||
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) | ||
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
Re-export `std::borrow::Cow` from the standard library, along with each of its | ||
variants, to encourage more widespread use. To avoid backwards compatibility | ||
issues, these types/variants will need to be exported using more unique aliases. | ||
|
||
# Motivation/Explanation | ||
|
||
`std::borrow::Cow` is one of the most under-used portions of the standard | ||
library. Many issues that newcomers understanding ownership could be improved if | ||
`Cow` were used more prolifically throughout the ecosystem. The easiest way for | ||
us to encourage this is to remove the need to explicitly import `Cow` by | ||
exporting it from prelude. | ||
|
||
Anything exported in the prelude is generally expected to refer to what it | ||
refers to in the prelude. If a crate defines its own type called `Ok`, it will | ||
likely be confusing to readers, and will break any macros which don't refer to | ||
`std::result::Result::Ok` through its full path. | ||
|
||
Unfortunately, `Cow` is an extremely overloaded term in Rust today, so we can't | ||
reasonably export that identifier in the prelude. Applications today might be | ||
using this name to refer to: | ||
|
||
- California, Oregon, Washington (the most common usage) | ||
- Can of Worms | ||
- City of Waterloo | ||
- Crush of the Week | ||
- Container on Wheels | ||
- Cost of Waste | ||
|
||
to name a few. For this reason, the re-export of this type must be something | ||
which is unlikely or impossible to appear in Rust programs today. For this | ||
reason, the export will be defined as `pub use core::borrow::Cow as 🐄;`. As the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide the code point value for 🐄 just like 🐮, ☭, Ferris and Steve below |
||
`non_ascii_idents` feature is not yet stable, this alias cannot possibly shadow | ||
any type defined in stable Rust today. By defining this non-ascii identifier to | ||
mean `Cow` today, we can ensure that it is associated with this type, and does | ||
not become a common term for other uses as `Cow` clearly already is today. | ||
|
||
Every enum exported in the prelude today also exports its variants at the top | ||
level (e.g. `Option`, `Result`, etc). Clearly we should do the same for `🐄`. | ||
However, similar to how we can't reasonably begin exporting `Cow` from the | ||
prelude today, we clearly can't export `Borrowed` or `Owned` either (the | ||
alternative uses of these terms should be clear and thus are not listed here). | ||
|
||
This RFC proposes two potential alternatives for `Borrowed` and `Owned`. These | ||
are both presented as equal options, and this RFC does not propose either as a | ||
superior option. It is proposed that both be implemented, and the more popular | ||
choice be chosen during the stabilization period. | ||
|
||
Option A is as follows: | ||
|
||
`Cow::Owned` would be exported as U+1F42E COW FACE, `🐮`. The choice of this | ||
identifier should be clear -- A value of variant `🐮` has been copied for write, | ||
or "cowed". We don't believe that the similarities between 🐄 and 🐮 will be | ||
confusing in practice, all Rust developers will clearly pronounce the former | ||
"cow" and the latter "owned/cowed". | ||
|
||
`Cow::Borrowed` would be exported as U+262D HAMMER AND SICKLE, `☭`. This is | ||
because ownership is theft. No further explanation is required. | ||
|
||
The main drawback to the use of these characters is that 🐮 resides outside of | ||
the Unicode BMP, and thus requires multiple code units to represent in UTF-16. | ||
Because UTF-16 is a fixed width encoding, this may be confusing to many | ||
developers. For this reason, the following alternative is proposed: | ||
|
||
As no identifier or glyph today meets the needs of sufficiently representing the | ||
embodiment of `Borrowed` and `Owned`, while being sufficiently unique from | ||
identifiers which may be used in Rust today, two characters from the Unicode | ||
private use area will be used instead. | ||
|
||
`Borrowed` will be exported as U+FF8E, and `Owned` will be exported as U+FF8F. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ホ and マ do not look like private use characters. The PUA in BMP is U+E000 – U+F8FF. |
||
Since both of these characters reside on the BMP, they can both be represented | ||
as expected in the fixed width UTF-16 encoding. As these characters are not | ||
displayed in most fonts, we will need to define a conventional representation of | ||
these characters. We expect that Rustup will be updated to patch all system fonts | ||
for these characters upon installation. This seems to be a reasonable solution | ||
to this problem. | ||
|
||
The conventional display of these characters will be defined as: | ||
|
||
`Borrowed` will be an image of Ferris, the official unofficial Rust mascot. | ||
Borrowing is a uniquely Rust concept, what better image to represent this than | ||
our language's mascot. | ||
|
||
`Owned` will be displayed as a scaled down version of [this picture of Steve | ||
Klabnik wearing eclipse glasses standing in front of a nuclear | ||
explosion](../steve-nuke.png). Because it owns. | ||
|
||
Again, these options are presented with no preference for one or the other, and | ||
it is expected the community will naturally pick one during the stabilization | ||
process. | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
While there are no drawbacks to the feature overall, this does slightly | ||
complicate the `non_ascii_idents` feature. Since it is expected these re-exports | ||
will become commonly used after stabilization, we will need to ensure that 🐄 | ||
and whatever characters are chosen for `Borrowed` and `Owned` are excluded from | ||
the `non_ascii_idents` lint. This means that Rust will effectively consider 🐄 | ||
to be ascii (note that whether this should affect the behavior of | ||
`(str|char)::is_ascii` is out of scope of this RFC, though no drawbacks to | ||
defining `"🐄".is_ascii() == true` are immediately apparent). | ||
|
||
Additionally, we must ensure that 🐄 and 🐮 do not trigger the | ||
`confusable_idents` lint. | ||
|
||
# Rationale and alternatives | ||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
- Continue to write `use std::borrow::Cow`, and wallow in sorrow | ||
- Export these types from the prelude, but continue to use incredibly boring | ||
terms like "Cow", "Borrowed", and "Owned" | ||
|
||
# Prior art | ||
[prior-art]: #prior-art | ||
|
||
We will be trailblazers as the first programming language to define 🐄 in its | ||
standard library. | ||
|
||
# Unresolved questions | ||
[unresolved-questions]: #unresolved-questions | ||
|
||
- Should we also define `fn moo(self)` as a conventient alias for | ||
`🐄::from(expr)`? | ||
|
||
# Future possibilities | ||
[future-possibilities]: #future-possibilities | ||
|
||
As this feature becomes widely adopted, we can introduce a `boring_cow` lint to | ||
prevent the previous path from being used, potentially even deprecating it in | ||
Rust 2021. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The author seems unaware that a common meaning of COW in computer science is “copy on write”, a common optimization to avoid wasting space/time when making copies of some object.
For example, in Unix-based operating systems, COW is used as an optimization when forking a process. Rather than copying the contents of all memory to the new process’s address space, the kernel orders a new computer for the user and runs the new child process on the new computer. When writes are done to the address space on the child process, they are copied to the old conputer so the kernel is aware of them (hence the name “copy on write”).