[squeak-dev] sends of #class and #== considered harmful, may we please stop?

Levente Uzonyi leves at caesar.elte.hu
Sat Nov 24 14:26:01 UTC 2018


On Fri, 23 Nov 2018, Chris Muller wrote:

> Hi Eliot,
>
>> > 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.

>
>> 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". "foo 
isMemberOf: Bar" is what you should use instead (if you really want worse 
performance :)).

Levente

>
>> > This is no surprise, since writing a send to #== instead of #= for no
>> > more than "performance" is actually breaking encapsulation in the
>> > firs t 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?
>>
>> I think it is wrong.  xxxClass is a horrible hack that should be banished ASAP.
>
> Other than it having an unattractive name, what is wrong about it?
> Smalltalk is supposed to be a full computer implemented in itself, but
> you want to introduce a new VM feature and a new global setting that
> slows down the entire image and even has to be reckoned with all the
> way out in the Linux scripts (for cmdline arg), all just to avoid
> writing #= instead of #== in a few places?   :(
>
>  - Chris


More information about the Squeak-dev mailing list