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 CCVector.resize_with and CCVector.resize_with_init, tests and doc #389

Merged
merged 4 commits into from
Oct 21, 2021

Conversation

RadioPotin
Copy link
Contributor

Greetings,

I've been using this lib for a school project of mine and it has been of great help.
I've come to need the feature this PR adds so I thought it would benefit other people too.

It being my first contribution to the lib, do tell me if I have omitted anything.
Cordially :)

@@ -201,6 +201,52 @@ let push v x =
let v = of_list [1;2;3] in push v 4; to_list v = [1;2;3;4]
*)

let resize_with v f size =
if size > Sys.max_array_length then
failwith "vec.resize_with: size too big"

Choose a reason for hiding this comment

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

Invalid_argument ?

Copy link
Owner

Choose a reason for hiding this comment

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

Agreed, invalid_argument "…" is more in line with the rest 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Understood

Comment on lines 211 to 218
else
let new_vec = Array.make size (f 0) in
for i = 0 to size - 1 do
Array.unsafe_set new_vec i (f i)
done;
v.vec <- new_vec;
v.size <- size;
()
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
else
let new_vec = Array.make size (f 0) in
for i = 0 to size - 1 do
Array.unsafe_set new_vec i (f i)
done;
v.vec <- new_vec;
v.size <- size;
()
else (
let new_vec = Array.make size (f 0) in
for i = v.size to size - 1 do
Array.unsafe_set new_vec i (f i)
done;
v.vec <- new_vec;
v.size <- size;
()
)

The semantics should be, imho, that f is only called for new arguments. In particular, resize_with v f (size v) should not do anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it

if size > Sys.max_array_length then
failwith "vec.resize_with_init: size too big"
else if size <= Array.length v.vec then
for i = 0 to v.size - 1 do
Copy link
Owner

Choose a reason for hiding this comment

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

same remark here, don't touch the existing elements

(** [resize_with vec f size] resizes vector [vec] up to [size], fills vector
with calls to [f] on indexes [[0.. size - 1]].
The contents of [vec] are merely overwritten with calls to [f] if [size]
is inferior or equal to the current size of [vec].
Copy link
Owner

Choose a reason for hiding this comment

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

both the docs could mention @raise Invalid_argument if the size is too big

Copy link
Owner

@c-cube c-cube left a comment

Choose a reason for hiding this comment

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

That's a good start, I think 🙂 . However the semantics need to be discussed, in particular wrt elements already present before the resize. My view is that they should be preserved, and resize should be of complexity linear in the number of new elements.

@RadioPotin
Copy link
Contributor Author

Thank you for your reviews @c-cube

I've applied the changes you have suggested, I have yet to commit them, though I have a question regarding raise (Invalid_argument ...) for both functions:

1- Should I also fail if size < 0 ?
2- Should I check if size > Sys.max_array_length in each function or let the check be within the call to Array.make when it happens that we are actually going to use size to allocate ?

Not raising Invalid argument _ in these function would save the cost of a check already happening in Array.make, what are your thoughts ?

@c-cube
Copy link
Owner

c-cube commented Oct 20, 2021

I'm not sure, tbh. Doing the check ourselves helps giving better error messages, but it's also a tiny bit of overhead. I think it's fine skipping them altogether.

Copy link
Owner

@c-cube c-cube left a comment

Choose a reason for hiding this comment

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

some bugs :)

let resize_with v f size =
if size > Sys.max_array_length then
invalid_arg "vec.resize_with: size too big"
else if size > Array.length v.vec then
Copy link
Owner

Choose a reason for hiding this comment

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

Still not correct, this will not work if, say, v.size = 5 but Array.length v.vec = 10 when we want to resize to 8.

I think it's simpler to call the function to ensure capacity is >= size, and then add missing elements.

let resize_with_init v ~init size =
if size > Sys.max_array_length then
invalid_arg "vec.resize_with_init: size too big"
else if size > Array.length v.vec then
Copy link
Owner

Choose a reason for hiding this comment

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

Same, this doesn't do anything in case v.vec is big enough but v.size < size.


(*$T
let v = make 1 0 in to_list (resize_with_init v ~init:1 5) = [1;1;1;1;1]
let v = make 1 0 in length (resize_with_init v ~init:1 5) = 5
Copy link
Owner

Choose a reason for hiding this comment

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

need some tests to cover the case mentioned above :)

@RadioPotin
Copy link
Contributor Author

Hello again,

I think i've fixed the bug you mentioned, i've added a single test in each function in regards to it

@c-cube
Copy link
Owner

c-cube commented Oct 21, 2021

Did you run the tests locally? I suspect they don't compile (there's a -1 that is most likely parsed the wrong way).

edit: to run the tests you need qtest, qcheck, and make test

@RadioPotin
Copy link
Contributor Author

Yikes, my bad I was running dune runtest instead of make test but was clueless

@c-cube
Copy link
Owner

c-cube commented Oct 21, 2021

resize_with v (fun …) (-1) should raise, btw.

@c-cube
Copy link
Owner

c-cube commented Oct 21, 2021

I'm going to merge and fix on master.

@c-cube c-cube merged commit d1ddeeb into c-cube:master Oct 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants