The former is technically impossible due to different object representations, the latter is possible and not restricted at all. For example, true and false are not immediate objects, you can use #become*: on them to blow your image up. So, there's no restriction at all if it's technically possible to use #become*:. The responsibility model is the simplest here: use at your own risk. Since this comes up every once in a while, I suggest a comment be added to those methods stating the responsibility model explicitly.
+1
Why express +1 for the responsibility model for use of become: (which I agree with), but not for mutating objects?
*Especially* a warning that becomeForward: does modify the target's hash.
I assume this is not referring to a Warning signal here, but just something in the comment. But even that wouldn't be necessary as long as the indirection remains, since the "copyHash: false" code makes that very clear.
I don't know how the VM handles immutability in this case, but it's possible that it wouldn't let #become*: affect immutable objects.
I think that would be fine, you should be able to become an immutable object and vice versa.
On the other hand, I'm sure it would let you change fields of immutable objects via #become*:, but that's not an issue in your case.
This is debatable ... I would rather have the VM raise an error when trying to become a field of an immutable object. Immutable should mean immutable, no?
So for bulkBecome:, will the error mean it becomed some of them (the ones that that could), but not all? It's getting complex!
However, it seems to me that becomerForward: doing a copyHash is itself a bug. What's the rationale for copying the receiver's hash to the target object?
For when you become a Proxy object to a Symbol selector to perform, which are keys in MethodDictionary's. It's absolutely essential.
Best, Chris