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

Chris Muller asqueaker at gmail.com
Sat Nov 24 04:04:24 UTC 2018

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

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

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