# What about \`unwrap\_or\_from\` methods?

**URL:** <https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143>\
**Category:** libs\
**Created:** [April 12, 2020, 8:21am UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143 "2020-04-12T08:21:21Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aloso](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/aloso/32/5039_2.png) [@Aloso](https://internals.rust-lang.org/u/Aloso)\
**Post date:** [April 12, 2020, 8:21am UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/1 "2020-04-12T08:21:21Z")

</div>

I think it would be useful to have `Option::unwrap_or_from` and `Result::unwrap_or_from` methods, which call `From::from` on the fallback value if the value is `None`/`Err`.

For example, if you have an `Option<String>`, you could write

```rust
let _: String = option.unwrap_or_from("default value");

```

which would be equivalent to

```rust
let _: String = option.unwrap_or_else(|| String::from("default value"));

```

Do you think it's justified to add this to the standard library? Also, do you think that `unwrap_or_into` would be a better name?

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [April 12, 2020, 8:56am UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/2 "2020-04-12T08:56:48Z")

</div>

Could you elaborate on the use case for this, which would make it so common as to need a shorthand?

---

<div class="post-metadata">

**Author:** ![Aloso](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/aloso/32/5039_2.png) [@Aloso](https://internals.rust-lang.org/u/Aloso)\
**Post date:** [April 12, 2020, 9:08am UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/3 "2020-04-12T09:08:51Z")

</div>

`String` and `Vec` are the most common use cases I think. To get some data, I just cloned the rustc repository and searched for `.unwrap_or_else(`. Ripgrep found 430 usages, and at least 37 of them could be trivially converted to `unwrap_or_from` (ignoring the ones that could just use `unwrap_or`). That's fewer than I expected though.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [April 12, 2020, 10:08am UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/4 "2020-04-12T10:08:01Z")

</div>

In such a case the type to convert into should always be known to the compiler, so you could write the shorter `option.unwrap_or_else(|| "default value".into())` which is a fairer syntactic comparison.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [April 12, 2020, 10:47am UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/5 "2020-04-12T10:47:03Z")

</div>

This thread makes me wonder if there’s a strong reason against having

```rust
impl<T, F: FnOnce() -> T> From<F> for T {
    fn from(f: F) -> T { f() }
}

```

in the standard library. Then one could change `unwrap_or_else` (and lots of other API accepting `Fn() -> T` parameters) to be more general and wouldn’t need an additional `unwrap_or_from`. This would unfortunately, probably both would things technically be breaking changes though.

_Edit:_ Damn it, it conflicts with `From<T> for T` for some reason.

---

<div class="post-metadata">

**Author:** ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)\
**Post date:** [April 12, 2020, 1:22pm UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/6 "2020-04-12T13:22:14Z")

</div>

Yeah, someone could `impl FnOnce for Foo { type Output = Foo; ... }`, and then there'd be two competing ways to convert Foo to Foo.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [April 12, 2020, 1:32pm UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/7 "2020-04-12T13:32:54Z")

</div>

Yeah, I actually know that that's the conflict there, but it's a conflict that realistically should never happen.

Currently `Fn`-traits are still unstable, so it's actually impossible to get competing impls here, since a closure or `fn` will never have itself as `Output`. This means that if we would get some negative-impl feature or something else enabling us to prevent `T: FnOnce<(), Output = T>` (i.e. `T: FnOnce() -> T`) before stabilizing `Fn`-traits, then this conflict might still be possible to resolve.

_Edit:_ A bigger problem might be that we can already do some `impl From(fn() -> MyType) for MyType` instances currently, so that this whole idea becomes backwards-incompatible.

---

<div class="post-metadata">

**Author:** ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)\
**Post date:** [April 12, 2020, 1:39pm UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/8 "2020-04-12T13:39:47Z")

</div>

> [@steffahn](#):
>
> Currently `Fn` -traits are still unstable, so it's actually impossible to get competing impls here, since a closure or `fn` will never have itself as `Output` .

I mean, technically...

```rust
use std::any::Any;

fn foo()->impl Any {
  foo
}

fn main() {
    let bar = None.unwrap_or_else(foo);
}

```

Although I'm not actually sure how `foo::Output` would be defined here given the existential type

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [April 12, 2020, 1:48pm UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/9 "2020-04-12T13:48:39Z")

</div>

I think the biggest problem with this proposal is that taking it further would imply the need to add `unwrap_or_else_xyz` for all kinds of common traits with method `xyz` and each for both `Option` and `Result`, and all that just to be able to write `my_val.unwrap_or_else_xyz(foo)` instead of `my_val.unwrap_or_else(||foo.xyz())`.

_Under this naming scheme `unwrap_or_from` would be called `unwrap_or_else_into`._

Hence, you could propose `unwrap_or_else_to_owned` next, and then `unwrap_or_else_to_string` and so on.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [April 12, 2020, 4:12pm UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/10 "2020-04-12T16:12:36Z")

</div>

I don't like heap-allocating string literals when it's avoidable, so I prefer converting the other way. This already works, and if you don't need the owned type, it's more efficient too:

```rust
let s: &str = string_option.as_deref().unwrap_or("default value");

```

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [July 11, 2020, 4:23pm UTC](https://internals.rust-lang.org/t/what-about-unwrap-or-from-methods/12143/11 "2020-07-11T16:23:24Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
