From 74d9976443757d4a0fd780f6079b91a71eab04f9 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 5 Sep 2019 12:22:27 +0100 Subject: [PATCH 1/6] Initial proposal for `bool_to_option` --- text/0000-bool-to-option.md | 106 ++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 text/0000-bool-to-option.md diff --git a/text/0000-bool-to-option.md b/text/0000-bool-to-option.md new file mode 100644 index 00000000000..0b4058b7f4a --- /dev/null +++ b/text/0000-bool-to-option.md @@ -0,0 +1,106 @@ +- Feature Name: `bool_to_option` +- Start Date: 2019-09-05 +- 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 + +Add methods to `bool` for converting to an `Option`, given a `t: T`, where `true` maps +to `Some(t)` and `false` maps to `None`, abstracting the following common pattern in Rust. + +```rust +if some_condition { + Some(t) +} else { + None +} +``` + +# Motivation +[motivation]: #motivation + +This is an +[extremely common pattern](https://sourcegraph.com/search?q=repogroup%3Acrates+%2Felse%5Cs*%7B%5Cs*None%5Cs*%7D%2F+count%3A1000) +in Rust code, but is quite verbose, taking several lines to achieve something with only two important +data: the `bool` and the `T`. If we instead collapse the expression on to a single line, the legibility of the code is reduced. In +addition, chaining a conversion from a `bool` to an `Option` is inconvenient in this form and +usually requires binding an extra variable to remain readable. Abstracting this common pattern into +a method will make code more readable and require less repetitive typing on the user's part. + +A method for converting from `bool` to `Option` has been requested several times in the past [[1]](https://github.com/rust-lang/rfcs/pull/2180) [[2]](https://github.com/rust-lang/rust/issues/50523) [[3]](https://github.com/rust-lang/rfcs/issues/2606) in the past and shows a significant desire +from users. + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +Following this proposal, we will add two methods to `bool`: + +```rust +impl bool { + fn then(self, t: T) -> Option { + if self { + Some(t) + } else { + None + } + } + + fn then_with T>(self, f: F) -> Option { + if self { + Some(f()) + } else { + None + } + } +} +``` + +The primitive type `bool` currently has no methods, so it will be necessary to add support similarly to other primitive types that do have methods, like [`char`](https://doc.rust-lang.org/src/core/char/methods.rs.html#11-1393). + +# Drawbacks +[drawbacks]: #drawbacks + +Save the usual drawbacks of adding a new method to the standard library, there are no +drawbacks. + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +The implementations here are the only reasonable ones. + +The following names have been suggested in the past. The choice in this proposal has been made to +avoid possible confusion (e.g. avoiding a name that suggests a conversion from `bool` to +`Option<()>` rather than `Option`), and to be consist with existing naming conventions (e.g. +`then_with` rather than `then_do` to be consist with methods such as `get_or_insert_with`), +but ultimately comes down to personal preference. + +- [`then` and `then_do`](https://github.com/rust-lang/rfcs/pull/2180#issuecomment-350498489) +- [`some`](https://github.com/rust-lang/rfcs/issues/2606#issue-387773675) +- [`as_some` and `as_some_from`](https://docs.rs/boolinator/2.4.0/boolinator/trait.Boolinator.html) +- [`to_opt` or `to_option`](https://github.com/rust-lang/rfcs/issues/2606#issuecomment-476019577) +- [`some_if` and `lazy_if`](https://github.com/rust-lang/rfcs/pull/2180) + +This functionality could instead be provided by a crate (e.g. +[boolinator](https://docs.rs/boolinator/2.4.0/boolinator/)), but this functionality is commonly +desired and an obvious candidate for the standard library, where an external crate for such simple +functionality is not convenient. + +# Prior art +[prior-art]: #prior-art + +- Jane Street's OCaml Core library contains a +[`some_if`](https://ocaml.janestreet.com/ocaml-core/109.55.00/tmp/core_kernel/Option.html#VALsome_if) +method on `Option`. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +None. + +# Future possibilities +[future-possibilities]: #future-possibilities + +Methods for converting from a `bool` to a `Result`, e.g. `then_else` and `then_else_with`, +would be obvious candidates for inclusion into the standard library, which could also be included +as an addendum to this proposal if desire is expressed. From e271d7c218790593cce095cc3605c6c30d190eae Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 5 Sep 2019 13:35:13 +0100 Subject: [PATCH 2/6] Clarify some segments --- text/0000-bool-to-option.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/text/0000-bool-to-option.md b/text/0000-bool-to-option.md index 0b4058b7f4a..b2e1c9f0bea 100644 --- a/text/0000-bool-to-option.md +++ b/text/0000-bool-to-option.md @@ -22,14 +22,18 @@ if some_condition { This is an [extremely common pattern](https://sourcegraph.com/search?q=repogroup%3Acrates+%2Felse%5Cs*%7B%5Cs*None%5Cs*%7D%2F+count%3A1000) -in Rust code, but is quite verbose, taking several lines to achieve something with only two important -data: the `bool` and the `T`. If we instead collapse the expression on to a single line, the legibility of the code is reduced. In -addition, chaining a conversion from a `bool` to an `Option` is inconvenient in this form and -usually requires binding an extra variable to remain readable. Abstracting this common pattern into -a method will make code more readable and require less repetitive typing on the user's part. - -A method for converting from `bool` to `Option` has been requested several times in the past [[1]](https://github.com/rust-lang/rfcs/pull/2180) [[2]](https://github.com/rust-lang/rust/issues/50523) [[3]](https://github.com/rust-lang/rfcs/issues/2606) in the past and shows a significant desire -from users. +in Rust code, but is quite verbose, taking several lines to achieve something with only two +important data: the `bool` and the `T`. If we instead collapse the expression on to a single line by +simply removing newlines (i.e. `if some_condition { Some(t) } else { None }`), the legibility of the +code is reduced. In addition, chaining a conversion from a `bool` to an `Option` is inconvenient +in this form and usually requires binding an extra variable to remain readable. Abstracting this +common pattern into a method will make code more readable and require less repetitive typing on the +user's part. + +A method for converting from `bool` to `Option` has been requested several times in the past +[[1]](https://github.com/rust-lang/rfcs/pull/2180) +[[2]](https://github.com/rust-lang/rust/issues/50523) +[[3]](https://github.com/rust-lang/rfcs/issues/2606) and shows a significant desire from users. # Reference-level explanation [reference-level-explanation]: #reference-level-explanation @@ -56,7 +60,9 @@ impl bool { } ``` -The primitive type `bool` currently has no methods, so it will be necessary to add support similarly to other primitive types that do have methods, like [`char`](https://doc.rust-lang.org/src/core/char/methods.rs.html#11-1393). +The primitive type `bool` currently has no methods, so it will be necessary to add support similarly +to other primitive types that do have methods, like +[`char`](https://doc.rust-lang.org/src/core/char/methods.rs.html#11-1393). # Drawbacks [drawbacks]: #drawbacks From 66766338c1329ba06dfa91dc115ef2a7b44e154f Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 6 Sep 2019 11:37:35 +0100 Subject: [PATCH 3/6] Mention `#[lang = "bool"]` --- text/0000-bool-to-option.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/0000-bool-to-option.md b/text/0000-bool-to-option.md index b2e1c9f0bea..140ba3a1d8e 100644 --- a/text/0000-bool-to-option.md +++ b/text/0000-bool-to-option.md @@ -62,7 +62,8 @@ impl bool { The primitive type `bool` currently has no methods, so it will be necessary to add support similarly to other primitive types that do have methods, like -[`char`](https://doc.rust-lang.org/src/core/char/methods.rs.html#11-1393). +[`char`](https://doc.rust-lang.org/src/core/char/methods.rs.html#11-1393). This will require the +addition of a new lang item: `#[lang = "bool"]`. # Drawbacks [drawbacks]: #drawbacks From 93a2c22a7dd39477d6ad5f93e0849aab4b47bfe5 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 7 Sep 2019 15:53:11 +0100 Subject: [PATCH 4/6] Add mention of reference implementation --- text/0000-bool-to-option.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text/0000-bool-to-option.md b/text/0000-bool-to-option.md index 140ba3a1d8e..208f314a799 100644 --- a/text/0000-bool-to-option.md +++ b/text/0000-bool-to-option.md @@ -65,6 +65,8 @@ to other primitive types that do have methods, like [`char`](https://doc.rust-lang.org/src/core/char/methods.rs.html#11-1393). This will require the addition of a new lang item: `#[lang = "bool"]`. +A reference implementation is provided in [#64255](https://github.com/rust-lang/rust/pull/64255). + # Drawbacks [drawbacks]: #drawbacks From f07f27efc8b26917c214774e53315108bba79b95 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 19 Sep 2019 12:30:45 +0100 Subject: [PATCH 5/6] Rename `then` to `to_option` --- text/0000-bool-to-option.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/text/0000-bool-to-option.md b/text/0000-bool-to-option.md index 208f314a799..6d52da67b58 100644 --- a/text/0000-bool-to-option.md +++ b/text/0000-bool-to-option.md @@ -42,7 +42,7 @@ Following this proposal, we will add two methods to `bool`: ```rust impl bool { - fn then(self, t: T) -> Option { + fn to_option(self, t: T) -> Option { if self { Some(t) } else { @@ -50,7 +50,7 @@ impl bool { } } - fn then_with T>(self, f: F) -> Option { + fn to_option_with T>(self, f: F) -> Option { if self { Some(f()) } else { @@ -81,13 +81,14 @@ The implementations here are the only reasonable ones. The following names have been suggested in the past. The choice in this proposal has been made to avoid possible confusion (e.g. avoiding a name that suggests a conversion from `bool` to `Option<()>` rather than `Option`), and to be consist with existing naming conventions (e.g. -`then_with` rather than `then_do` to be consist with methods such as `get_or_insert_with`), -but ultimately comes down to personal preference. +`to_option_with` to be consist with methods such as `get_or_insert_with`), +but ultimately comes down to personal preference and indication of +[community consensus](https://github.com/rust-lang/rfcs/pull/2757#issuecomment-529228631). +- [`to_opt` or `to_option`](https://github.com/rust-lang/rfcs/issues/2606#issuecomment-476019577) - [`then` and `then_do`](https://github.com/rust-lang/rfcs/pull/2180#issuecomment-350498489) - [`some`](https://github.com/rust-lang/rfcs/issues/2606#issue-387773675) - [`as_some` and `as_some_from`](https://docs.rs/boolinator/2.4.0/boolinator/trait.Boolinator.html) -- [`to_opt` or `to_option`](https://github.com/rust-lang/rfcs/issues/2606#issuecomment-476019577) - [`some_if` and `lazy_if`](https://github.com/rust-lang/rfcs/pull/2180) This functionality could instead be provided by a crate (e.g. @@ -110,6 +111,6 @@ None. # Future possibilities [future-possibilities]: #future-possibilities -Methods for converting from a `bool` to a `Result`, e.g. `then_else` and `then_else_with`, +Methods for converting from a `bool` to a `Result`, e.g. `to_result` and `to_result_with`, would be obvious candidates for inclusion into the standard library, which could also be included as an addendum to this proposal if desire is expressed. From 29281326816bf55b9ecb0369e8805b364e9e9445 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 23 Oct 2019 13:00:34 +0100 Subject: [PATCH 6/6] Change method names to `then_some` and `then` --- text/0000-bool-to-option.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/text/0000-bool-to-option.md b/text/0000-bool-to-option.md index 6d52da67b58..29049dd61a8 100644 --- a/text/0000-bool-to-option.md +++ b/text/0000-bool-to-option.md @@ -42,7 +42,7 @@ Following this proposal, we will add two methods to `bool`: ```rust impl bool { - fn to_option(self, t: T) -> Option { + fn then_some(self, t: T) -> Option { if self { Some(t) } else { @@ -50,7 +50,7 @@ impl bool { } } - fn to_option_with T>(self, f: F) -> Option { + fn then T>(self, f: F) -> Option { if self { Some(f()) } else { @@ -80,12 +80,13 @@ The implementations here are the only reasonable ones. The following names have been suggested in the past. The choice in this proposal has been made to avoid possible confusion (e.g. avoiding a name that suggests a conversion from `bool` to -`Option<()>` rather than `Option`), and to be consist with existing naming conventions (e.g. -`to_option_with` to be consist with methods such as `get_or_insert_with`), +`Option<()>` rather than `Option`), and to be consist with existing naming conventions, but ultimately comes down to personal preference and indication of -[community consensus](https://github.com/rust-lang/rfcs/pull/2757#issuecomment-529228631). +[community consensus](https://github.com/rust-lang/rfcs/pull/2757#issuecomment-544437510) following +the [examples in the rustc codebase](https://github.com/rust-lang/rust/pull/65195). -- [`to_opt` or `to_option`](https://github.com/rust-lang/rfcs/issues/2606#issuecomment-476019577) +- [`to_option` and `to_option_with`](https://github.com/rust-lang/rfcs/pull/2757#issuecomment-529228631) +- [`to_opt` or `then_some`](https://github.com/rust-lang/rfcs/issues/2606#issuecomment-476019577) - [`then` and `then_do`](https://github.com/rust-lang/rfcs/pull/2180#issuecomment-350498489) - [`some`](https://github.com/rust-lang/rfcs/issues/2606#issue-387773675) - [`as_some` and `as_some_from`](https://docs.rs/boolinator/2.4.0/boolinator/trait.Boolinator.html)