This is an interesting concept. One of the main complications in a “purely functional” setting would be that the identity of the object is usually not observed in a “purely functional” sense. I.E., if I copy an object or create a new identical one, in Java he expected the clone to be not the original. But in the functional setting, it is expected that the new one will be semantically identical to the old one, although the garbage collector will treat it differently.
So, if we allow the identification of the object to be part of the semantics, it will sound, otherwise, probably not. In the latter case, even if the hack could be found (I was thinking about one described below), you will probably have a language implementation fighting you everywhere, because it is going to do all kinds of things to use this fact that the identification of the object should not be observable.
One “hack” that appeared in my head would be to use values unique in construction as keys, so in most cases the value of equality will coincide with the reference equality. For example, I have a library that I personally use in Haskell with the following in my interface:
data Uniq s getUniq :: IO (Uniq RealWorld) instance Eq (Uniq s) instance Ord (Uniq s)
The hash map, as you described, will most likely work with them as a key, but even here I can think about how it can break: suppose the user stores the key in a strict field of some data structure, and the compiler is optimized. Optimization " unbox-strict-fields ". If "Uniq" is just a newtype wrapper for an integer of a machine, there can no longer be an object to which the GC can point and say "what is the key"; therefore, when the user goes and unpacks his key to use it, the card may already have forgotten about it. (Edit: this specific example can obviously be bypassed, make the Uniq implementation something that cannot be unpacked as such: the fact is that it is complicated, because the compiler is trying to be useful in many ways, to expect)
TL DR: I would not say that it is impossible to do this, but I suspect that in many cases the “optimization” will either break or break into a weak implementation of the hash map, unless the identity of the object is provided with a first-class observable status.