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

Tracking issue for Iterator::is_partitioned #62544

Open
2 tasks
cuviper opened this issue Jul 9, 2019 · 6 comments
Open
2 tasks

Tracking issue for Iterator::is_partitioned #62544

cuviper opened this issue Jul 9, 2019 · 6 comments
Labels
A-iterators Area: Iterators B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@cuviper
Copy link
Member

cuviper commented Jul 9, 2019

/// Checks if the elements of this iterator are partitioned according to the given predicate,
/// such that all those that return `true` precede all those that return `false`.
fn is_partitioned<P>(mut self, mut predicate: P) -> bool
where
    Self: Sized,
    P: FnMut(Self::Item) -> bool,

feature = "iter_is_partitioned"

ref: #62278

Unresolved questions

  • Do we want this function at all? (Motivating use cases would be useful.)
  • Would is_sorted_by_key already cover all use cases?
@cuviper cuviper added B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jul 9, 2019
@KodrAus KodrAus added A-iterators Area: Iterators Libs-Tracked Libs issues that are tracked on the team's project board. labels Jul 30, 2020
@TheWastl
Copy link
Contributor

Is there anything blocking this from stabiilization?

@cuviper
Copy link
Member Author

cuviper commented Dec 16, 2020

No blocker that I know of. There's some question about the related partition_in_place, but is_partitioned is straightforward.

@m-ou-se
Copy link
Member

m-ou-se commented Dec 20, 2020

Comments from the stabilization PR:

I've looked at the various linked issues but didn't see any motivating use cases for this routine.

Thinking a bit more about this, I suppose that pretty much all use cases of this function are also covered by is_sorted_by_key.

I've added this as an unresolved question above.

@jayaddison
Copy link
Contributor

(arrived here thanks to an initially unrelated curiosity re: iterator::partition (specifically, that it only provides binary partitions))

About use cases: one could be to aid (perhaps semi-automated) porting of existing C++ code that uses stdlib partition (which maps to partition_in_place in Rust, as I understand it?) in combination with stdlib is_partitioned.

I'm a very small Rustacean so I don't know if I understand correctly, but it does seem like all use cases for is_partitioned could theoretically be translated to an implementation in terms of is_sorted_by_key -- but that doing that could require careful sort order / partition function handling, and perhaps more care than automated porting tools could achieve easily / performantly. Basically I think they'd tend to rewrite it as a a check for is_sorted_by ( negation ( partition_func ) ) (because the left-side partition is the true values).

Current implementation notes: is_sorted_by_key performs a (lazy) map across the iterator whereas the current is_partitioned implementation short-circuits by applying all until failure, and then any for remaining elements. Those seem to both have O(n) worst-case?

@siebenHeaven
Copy link

siebenHeaven commented Dec 9, 2023

Can this be extended to return an Option<usize> that would be Some(partition_point) if it is partitioned and None if it's not?

@evlogii
Copy link

evlogii commented Apr 1, 2024

I conducted some testing, and the current implementation (which is quite neat in my opinion), iter.all(predicate) || !iter.any(predicate), is about 2.5 times faster than the implementation using iter.is_sorted_by_key(|x| !predicate(x)). I conducted this testing in response to @jayaddison's comment, although I must admit that I somewhat lost track of the original purpose in the process.

While I feel somewhat indifferent towards the is_partitioned() function, I would be interested in seeing something similar to what @siebenHeaven suggests implemented. However, I believe the function should be named differently; perhaps find_partition_index would be more suitable?

Is there a similar suggestion already in progress? If so, could you assist me in locating it? If not, would you be able to point me to how I can create a new one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-iterators Area: Iterators B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. Libs-Tracked Libs issues that are tracked on the team's project board. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants