Without a way to give objects identity you'd get stuck pretty fast as it's not guaranteed you have access to any data to hash. You'd have to break encapsulation. That would then hit problems with evolution, where a new version of a class changes its fields and then everything that uses it as a hashmap key breaks.
My experience with platform design has consistently been that handling version evolution in the presence of distant teams increases complexity by 10x, and it's not just about some mechanical notion of backwards compatibility. It's a particular constraint for Java because it supports separate compilation. This enables extremely fast edit/run cycles because you only have to recompile a minimal set of files, and means that downloading+installing a new library into your project can be done in a few seconds, but means you have to handle the case of a program in which different files were compiled at different times against different versions of each other.
JavaScript handles the "no identity hash" with WeakMap and WeakSet, which are language built-ins. For Virgil, I chose to leave out identity hashes and don't really regret it. It keeps the language simple and the separation clear. HashMap (entirely library code, not a language wormhole) takes the hash function and equality function as arguments to the constructor.
This is partly my style too; I try to avoid using maps for things unless they are really far flung, and the things that end up serving as keys in one place usually end up serving as keys in lots of other places too.
Does that assume that you have only one key type and not an infinite sized hierarchy of child classes to deal with? If you had a map that took a Number as key, how many child classes do you think your helper class would cover and what extension framework would it use to be compatible with user defined classes?
The reality would be that in all but the most extreme cases emulating set semantics by iterating a list would then be considered good enough, "avoid premature optimization" and all that. In real life code, this would have eaten up any advantage of a shorter object header a hundred times.
mike_hearn|2 years ago
My experience with platform design has consistently been that handling version evolution in the presence of distant teams increases complexity by 10x, and it's not just about some mechanical notion of backwards compatibility. It's a particular constraint for Java because it supports separate compilation. This enables extremely fast edit/run cycles because you only have to recompile a minimal set of files, and means that downloading+installing a new library into your project can be done in a few seconds, but means you have to handle the case of a program in which different files were compiled at different times against different versions of each other.
titzer|2 years ago
[1] https://github.com/titzer/virgil/blob/master/lib/util/Map.v3
This is partly my style too; I try to avoid using maps for things unless they are really far flung, and the things that end up serving as keys in one place usually end up serving as keys in lots of other places too.
josefx|2 years ago
usrusr|2 years ago