# Add \`std::mem::{swap, replace, take}\` to the prelude

**URL:** <https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035>\
**Category:** libs\
**Created:** [February 11, 2021, 9:26pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035 "2021-02-11T21:26:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![cole-miller](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cole-miller/32/7607_2.png) [@cole-miller](https://internals.rust-lang.org/u/cole-miller)\
**Post date:** [February 11, 2021, 9:26pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/1 "2021-02-11T21:26:14Z")

</div>

I find myself using `std::mem::{swap, replace, take}` frequently. They're essential parts of the language that (imo) could use more visibility and deserve to be exported somewhere that's less obscure and quicker to name. I'd guess that adding them to the prelude would cause name collision/clarity issues, although I'd still support it personally. Alternatively, and less disruptively, they could be re-exported directly under `std` and `core` -- does that appeal to people?

[Edit: It's been pointed out that name collisions aren't in fact an issue here. So my preference is to just add these functions to the prelude.]

---

<div class="post-metadata">

**Author:** ![Nokel81](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nokel81/32/3966_2.png) [@Nokel81](https://internals.rust-lang.org/u/Nokel81)\
**Post date:** [February 11, 2021, 9:37pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/2 "2021-02-11T21:37:08Z")

</div>

Maybe as a less destructive means we could add `use std::mem;` to the prelude in the 2021 edition.

That way they are accessible as `mem::swap`, ... which I think is better than having all three functions.

---

<div class="post-metadata">

**Author:** ![cole-miller](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cole-miller/32/7607_2.png) [@cole-miller](https://internals.rust-lang.org/u/cole-miller)\
**Post date:** [February 11, 2021, 9:44pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/3 "2021-02-11T21:44:07Z")

</div>

That effectively adds `mem` as a new top-level namespace, which seems more disruptive than re-exporting some functions under `std`. And not hiding `swap` and co. inside `mem` (which is kind of an obscure location imo) was a significant motivation for my original suggestion.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [February 11, 2021, 9:46pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/4 "2021-02-11T21:46:37Z")

</div>

> [@cole-miller](#):
>
> I'd guess that adding them to the prelude would cause name collision/clarity issues, although I'd still support it personally.

I think it's ok, actually, since `use`d _item_s are preferred over prelude ones. (The problem is trait methods, which don't have this safety net, and thus cause ambiguity.)

I agree that `replace` is a quintessential Rust method, and would support having them in the prelude.

(I think that `drop` being there gives a potential precedent argument.)

> [@cole-miller](#):
>
> Alternatively, and less disruptively, they could be re-exported directly under `std` and `core` -- does that appeal to people?

I'm not a fan of that. Right now it's common to call them as `mem::replace` (with the `use std::mem;`) -- I think if we're going to encourage a convention change it should be all the way to `replace`, not to `std::replace`.

---

<div class="post-metadata">

**Author:** ![cole-miller](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cole-miller/32/7607_2.png) [@cole-miller](https://internals.rust-lang.org/u/cole-miller)\
**Post date:** [February 11, 2021, 9:54pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/5 "2021-02-11T21:54:31Z")

</div>

> [@scottmcm](#):
>
> I think it's ok, actually, since `use` d _item_ s are preferred over prelude ones.

My worry was that `swap`/`replace`/`take` in the prelude might collide with existing user-defined functions, not with the same functions imported from their canonical paths. But I'd be delighted if that's not a major concern after all.

> [@scottmcm](#):
>
> Right now it's common to call them as `mem::replace` (with the `use` )

Huh, I wasn't aware of that practice. `use std::mem;` has never appealed to me, because I don't like calling the functions as `mem::replace` etc., but apparently I'm in the minority.

---

<div class="post-metadata">

**Author:** ![Nokel81](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nokel81/32/3966_2.png) [@Nokel81](https://internals.rust-lang.org/u/Nokel81)\
**Post date:** [February 11, 2021, 10:00pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/6 "2021-02-11T22:00:44Z")

</div>

Given that `use std::mem;` is already common. And that I don't think that namespaced functions can conflict with trait functions would adding it to the prelude be a backwards compatible change?

---

<div class="post-metadata">

**Author:** ![cole-miller](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cole-miller/32/7607_2.png) [@cole-miller](https://internals.rust-lang.org/u/cole-miller)\
**Post date:** [February 11, 2021, 10:02pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/7 "2021-02-11T22:02:51Z")

</div>

~~If somebody's code defines a free function named `replace` then adding `std::mem::replace` to the prelude will break that module (right?). I don't know whether that's a problem in practice but it certainly _could_ occur.~~ Never mind, I just tried this on the playground with `drop` and there's no breakage -- TIL! Okay, in that case I support just adding these to the prelude in the 2021 edition.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [February 11, 2021, 10:46pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/8 "2021-02-11T22:46:45Z")

</div>

> [@cole-miller](#):
>
> Huh, I wasn't aware of that practice.

I guess I should clarify that I only know this anecdotally. It might be a property of the codebases I look at, not something common.

But here's part of a `rg '[^.a-zA-Z]replace\(' --type rust` in the rust repro, as an example:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/6/67809c0d52fe39aff1c9b225c278bf8bf6d95f1f.png)

> [@cole-miller](#):
>
> Never mind, I just tried this on the playground with `drop` and there's no breakage

Since I was also just doing it, here's a demo for anyone who wants to try at home:

```rust
mod uhoh {
    pub fn drop(x: i32) {
        dbg!(("yup, not the prelude one", x));
    }
}
use uhoh::drop;

fn main() {
    drop(4);
}

```

[https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=71f2b2c819ab9d47d29e88c04be058d5](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=71f2b2c819ab9d47d29e88c04be058d5)

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [February 11, 2021, 11:40pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/9 "2021-02-11T23:40:09Z")

</div>

> [@cole-miller](#):
>
> I find myself using `std::mem::{swap, replace, take}` frequently. They're essential parts of the language that (imo) could use more visibility and deserve to be exported somewhere that's less obscure and quicker to name.

Purely anecdotal, but the first time I ended up using `swap` for some sentinel pattern situation, I felt the need to go ask IRC if I was doing something bad or silly. Some combination of not having seen the pattern yet and it being not imported while living beside things like `transmute` and `forget`.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [February 12, 2021, 12:13am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/10 "2021-02-12T00:13:16Z")

</div>

I agree that these functions living in `mem` makes them "feel" scary. I don't think putting them in the prelude is the right way to demystify them either.

I almost always use `mem::swap` and other free functions by importing the namespace, not the free fun function. Personally, I do this for basically every free function, even my own. (I'm also writing C++ professionally for $gradschool right now, so maybe that's (anti)corroded my style preferences...)

If they were in the prelude, I'd get used to using them unprefixed. But I think the "better" solution is to address what makes the `mem` module "scary" in the first place. One of the most empowering things that Rust gives you is the ability to do things terrifying in less safe languages without worry, because tyck and borrowck have your back.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [February 12, 2021, 12:22am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/11 "2021-02-12T00:22:53Z")

</div>

Given that I don't even like `drop` being in the prelude, I _very much_ would not want this. I want to see where free functions come from, as it's not always immediately obvious what the context is.

---

<div class="post-metadata">

**Author:** ![cole-miller](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cole-miller/32/7607_2.png) [@cole-miller](https://internals.rust-lang.org/u/cole-miller)\
**Post date:** [February 12, 2021, 1:29am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/12 "2021-02-12T01:29:39Z")

</div>

De-mystifying `std::mem` sounds good to me, but there are also other other motivations for having `swap` etc. in the prelude:

- they're useful in a variety of situations, not just when doing detailed stuff with memory
- they should be prominently visible and easy to discover, because they solve a problem that comes up pretty regularly when writing Rust code and that can't readily be worked around
- typing out `std::mem::swap` (or adding an `import mem;` if you incline to that style) adds friction that I think should not exist here

I can sympathize with not liking free functions without a namespace. On the other hand, adding `swap` etc. to the prelude doesn't stop you from spelling out the full paths or importing `std::mem` in your code if you prefer that. (I can even imagine a Clippy lint for banning calls to free functions outside the current module without a namespace.)

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mbrubeck/32/174_2.png) [@mbrubeck](https://internals.rust-lang.org/u/mbrubeck)\
**Post date:** [February 12, 2021, 2:41am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/13 "2021-02-12T02:41:36Z")

</div>

I definitely agree that `std::mem::replace` is one of Rust's best-kept secrets, and that it should be more discoverable. I'm not sure how much the prelude would help with that goal, but it might.

As an aside: If I were designing a Rust-like language from scratch today, instead of an assignment operator I would include an infix operator like `a <- b` that is equivalent to `replace(&mut a, b)`, and perhaps `a <-> b` to mean `swap(&mut a, &mut b)`.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [February 12, 2021, 4:46am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/14 "2021-02-12T04:46:26Z")

</div>

> [@jhpratt](#):
>
> I want to see where free functions come from

Can you elaborate on this?

I'm curious if we could isolate what it is about _free functions_ that cause that desire. For example, do you have the same feelings about types (like `Vec`)? Or trait methods (like `.clone()`)? Would you prefer that, say, it be a `SwapExt` trait in the prelude so it would be `a.swap(&mut b)` instead of `swap(&mut a, &mut b)`? There's also been talk of perhaps adding `HashMap` to the prelude -- would that trigger the same objection?

> [@CAD97](#):
>
> If they were in the prelude, I'd get used to using them unprefixed.

I think this is a good summary of my instinct here. That they'd become kinda like "operators" in my head (as in Matt's aside), just alphabetic ones instead of symbolic ones. Or maybe "vocabulary words". So these shouldn't be that many of them -- I wouldn't want `create_dir_all` in the prelude, for example, even though the name makes it pretty clear even with an `fs::` prefix.

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [February 12, 2021, 5:35am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/15 "2021-02-12T05:35:12Z")

</div>

> [@mbrubeck](#):
>
> an infix operator like `a <- b` that is equivalent to `replace(&mut a, b)`

Would this be the default assignment in order to facilitate linear types?

---

<div class="post-metadata">

**Author:** ![H2CO3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/h2co3/32/2849_2.png) [@H2CO3](https://internals.rust-lang.org/u/H2CO3)\
**Post date:** [February 12, 2021, 5:44am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/16 "2021-02-12T05:44:45Z")

</div>

There are a lot of functions in `std::mem` with generic enough names that they might as well do something else (you can `replace` a lot of things in many ways). Hence, the practice of calling them as `mem::replace()` etc. emerged, so as to indicate that they are memory management primitives and do nothing funny.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [February 12, 2021, 7:24am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/17 "2021-02-12T07:24:48Z")

</div>

With the exception of `drop`, there aren't any free functions in the prelude (I suspected this, and a quick check confirmed it). Some traits that are applicable to _nearly everything_, like the associated traits for `derive`s, `From`/`Into`, `ToOwned`, etc. are also in the prelude. To me, that they're applicable to just about any program someone might want to write is the reason they are present. `drop`, on the other hand, is not as widely applicable. I just did a quick `rg "drop\("` over the directory I keep all my projects in; the only match was in `standback`, which is derived from stdlib. Said another way, I don't call `drop` anywhere at all in any of my Rust code.

Performing the same (limited) analysis for `std::mem::{swap, replace, take}`, there is all of one match wherein I swap a telemetry log out for an empty one. Checking for `as_mut()`, `as_ref()`, `into()`/`::into()`, `into_iter()`, `iter()`, `to_owned()`, `to_string()`, and `::from(_)` yields a cumulative 607 matches (nb: not lines). This does not include fully-qualified syntax for most of the methods. For reference, these projects combine to 26,834 lines of Rust code per `tokei`.

Macros are a different story that really isn't applicable here, as nothing being talked about is macros.

So as I've stated previously in other threads, I suppose the reason I'm opposed to it is primarily the lack of real-world usage in the areas of the projects I have cloned locally. I also personally believe that having the `mem::` prefix is preferred, but that's a style concern. I understand that other use cases would benefit from these methods being in the prelude in the same way that `drop` is, but ~1/27,000 is hardly comparable to ~1/44 in my real-world codebases.

Now that I am finishing typing this out, I realize that it's not really an argument against free functions being in the prelude, just that it's not used enough in my experience. But regardless, hopefully this helps somehow.

As a side note, I have excluded the rust and standback repositories that I have cloned locally from this data, as I'm fairly certain they are nowhere near representative of the average codebase.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [February 12, 2021, 8:29am UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/18 "2021-02-12T08:29:24Z")

</div>

> [@jhpratt](#):
>
> Now that I am finishing typing this out, I realize that it's not really an argument against free functions being in the prelude, just that it's not used enough in my experience. But regardless, hopefully this helps somehow.

That's great. It answers my core question of whether there's something about functions that needs to be considered differently. (I don't know whether `default()` might ever be in the prelude in addition to `Default`, but if there was something bad about functions it would be important to know.)

The concern over insufficient usage I always find hard to weigh, because it's just so hard to find a representative sample. Totally agree that `swap` is way less common than something like `.clone()`. But it would also be easy to have FSM-based code where `.to_string()` never shows up but [`replace` is common](https://internals.rust-lang.org/t/feedback-requested-book-on-api-type-patterns/13976/20).

I would definitely expect analysis like this to be welcome in any FCP about whether or not to do this. Personally I like them for their core "ownershipness", but I'm also not on the team that would have to approve a prelude addition. (AFAIK that's libs.)

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [February 12, 2021, 1:49pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/19 "2021-02-12T13:49:32Z")

</div>

Running an analysis like this over [crates.io](http://crates.io) and/or Rust GitHub repos (similar to how crater works) could potentially prove useful. For something like that, we'd probably want a tool that is actually aware of the types, such that aliases, fully-qualified calls, etc. are covered: I would imagine my trivial regex missed some edge cases.

No idea how this type of thing would be created, but it's an interesting idea that I'd help with. Any changes to the prelude beyond adding `TryFrom` and `TryInto` will almost certainly prove controversial, so having hard data could prove invaluable.

---

<div class="post-metadata">

**Author:** ![cole-miller](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cole-miller/32/7607_2.png) [@cole-miller](https://internals.rust-lang.org/u/cole-miller)\
**Post date:** [February 12, 2021, 5:28pm UTC](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035/20 "2021-02-12T17:28:08Z")

</div>

I can understand that motivation. But I see these functions as part of the core Rust "vocabulary" (to use @scottmcm's language), not specialized tools, and making them available unqualified seems like a reasonable way to reflect that in `std`.

[Next page](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035.md?page=2)
