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

Implement HashMap similar to Python's dict #19

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

Conversation

frostburn
Copy link
Member

Implement an abstract base class for values hashable by their numeric value and distinguishable by strict equality. Implement HashMap as an associative data structure for hashable values. Implement HashSet as a collection of hashable values. Replace FractionSet implementation with HashSet.

@frostburn frostburn requested a review from arseniiv April 10, 2024 12:33
@frostburn

This comment was marked as resolved.

Copy link

@arseniiv arseniiv left a comment

Choose a reason for hiding this comment

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

I’m satisfied with this as is but you’ll most probably agree changing things that were commented would be useful! 🥨

src/hashable.ts Outdated
export abstract class Hashable {
abstract strictEquals(other: Hashable): boolean;

abstract valueOf(): number;

Choose a reason for hiding this comment

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

It’s not obvious that this returns specifically the hash value, I’d name it like getHash or getHashValue[Of]

Copy link
Member Author

Choose a reason for hiding this comment

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

.valueOf() is something that every JS object kind of should have and is close enough to a hash in the identification sense.

src/hashable.ts Outdated
* Python style set implementation using hashable values.
*/
export class HashSet<T extends Hashable | Primitive> implements Set<T> {
private hashmap: HashMap<T, undefined>;

Choose a reason for hiding this comment

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

Is undefined really a good singleton type for non-values associated with present keys? I see you using undefined in HashMap.get (I presume in accordance with JS doing this for objects and stuff) so it’s better to use another singleton like null or maybe even true if it can be detached from the boolean type, than to ensure no undefined leaked somewhere.

@@ -382,3 +382,31 @@ describe('Constant structure checker with a margin of equivalence', () => {
expect(hasMarginConstantStructure([1199, 1200], 2)).toBe(false);
});
});

Choose a reason for hiding this comment

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

A good idea would be adding tests to cover every method of HashMap (but probably not necessary HashSet) because there are usually two main paths for Hashable and primitive types, so it’s good to at least be confident they don’t diverge in behavior.

@arseniiv
Copy link

Wait I think there was one more comment but well probably I’m seeing things.

src/fraction.ts Outdated
* new Fraction("19.5").strictEquals(new Fraction("98/5")) // false
* ```
**/
strictEquals(other: Fraction) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This one fails when using heterogenous HashMaps with other non-primitive keys.

/**
* A hashable type expected to remain immutable so that it can be used as a dictionary / hash map key.
*/
export abstract class Hashable {

This comment was marked as resolved.

@frostburn
Copy link
Member Author

A benchmark should be added to determine the impact of .valueOf() vs. a compute-optimized .getHash().

Implement an abstract base class for values hashable by their numeric value and distinguishable by strict equality.
Implement HashMap as an associative data structure for hashable values.
Implement HashSet as a collection of hashable values.
Replace FractionSet implementation with HashSet<Fraction>.
@frostburn
Copy link
Member Author

This a bit more work than expected as the whole library needs more type precision when it comes to immutability.
The implementation should also be verified to be compatible with minor modifications to sonic-weave's TimeMonzo.
Benchmarks would benefit from #20 to avoid extra migration work later.
The removal of FractionSet makes this a breaking change.

Converting PR to draft for later when HashMap is actually needed.

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.

2 participants