data StableName a
Stable names have the following property: If sn1 :: StableName and sn2 :: StableName and sn1 == sn2 then sn1 and sn2 were created by calls to makeStableName on the same object.
The reverse is not necessarily true: if two stable names are not equal, then the objects they name may still be equal.
reallyUnsafePtrEquality# :: a -> a -> Int#
reallyUnsafePtrEquality# returns whether two objects on the GHC heap are the same object. It's really unsafe because the garbage collector moves things around, closures, etc. To the best of my knowledge, it can return false negatives (it says two objects aren't the same, but they are), but not false positives (saying they're the same when they aren't).
Both of them seem to do the same basic thing: they can tell you whether two objects are definitely the same, but not whether they're definitely not.
The advantages I can see for StableNames are:
The advantages I can see for reallyUnsafePtrEquality#:
My questions are:
Did I miss anything?
Is there any use case where the fact that StableNames are separate from the objects they name is an advantage?
Is either one more accurate (less likely to return false negatives) than the other?
If you don't need hashing, don't care about portability, and aren't bothered by using something called reallyUnsafe, is there any reason to prefer StableNames over reallyUnsafePtrEquality#?
Holding the StableName
of an object doesn't prevent it from being garbage collected, whereas holding the object itself around (to use with reallyUnsafePtrEquality#
later) does. Sure, you can use System.Mem.Weak
, but at that point, why not just use a StableName
? (In fact, weak pointers were added with StableName
s.)
Being able to hash them is the main motivator for StableName
s, as the documentation says:
We can't build a hash table using the address of the object as the key, because objects get moved around by the garbage collector, meaning a re-hash would be necessary after every garbage collection.
In general, if StableName
s will work for your purposes, I'd use them, even if you need to use unsafePerformIO
; if you really need reallyUnsafePtrEquality#
, you'll know. The only example I can think of where reallyUnsafePtrEquality#
would work and StableName
s wouldn't is speeding up an expensive Eq
instance:
x == y =
x `seq` y `seq`
case reallyUnsafePtrEquality# x y of
1# -> True
_ -> slowEq x y
There's probably other examples I just haven't thought of, but they're not common.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With