Skip to content
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

Add as_slice and as_mut_slice to Option #92411

Closed
wants to merge 3 commits into from
Closed

Add as_slice and as_mut_slice to Option #92411

wants to merge 3 commits into from

Conversation

ChaiTRex
Copy link
Contributor

Extracts an immutable or mutable slice from an option such that, if
the option is a None value, the slice is empty, and if the option
is a Some value, the slice is length one.

The slice is, for all practical purposes except extracting a
pointer, a reference to the actual contents of the owned option. If
it's a Some value, slice index zero contains the contents of the
owned option. If it's a None value, the slice is length zero and
cannot be read from or written to.

Extracts an immutable or mutable slice from an option such that, if
the option is a None value, the slice is empty, and if the option
is a Some value, the slice is length one.

The slice is, for all practical purposes except extracting a
pointer, a reference to the actual contents of the owned option. If
it's a Some value, slice index zero contains the contents of the
owned option. If it's a None value, the slice is length zero and
cannot be read from or written to.
@rust-highfive
Copy link
Collaborator

r? @kennytm

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 29, 2021
@jhpratt
Copy link
Member

jhpratt commented Dec 29, 2021

What's the motivation here?

@ChaiTRex
Copy link
Contributor Author

ChaiTRex commented Dec 29, 2021

@jhpratt A lot of functions will take a slice as an argument, and so I saw a question which involved having an option and needing to pass it to a function that took a slice.

This is a tricky problem to solve because core::slice::from_ref is relatively poorly known, and so they were having trouble with lifetime issues.

Solving it can lead down inefficient paths like option.into_iter().collect::<Vec<_>>() and then extracting a slice from that.

It can lead down rabbitholes where you create a function that takes an option and tries to make a zero or one element array that you return a slice of, which won't compile, or something like option.and_then(|x| Some(&[x])).unwrap_or(&[]), which also won't compile.

The best solution given was a function much like this pull request (except with Option methods instead of a match) that took an Option<&T> instead of an Option<T>.

This pull request takes all the confusion out of it; can take an Option<T> rather than only an Option<&T>; needs no copying, moving (allowing the reuse of the option), or allocation; and has the same name and interface as Vec's as_slice and as_mut_slice methods.

@jhpratt
Copy link
Member

jhpratt commented Dec 29, 2021

If core::slice::from_ref is poorly known, why not try to improve visibility on that front? opt.as_ref().map_or(&[], core::slice::from_ref) works exactly how you'd expect. I just don't see this as a common problem, and it's not as if Option<T> is semantically a slice the same way Vec<T> is.

@ChaiTRex
Copy link
Contributor Author

ChaiTRex commented Dec 30, 2021

It's not that it's the most common problem, but it's got to be somewhere near as common as the need for core::slice::from_ref, and it's easier to find as a method in Option's documentation with the same name it has with arrays and with Vec than in the standalone functions of an unrelated module to Option.

To try to raise the visibility of core::slice::from_ref in this case. I've posted a question and answer on Stack Overflow for it so that it shows up on Google.

I disagree that options aren't semantically a slice. They're zero or one elements contiguous and so on in memory, and, as core::slice::from_ref points out, any reference is semantically a slice of one element.

The only difference here is that the None case is simplified a bit from making the returned slice's pointer point somewhere into the actual option. It seems a bit like how Vec::new() doesn't allocate and can still produce an empty slice.

@jhpratt
Copy link
Member

jhpratt commented Dec 30, 2021

I disagree that options aren't semantically a slice. They're zero or one elements contiguous and so on in memory, and, as core::slice::from_ref points out, any reference is semantically a slice of one element.

How something is laid out in memory has nothing to do with how it semantically is or is not a slice. Semantics is a high-level overview.

Where are you seeing a mention of how a reference is semantically a slice of one element? That's not present in the documentation and it's an assertion I also disagree with.

@ChaiTRex
Copy link
Contributor Author

Unfortunately, I'm not sure what you mean by semantically a slice then. From what I've seen in Rust and other languages, a slice is specifically a finite sequence of elements of one type laid out contiguously in memory. Can you please clarify?

@jhpratt
Copy link
Member

jhpratt commented Dec 30, 2021

As I said, it has nothing to do with how it's laid out in memory. Semantics deals with how you think about a value. I'd be quite surprised if a significant number of people think of an option as a slice. As an experienced programmer I know I never have; it's always mentally been the enum that it is.

@ChaiTRex
Copy link
Contributor Author

While I understand that some people don't currently think of it as sliceable, perhaps because it's an enum, this isn't the kind of surprise that leads to mistakes in coding, and there are plenty of unexpected ways of thinking about things in programming that people discover as they go along.

If someone who understands what a slice is sees as_slice() in the documentation for Option or in code where it's applied to an option, it's immediately understandable what the method does, even if they're surprised to see it. All expectations about how the produced slice will behave are maintained.

@jhpratt
Copy link
Member

jhpratt commented Dec 30, 2021

I actually would not understand what the method does without looking at its signature. My intuition from the name is that this would return Option<&[T]>.

Additions to the standard library aren't meant to be easy. Something not being prone to mistakes really isn't the threshold we're shooting for. Methods need to be at least relatively common, which I have seen any evidence of (and it's certainly not self-evident or I wouldn't be asking).

@ChaiTRex
Copy link
Contributor Author

Fair enough. I don't think there's a better name (a different one would diverge from the array and vector as_slice methods), but the documentation would clear it up.

I'll look for how prevalent equivalent code is.

@ChaiTRex
Copy link
Contributor Author

Found that this was proposed before and rejected. See #27776.

Will continue looking.

@camelid camelid added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Jan 1, 2022
@JohnCSimon JohnCSimon added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 23, 2022
@JohnCSimon
Copy link
Member

Ping from triage:
@ChaiTRex Can you please post your status on this PR?

@ChaiTRex ChaiTRex closed this Feb 17, 2022
@ChaiTRex
Copy link
Contributor Author

Added in #105871.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants