Basically, it comes down to Proxy's. I want them to work better in Squeak. But every time we put another send to #class or #== in an implementation of #=, since those methods are inlined, they're too brittle to work with Proxy's. This causes hard-to-trackdown bugs in applications and mini-messes to deal with them since the app is forced to change its code to become "aware" of potential Proxy'iness of an object before comparing it with #=.
The disease is the inclining of #class and #==, not the use of these in comparison methods. In the VisualWorks vm I implemented a command-line/image header switch that enabled/disabled this inlining. It is easy to implement the same thing on Cog.
If we did, then these methods would not be inlined if the flag is enabled, on a per-image basis.
Having consistent send properties among all messages would be cool. Having said that, I do like performance, and there aren't that many in-lined messages, and experience has trained me to recognize when I use them and pay attention to the Proxy-dynamics. A "global switch" approach would force the entire image to incur the overhead, even for non-DB objects like the Morphs of the UI. A simple #yourself strategically sprinkled here or there is not such a huge deal for me, except that a lot of them could be trivially eliminated by nothing more than a flexibility from my peers about their interpretations of "equivalence".
Perhaps if the method were called #ensureNonProxiedReceiver instead of #yourself, your peers would know why it is there.
Actually it is. Pretty close anyway, it's called #realObjectIfMutatingProxy, but #yourself works too and I was trying to keep the conversation simpler by sticking with standard familiar vocabulary.
An alternative is Marcus Denker’s Opal compiler for Pharo which compiles #class and #== to normal sends, avoiding the inlined special selector bytecodes for these sends. That’s arguably an even better solution, because it retains the ability to inline. Although the mirror methods objectClass: and object:eqeq: can be used, with more overhead.
In any case, instead of proposing to change a natural and comprehensible idiom, we can instead evolve the implementation to meet our needs.
Smalltalk is supposed to be about messages, not types. So why shouldn't we let the _messages_ determine equivalence instead of enforcing conformance to some specific "type"? You know we already have several classes that use #isKindOf: rather than == otherObject class. So, I think my proposal is natural and comprehensible too, especially. from the aspect that it avoids the real-world bugs that can sometimes seem incomprehensible.
"foo isKindOf: Bar" is not a substitute for "foo class == Bar".
We're talking about defining a useful meaning for equivalence between two complex objects, not making a substitute for identity checks. I doubt you can articulate as clear a position against #isKindOf: in that context.
"foo isMemberOf: Bar" is what you should use instead (if you really want worse performance :)).
I'm not sure if you're joking here, or not. :/ I'm open to all serious suggestions.
- Chris