I hope to clarify and contribute, the terms identity or equality hash caused my irritation, as well as some aspects of the examples mentioned before (mathematical aspects of a set).
First: a hash is a hash, there is no "identity" or "equality" hash.
To begin with, to distinguish, the difference between identiy == and equailty =, in words, if objects are the same (==) or have the same value(s) (=).
Technically, identity, is implemented by a pointer comparison (it is the same object if it has the same location) - no hash involved. It relies on the fact no dublicates of an object exist.
Equality, is implemented by comparing (many) values stored in the object, that means to compare all of its elements stored in a location. Duplicates of such objects may exist. Note: conceptually also no hash involved here!
Thus identity always performs better than equality as comparing the address (location) is faster in general (with some exceptions, see at the end) than many values, elements of the object.
Now what about hashes: hashing is used to gain speed this comparison, but this may fail:
if hashes of objects are different, then the objects are certainly different - but if two objects have the same hash, they STILL MAY BE DIFFERENT.
Now it is left to decide if such a hash collision causes an error when applied or can silently be ignored or requires a costly recheck to detect and avoid the collision.
So the framework offers you IdentitySets and IdentityDictionaries to avoid collision costs, but at the expense of obeying the law of forbidden duplication.
If you do not care about the hash collision cost, you savely can use normal Sets, LookupTable, Dictionaries, based on eqality, which in turn is based on hashes.
The price is if you want to profit from faster identity checks, you have to make certain that you are not duplicating objects braking their identity.
It costs quite a lot of work to grant object identies, in particular for e.g. persistent objects. In the technical world, UUID have been invented to suport this (also a specialised form of a hash code).
So e.g. for some elementary objects (numbers, characters and atoms) have to be treated specially to grant this logic.
E.g. 3 copy or $A copy does not make sense and provides no second object with the same value.
Here it is faster to compare the values and not to allocate a number or character object at all.
To remember: this is also the most important difference between symbols # and atoms ##.
And finally, to the difference of basicHash and hash. hash methods are built upon basisHash methods.
As I said, hashes imposes logic uncertainty due to hash collisions.
You can gain performance, if you design its hash computation, e.g. you benefit if you can ignore elements of an object which are irrelevant.
So Smalltalk offers you the opportunity to implement your own specific hash and = methods, as long as you are folowing the implied rules (or otherwise, you are responsible for the implications or failures).
The basicHash is then (as the name says) the most basic implementation to grant system wide functionality, is forms the (basic) fall back, if you do not provide your own hash.
It would be counterproductive to implement other basicHashes, as you can do this already in the hash methods.
And a remark to the speed investigations: in general it is conceptually senseless to use String keys in IdentitySets and IdentityDictionaries) (as Strings can have duplicates).
It's like division by 0.
Kind regards
M