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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Associate Container/Set #15

Merged
merged 23 commits into from
Dec 18, 2018
Merged

Associate Container/Set #15

merged 23 commits into from
Dec 18, 2018

Conversation

choznerol
Copy link
Contributor

@choznerol choznerol commented Sep 30, 2018

Will close part of #4

The code implementation (set/mod.rs) will be push/rebase in thie branch. Besides the code, the draft will be edit in HackMD before ready to publish. Please feel free to add/suggest good topics to cover!
馃憠https://hackmd.io/VsM13vR1TrKzVRsKpHuTjA?both

@choznerol choznerol self-assigned this Sep 30, 2018
@choznerol
Copy link
Contributor Author

choznerol commented Oct 6, 2018

Implement HashSet::union()

In the last commit (caab7fb) I implemented union(&self, other: &HashSet<T>) -> HashSet<T> with following strategy:

  1. Clone other into a new set.
  2. Insert every item from self to the new set (duplication avoided by insert())

and it works

To achieve this, I had to derive Clone trait for both HashMap and HashSet, and also bound the key T of HashSet with Clone. Before proceeding with other methods like difference(), I'd like to make sure if using Clone this way is reasonable and expected?

@weihanglo
Copy link
Owner

weihanglo commented Oct 6, 2018

@choznerol Nice try. Here are my opinions concerning binding HashSet with Clone trait.

First, to be a generic container type, HashMap/HashSet is expected to store nearly every types. Current bound traits on key T in HashMap (Hash, Eq) are reasonable and the intent is explained in the doc. However, bound with Clone trait is too subtle and would lose the flexibility to store arbitrary types. Moreover, clone operation may or may not be expensive but still an overhead.

Second, creating a new HashSet is a rational strategy in dynamic language like Python. In Rust we follow a few essential rules to reduce resource usage. We can

  • move values into new HashSet without cloning.
  • create unions that borrow from original sets.
  • return an lazy iterator representing the union to avoid any extra allocation.

All these methods can cope with the Clone issue.

Last, you can still decide to bind Clone trait if that makes the explanation of HashSet more expressive and understandable. However, it could be more decent if methods which are restricted to Clone trait would be moved into another impl block. I can accept that types without Clone do not have any set operations.

These commits are still awesome attempts. Great job!

@choznerol
Copy link
Contributor Author

choznerol commented Oct 8, 2018

@weihanglo Thanks for the detail explanation! I did feel something weird when adding Clone trait bound but couldn't tell why.

I also peeked at std::HashSet after the first implementation and found the use of Union and Difference type, which borrows from the input set. However, adding dedicated types for union() and difference() might be a little bit overkill for the book. So I'll probably first try to refactor it to return a lazy iterator.

On the other hand, I could still mention the first implementation in the chapter (updated in the dract) to demostrate how that can be refactored in a more 'rust' way (thanks to the explaination above!).

@weihanglo
Copy link
Owner

A step-by-step guide is highly appreciated. It would be a great experience to walk through implementation details with such a veteran Rust developer.

@weihanglo weihanglo force-pushed the draft/set branch 3 times, most recently from cf910d1 to f6ebde2 Compare October 13, 2018 18:25
src/collections/set/mod.rs Outdated Show resolved Hide resolved
src/collections/set/mod.rs Outdated Show resolved Hide resolved
src/collections/set/mod.rs Outdated Show resolved Hide resolved
Copy link
Owner

@weihanglo weihanglo left a comment

Choose a reason for hiding this comment

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

Great work! Would be merged.

@weihanglo weihanglo merged commit 093d59e into weihanglo:master Dec 18, 2018
@weihanglo weihanglo deleted the draft/set branch December 18, 2018 14:46
@weihanglo weihanglo changed the title [WIP] Associate Container/Set Associate Container/Set Jan 30, 2019
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.

None yet

2 participants