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 slice::array_chunks to std #74373

Merged
merged 7 commits into from
Aug 1, 2020
Merged

add slice::array_chunks to std #74373

merged 7 commits into from
Aug 1, 2020

Conversation

lcnr
Copy link
Contributor

@lcnr lcnr commented Jul 15, 2020

Now that #74113 has landed, these methods are suddenly usable. A rebirth of #72334

Tests are directly copied from chunks_exact and some additional tests for type inference.

r? @withoutboats as you are both part of t-libs and working on const generics. closes #60735

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 15, 2020
Comment on lines 476 to 487
#[test]
fn test_array_chunks_infer() {
let v: &[i32] = &[0, 1, 2, 3, 4, -4];
let c = v.array_chunks();
for &[a, b, c] in c {
assert_eq!(a + b + c, 3);
}

let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6];
let total = v2.array_chunks().map(|&[a, b]| a * b).sum::<i32>();
assert_eq!(total, 2 * 3 + 4 * 5);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look at this beauty

@jplatte
Copy link
Contributor

jplatte commented Jul 15, 2020

Is there also a PR for array_windows? :)

@lcnr
Copy link
Contributor Author

lcnr commented Jul 15, 2020

Feel free to open one once T-libs decides this gets merged.
There are too many methods for me to do this all in one go 😄

@DutchGhost
Copy link
Contributor

Neat!! Just one little thought, should .array_chunks_mut::<N>() also be included in this PR?

@varkor varkor added the F-const_generics `#![feature(const_generics)]` label Jul 15, 2020
@varkor
Copy link
Member

varkor commented Jul 15, 2020

Presumably this fixes #60735.

@withoutboats
Copy link
Contributor

This looks good to me.

Only question to me is the name. Too bad that this is just a strictly better version of the existing chunks_exact. array_chunks is good, but maybe something that starts with chunks_ to group it with the other chunk methods alphabetically (chunks_array doesn't sound amazing but I don't have an immediate better alternative).

@lcnr
Copy link
Contributor Author

lcnr commented Jul 15, 2020

There are rare edge cases where chunks_exact is useful (when dealing with variably sized chunks) 😅

The docs order is a valid concern I didn't previously consider.
However, once we add the remaining const generic methods:

  • array_chunks_mut
  • array_windows
  • array_rchunks
  • array_rchunks_mut

We would end up with all const generics methods grouped together which IMO is also desirable.

I fairly strongly prefer array_chunks over chunks_array and wasn't yet able to come up with a good alternative starting with chunks_. chunks_const doesn't sound completely horrible, but I still prefer array_chunks here.

///
/// # Panics
///
/// Panics if `N` is 0.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a note here that says that future versions of this are allowed to panic at compile-time if N is 0 instead of run-time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While that's desirable, I am not sure how feasible it is to change this after stabilization.

Opened a discussion on zulip about this: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/array_chunks.20of.20size.200/near/204001667

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ended up changing array_chunks::<0>() to a compile time error. While we may removing this bound before this method hits stable, it seems like the better default for now.

error[E0277]: the trait bound `[(); 0]: core::slice::sealed::NonZero` is not satisfied

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, there's also an upper bound on array lengths for any non-ZST T, but that should get a compile-time error: the type `...` is too big for the current architecture.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aaah, nm. Adding this bound breaks type inference. Looks like we may have to live with a runtime error for now

@leonardo-m
Copy link

I've just seen that in my codebase I can replace all windows with array_windows.

src/libcore/slice/mod.rs Outdated Show resolved Hide resolved
@SimonSapin
Copy link
Contributor

Since this has the semantics of chunks_exact and not those of chunks, I feel this should be called array_chunks_exact (even though that’s lengthy and the corresponding array_chunks with chunks semantics is impossible).

@lcnr
Copy link
Contributor Author

lcnr commented Jul 16, 2020

Since this has the semantics of chunks_exact and not those of chunks, I feel this should be called array_chunks_exact

I personally do not feel this way as array_ very strongly implies fixed length. Anything which is not exact would
not be able to use an array, so using exact here is therefore unnecessarily redundant in my view.

@snawaz
Copy link

snawaz commented Jul 18, 2020

@lcnr

The docs order is a valid concern I didn't previously consider.
However, once we add the remaining const generic methods:

  • array_chunks_mut
  • array_windows
  • array_rchunks
  • array_rchunks_mut

We would end up with all const generics methods grouped together which IMO is also desirable.

I fairly strongly prefer array_chunks over chunks_array and wasn't yet able to come up with a good alternative starting with chunks_. chunks_const doesn't sound completely horrible, but I still prefer array_chunks here.

How about

  • chunks_const
  • chunks_mut_const
  • windows_const
  • rchunks_const
  • rchunks_mut_const

?

After all, these functions are based on const generics and thus take a const N as generic argument. I believe this also addresses @SimonSapin's concern (to use _exact in its name), as _const implies that anyway — that too, more strongly!

Or we could use _fixed suffix instead. I'd prefer the _const though. 😄

@DutchGhost
Copy link
Contributor

@lcnr

The docs order is a valid concern I didn't previously consider.
However, once we add the remaining const generic methods:

  • array_chunks_mut
  • array_windows
  • array_rchunks
  • array_rchunks_mut

We would end up with all const generics methods grouped together which IMO is also desirable.
I fairly strongly prefer array_chunks over chunks_array and wasn't yet able to come up with a good alternative starting with chunks_. chunks_const doesn't sound completely horrible, but I still prefer array_chunks here.

How about

* `chunks_const`

* `chunks_mut_const`

* `windows_const`

* `rchunks_const`

* `rchunks_mut_const`

?

After all, these functions are based on const generics and thus take a const N as generic argument. I believe this also addresses @SimonSapin's concern (to use _exact in its name), as _const implies that anyway — that too, more strongly!

Or we could use _fixed suffix instead. I'd prefer the _const though. smile

I'd prefer something else than _const, as it sort of almost suggest that the function is a const fn and that the resulting Iterator is const fn compatible

@cuviper
Copy link
Member

cuviper commented Jul 18, 2020

mut_const is too much of a contradiction, even though those qualifiers are referring to different things.

@snawaz
Copy link

snawaz commented Jul 18, 2020

mut_const is too much of a contradiction, even though those qualifiers are referring to different things.

That's true. 😂

Few more name suggestions along with others discussed so far, just for comparison, all at once:

  • array_chunks (original; will not group with the old members)
  • array_chunks_mut

vs

  • chunks_array (flipped; but does not look good)
  • chunks_mut_array

vs

  • chunks_const
  • chunks_mut_const (looks contradictory)

vs

  • chunks_fixed (does not look good enough to me)
  • chunks_mut_fixed

vs

  • chunks_static (as the size is known statically)
  • chunks_mut_static

Can't think of any other suffix 🤔

Hope the last one works for @lcnr and others.

@lcnr
Copy link
Contributor Author

lcnr commented Jul 18, 2020

I personally still prefer array_chunks here as I somewhat elaborated on in #74373 (comment).

At least for me personally static is too strongly related to lifetimes to also consider it to describe sizes.
I do think chunks_fixed seems okay, so I would also be fine with that.

@snawaz
Copy link

snawaz commented Jul 18, 2020

Fair enough.

After considering all alternative names I could think of, array_chunks seems pretty good to me now, also from another perspective: it could return &[T; N] instead of &[T]. And since each element (chunk) is an array, it could be named as chunks_as_array — looks lengthy though, but it (or simply chunks_array) has one advantage: grouping all chunks functions.

@cuviper
Copy link
Member

cuviper commented Jul 19, 2020

A slight variation could use the adjective -- arrayed_chunks or chunks_arrayed.

it could return &[T; N] instead of &[T].

That's exactly what this PR does! The closures like |[a, b]| would have refutable patterns if they were slices.

src/libcore/slice/mod.rs Outdated Show resolved Hide resolved
///
/// The chunks are slices and do not overlap. If `N` does not divide the length of the
/// slice, then the last up to `N-1` elements will be omitted and can be retrieved
/// from the `remainder` function of the iterator.
Copy link
Contributor

@pickfire pickfire Jul 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we mention that this is equivalent to chunks? Not specifying this might let people get the wrong idea, chunks_exact. Maybe we should also have a version for chunks_exact?

Copy link
Contributor Author

@lcnr lcnr Jul 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually equivalent to chunks_exact, as it returns &[T; N], which must always contain exactly N elements.

Because of this, implementing chunks usings arrays/const generics doesn't really make sense here.

Added a note to the method docs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, then how about a version for chunks? If there is a generic version for chunks_exact I think there should be one for chunks too.

If we took chunks_array then the chunks version will be chunks_array_not_exact? Or maybe we should keep the _exact for this?

@lcnr
Copy link
Contributor Author

lcnr commented Jul 31, 2020

yeah. Thanks 😅

@withoutboats
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Aug 1, 2020

📌 Commit 1b90e78393866dbedc859bd09a353ce83112e475 has been approved by withoutboats

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 1, 2020
@tesuji
Copy link
Contributor

tesuji commented Aug 1, 2020

Is this intentional?
image

@cuviper
Copy link
Member

cuviper commented Aug 1, 2020

That submodule was noticed before, then came back with the tracking issues...

@bors r-

@bors bors 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-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 1, 2020
@lcnr
Copy link
Contributor Author

lcnr commented Aug 1, 2020

................what? sry

fixed it @bors r=withoutboats

@bors
Copy link
Contributor

bors commented Aug 1, 2020

📌 Commit d51b71a has been approved by withoutboats

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 1, 2020
@bors
Copy link
Contributor

bors commented Aug 1, 2020

⌛ Testing commit d51b71a with merge b5eae9c...

@bors
Copy link
Contributor

bors commented Aug 1, 2020

☀️ Test successful - checks-actions, checks-azure
Approved by: withoutboats
Pushing b5eae9c to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 1, 2020
@bors bors merged commit b5eae9c into rust-lang:master Aug 1, 2020
@lcnr lcnr deleted the array_chunks branch August 1, 2020 11:13
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 12, 2020
Add `slice::array_chunks_mut`

This follows `array_chunks` from rust-lang#74373 with a mutable version, `array_chunks_mut`. The implementation is identical apart from mutability. The new tests are adaptations of the `chunks_exact_mut` tests, plus an inference test like the one for `array_chunks`.

I reused the unstable feature `array_chunks` and tracking issue rust-lang#74985, but I can separate that if desired.

r? `@withoutboats`
cc `@lcnr`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 22, 2021
Implement split_array and split_array_mut

This implements `[T]::split_array::<const N>() -> (&[T; N], &[T])` and `[T; N]::split_array::<const M>() -> (&[T; M], &[T])` and their mutable equivalents. These are another few “missing” array implementations now that const generics are a thing, similar to rust-lang#74373, rust-lang#75026, etc. Fixes rust-lang#74674.

This implements `[T; N]::split_array` returning an array and a slice. Ultimately, this is probably not what we want, we would want the second return value to be an array of length N-M, which will likely be possible with future const generics enhancements. We need to implement the array method now though, to immediately shadow the slice method. This way, when the slice methods get stabilized, calling them on an array will not be automatic through coercion, so we won't have trouble stabilizing the array methods later (cf. into_iter debacle).

An unchecked version of `[T]::split_array` could also be added as in rust-lang#76014. This would not be needed for `[T; N]::split_array` as that can be compile-time checked. Edit: actually, since split_at_unchecked is internal-only it could be changed to be split_array-only.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 22, 2021
Implement split_array and split_array_mut

This implements `[T]::split_array::<const N>() -> (&[T; N], &[T])` and `[T; N]::split_array::<const M>() -> (&[T; M], &[T])` and their mutable equivalents. These are another few “missing” array implementations now that const generics are a thing, similar to rust-lang#74373, rust-lang#75026, etc. Fixes rust-lang#74674.

This implements `[T; N]::split_array` returning an array and a slice. Ultimately, this is probably not what we want, we would want the second return value to be an array of length N-M, which will likely be possible with future const generics enhancements. We need to implement the array method now though, to immediately shadow the slice method. This way, when the slice methods get stabilized, calling them on an array will not be automatic through coercion, so we won't have trouble stabilizing the array methods later (cf. into_iter debacle).

An unchecked version of `[T]::split_array` could also be added as in rust-lang#76014. This would not be needed for `[T; N]::split_array` as that can be compile-time checked. Edit: actually, since split_at_unchecked is internal-only it could be changed to be split_array-only.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 23, 2021
Implement split_array and split_array_mut

This implements `[T]::split_array::<const N>() -> (&[T; N], &[T])` and `[T; N]::split_array::<const M>() -> (&[T; M], &[T])` and their mutable equivalents. These are another few “missing” array implementations now that const generics are a thing, similar to rust-lang#74373, rust-lang#75026, etc. Fixes rust-lang#74674.

This implements `[T; N]::split_array` returning an array and a slice. Ultimately, this is probably not what we want, we would want the second return value to be an array of length N-M, which will likely be possible with future const generics enhancements. We need to implement the array method now though, to immediately shadow the slice method. This way, when the slice methods get stabilized, calling them on an array will not be automatic through coercion, so we won't have trouble stabilizing the array methods later (cf. into_iter debacle).

An unchecked version of `[T]::split_array` could also be added as in rust-lang#76014. This would not be needed for `[T; N]::split_array` as that can be compile-time checked. Edit: actually, since split_at_unchecked is internal-only it could be changed to be split_array-only.
@cuviper cuviper added this to the 1.47.0 milestone May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. F-const_generics `#![feature(const_generics)]` finished-final-comment-period The final comment period is finished for this PR / Issue. merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

chunks_exact variant with const generic argument