Le mer. 1 juil. 2020 à 06:01, Chris Muller <ma.chris.m@gmail.com> a écrit :
On Tue, Jun 30, 2020 at 7:55 PM Levente Uzonyi <leves@caesar.elte.hu> wrote:
On Tue, 30 Jun 2020, Chris Muller wrote:

> Might be worth reopening this discussion.  ANY dependencies on #class seem like a bad thing to me, especially while it's still an in-lined message.  Below is the MC version that did it.  Looks like the time to change this

Using #class by default sounds correct to me. If some instances of
classes want to be equal to each other, they should handle that
themselves by overriding #=.

Because it causes that same undesirable loss of symmetry you mentioned about MCVersionName and String, except much worse because it's in a more general sense instead of application-specific.  It makes headaches for Magma applications because client code has to be aware of it.

Smalltalk wants to be about messages, not types.  What do we need to do to make #class non-inlined and therefore overridable?  My impression is that this is on the table for 6.0, is it still?

 - Chris


Hi Chris,
wait a minute, the failure of symmetry of MCVersionName is ABSOLUTELY UNRELATED to species or class.

There are some wonderful hacks, there are some clever hacks, but at the end, you very well know that you can cheat as long as you don't get caught.
MCVersionName is not a good hack.

Here we are dressing the String with additional application specific semantics.
The MCVersionName is a String which knows how to be interpreted in some context.
There are lot's of contexts where we could dress strings like that, imagine that we create a DateString, a NumberString...
Should we really do that?
When we do that, we confer more responsibilities to such subclasses. They are a String, and also more than a String.
But here, the application specific behavior is in contradiction with superclass, we redefined = with a different behavior.
At the end, we will always get caught with schemes like that, because we complexify and entangle the concepts.
It seems to me that it's a simple inheritance vs composition anti-pattern.

MCVersion name hash ~= MVVersion name asString hash is a good illustration.
It means that we're breaking a more general contract for implementing our hack.
It's typical of what will happen by abuse of inheritance.

Think of it, = is a relationship of equivalence. We don't want to loose that.
So it has to be symmetric, but also transitive:
    String new = StringSubclass1 & ( String new = StringSubclass2 new ) ==> (StringSubclass1 new = StringSubclass2 new).
That means that we would have accidental equivalence of separate domains if ever the string representation matches.
That's not what we want.

Also, if StringSubclass1 is more than a String, then how something less than a StringSubclass1 could be equivalent?
It's not equivalent, it does not behave the same, or we would not need to subclass in the first place.

Oh but we have String subclasses, ByteString and WideString, so what's the difference?
The difference is that those are implementation details. They are optimized internal representations of Strings.
We're not at all after conferring a different behavior, on the contrary.
We absolutely want to confer the same behavior to the outside whatever the internal representation (class) and try to make them be really equivalent.
Yes, more than often, the implementation details leak out of encapsulation.
It's the problem of tradeoffs between efficiency and universality. We have to trade some generality for some efficiency.

That's what happens with Interval and Array. They are not equivalent. They have slightly different behaviors and properties.
An Interval is more than an Array (it has numeric elements with arithmetic progression).
And it is less than an Array (it cannot at:put: or embed arbitrary objects).
We can casually have an Array carrying the same elements as an Interval, which can be expressed by #hasEqualElements:

species semantics was overloaded. It did also mean, in which recipient class should I select:, collect:...
If we use the same recipient for collecting, then we are similar (of same species)... And if similar, maybe equal?
It might be that Interval was originally seen as an implementation detail, a (space) optimized version of Array afterall.
But doing so, introduced complexity.
It entangled things.
It broke contracts (hash), or imposed very inefficient implementation of hash (enumerating all elements of an Interval).
In the end, we get caught, that is carrying more inconvenients than advantages when trying to sustain the illusion of equivalence.
It's far better and simpler to just abandon the illusion, because it's just that, a deceitful illusion.

I understand what you mean by abuse of using the class message, we have somehow lost a hook.
But IMO, this hook was not useful, except for one thing proxy.
We have more than one message in our palette, even if = is a very convenient symbol (short binary), we cannot dress it with different context specific meanings, the cheat is getting too apparent.