Hi Chris,
I think it should work the other way around. When you want to be able to use proxies everywhere (which can't work btw, because everywhere is just too vague), there should be a switch - a preference with an action - that recompiles all methods with the #== and #class bytescodes disabled except for those methods which have a special pragma preventing such deoptimization.
I'm surprised you didn't mention other special methods like #ifTrue:, #whileTrue:, #repeat:, #to:do:, etc. I think that's because you rarely create proxies for numbers, booleans and blocks.
Levente
P.S.: Please don't use #species for such thing. Why? #species is supposed to return "the preferred class for reconstructing the receiver". It is not a substitute for #class.
On Thu, 22 Nov 2018, Chris Muller wrote:
Hi guys,
Something I've been wanting to ask the community for years, but never had the gumption, was about changing how we write our #= and #hash methods, but now that we're combing through them anyway, I must!
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 #=.
This is no surprise, since writing a send to #== instead of #= for no more than "performance" is actually breaking encapsulation in the first place...
There is an easy solution. When writing #= and #hash implementations, use (#species or #xxxClass or #isKindOf: instead of #class) and #= instead #==. So, for example, Eliot, I want to upgrade your new Message>>#= to something like:
= anObject ^self xxxClass = anObject xxxClass and: [selector = anObject selector "selector lookup is by identity" and: [lookupClass = anObject lookupClass and: [args literalEqual: anObject arguments]]]
Or #species or #isKindOf:, like we do in many other methods. Now the method is Proxy-compatible.
What do you think?