[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
|