-
Notifications
You must be signed in to change notification settings - Fork 795
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
Implement chunkBySize and splitInto in Seq, List and Array #261
Conversation
CheckThrowsArgumentException (fun () -> Seq.divideInto 3 nullSeq |> ignore) | ||
|
||
// invalidArg | ||
CheckThrowsArgumentException (fun () -> Seq.divideInto 0 [1..10] |> ignore) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check for argument name (property of ArgumentException) on test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't done elsewhere in the tests that I can see and if done here it should probably be changed for all checks for ArgumentException
This is confusing for me. I thought it was supposed to be chunkBy |
@rojepp I was asked to implement this version. I guess this would not prevent the original version from being implemented if the demand is there for it |
[<CompiledName("ChunksOf")>] | ||
let chunksOf chunkSize (array:'T[]) = | ||
checkNonNull "array" array | ||
if chunkSize <= 0 then invalidArg "chunkSize" (SR.GetString(SR.inputMustBeNonNegative)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need an error message inputMustBePositive
, since 0 is non-negative but still invalid. From a quick scan, about 80% of usages for this message are correct (check for < 0
) but a handful are inaccurate (check for <= 0
).
Should not block this contribution, just something to look at later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I knew it wasn't quite right, but it was used in windowed with the same check and I assumed there was more to it than just adding a new constant :)
Implementation looks good, and nice test coverage, just a few comments there. On design I still wonder about a few things. I understand overall goal of keeping return types same as input types, but I wonder whether it's worth it for functions like this.
For
No. 2 is unavoidable unless If If Sorry for long post, just going through possibilities in my head. Would love for someone to convince me that these are bad ideas. 😆 |
On the types, one alternative option would be to use the following:
It could be argued that maybe we should have gone this route with
(One way of thinking about If we go with the first option, we should consider revisiting |
Hmm, interesting. Yes, |
Hi all, First, thank you @PatrickMcDonald for looking at this. As I've returned to doing bread-and-butter F# programming (rather than compiler work) in the context of updating Expert F# and doing some distributed cloud programming with MBrace, and based on years of seeing people want these functions, I've become convinced that we should add these to F#. So I felt we could at least put good implementations/designs of them on the table for F# 4.0, incorporating them should schedule permit. This is why I mentioned to @PatrickMcDonald that he might take a look at this. Thanks again for this. Equally, we all understand that schedule might not permit, and we'll all be ok with that :) OK, so on to the feedback... First naming.... I suggest we use I'm uncomfortable with both of the names "chunksOf" and "chunkBy"
I'm somewhat loathe to use up "Into" as a suffix, as it has a potential variety of other meanings - for some collection libraries, for example, it means "give a continuation which consumes the results", as in "zipInto". But I can't find anything better than For the semantics of For the types, I agree with option 1 of @PatrickMcDonald's suggestion here. Indeed I would suggest we also consider changing List.windowed (which is new in F# 4.0) to return a list-of-lists, for consistency, which would undo a previous decision we've made but consistency is very important here. |
Other possible verbs: So @dsyme you would suggest the bin sizes never differing by more than 1, with bigger bins front-loaded? Fascinating that words in this space ("chunks", "runs") evoke such unpleasant stuff 😷 |
The chunking functions in Deedle might be relevant to the discussion. See the relevant documentation section.
|
Thanks Tomas, that's very useful It looks like in Deedle |
I initially used Some other possibilities for |
@latkin - yes, bins never differing by more than 1, with bigger bins front-loaded To finalize the design for this, we need to
|
Here are the online dictionary synonyms for apportion :) Synonyms: accord, admeasure, administer, allocate, allot, assign, bestow, cut, cut up, deal, dispense, distribute, divvy, divvy up, dole out, give, lot, measure, mete, parcel, part, partition, piece up, prorate, ration, slice, split, split up |
Giving possibilities "cutInto" and "splitInto" (the Into clarifies the meaning of split). If you had to vote between "splitInto" and "divideInto" which would you choose and why? Any other suggestions? Thx |
There's also
|
An alternative to |
e194b9a
to
a2920d4
Compare
I vote for
When i search for chunk in Google i get always the answer for "split list in sublist of evenly size" Others: quick search for other languages ( consistency is good , easy to search )
|
Thanks, great feedback. Could you add links to the library functions of these other languages? |
|
| len -> | ||
let chunkCons = freshConsNoTail list.Head | ||
let res = freshConsNoTail chunkCons | ||
let (lenDivCount, lenModCount) = System.Math.DivRem(len, min len count) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is failing in one of the portable builds, I'll fix it
@dsyme updated with reference |
I like |
@latkin - yes, I think "arr |> Array.splitInto 10" does read very well. OK, so let's settle on
@PatrickMcDonald - can you make the updates to finalize this? Thanks |
Fantastic, I'll make these changes this evening. @latkin Do you have a strong opinion against me rebasing this branch to tidy up the history? I know they get rebased anyway but the history of commits gets left in the final commit message. |
@PatrickMcDonald I have no preference either way, feel free to rearrange as you see fit |
191be39
to
57b1443
Compare
57b1443
to
6a242f3
Compare
LGTM. Some tricky index arithmetic in this one! |
Great addition! Looking forward to using this. |
This PR implements
chunksOf: int -> M('T) -> M(M('T))
anddivideInto: int -> M('T) -> M(M('T))
See fsharp/fslang-design#25