Borg identity [was Re: why () is () and [] is [] work in other way?]

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Apr 27 14:40:50 EDT 2012


On Fri, 27 Apr 2012 10:33:34 -0700, Adam Skutt wrote:

>> Why should the caller care whether they are dealing with a singleton
>> object or an unspecified number of Borg objects all sharing state? A
>> clever interpreter could make many Borg instances appear to be a
>> singleton. A really clever one could also make a singleton appear to be
>> many Borg instances.
> 
> Trivial: to break cyclical references in a deep copy operation.

I asked why the *caller* should care. If the caller has to break cyclical 
references manually, the garbage collector is not doing its job.

If you're going to propose underpowered or buggy environments as an 
objection, then I'll simply respond that I'm not talking about any 
specific (underpowered or buggy) implementation, I'm talking about what 
is logically possible.


[...]
>> > How would inheritance work if I did that?
>>
>> You don't inherit from Borg instances, and instances inherit from their
>> class the same as any other instance.
> 
> I think you misunderstood me.  Define a Borg class where somehow
> identity is the same for all instances.  Inherit from that class and add
> per-instance members.

I think that if you're talking about per-instance members of a Borg 
class, you're confused as to what Borg means. Since all instances share 
state, you can't have *per-instance* data.


> Now, identity can't be the same for all
> instances.  As a result, you've just violated the Liskov Substituion
> Principal: code that relies on all Borg class instances having the same
> identity will fail when passed an instance of the subclass.

Not at all. Obviously each Borg subclass will have it's own fake 
identity. Code that requires instances of different types to be identical 
is fundamentally broken, since the mere fact that they are different 
types means they can't be identical.

I'll accept the blame for your confusion as I glossed over something 
which I thought was obvious, but clearly wasn't.

When I said that Borg instances are indistinguishable except for 
identity, I thought that was obvious that I was talking about instances 
of a single type. Mea culpa.

Clearly if x is an instance of Borg, and y is an instance of 
BorgSubclass, you can distinguish them by looking at the type. The point 
is that you shouldn't be able to distinguish instances of a single type.


> It's impossible to combine identities and not violate LSP, unless you
> forbid subclasses.  Your idea violates one of the most fundamental
> tenants of object-oriented programming.  This is because object identity
> is one of the fundamental consequences of object-oriented programming. 
> You can't do away with it, and any attempt to do so really just suggests
> that you don't understand OOP at all.

Oh please, enough of the religion of LSP.

Barbara Liskov first introduced this idea in 1987, twenty years after 
Simula 67 first appeared and thirty years after MIT researchers came up 
with the concept of object oriented programming. That's hardly 
fundamental to the concept of OOP. People have, and still do, violate LSP 
all the time.

LSP may be best practice but it's hardly essential. OOP was useful before 
LSP and it will remain useful in the face of violations.

Besides:

- In real life, subtypes often violate LSP. An electric car is a type of 
car, but it has no petrol tank. Wolf spiders have eyes, except for the 
Kauaʻi cave wolf spider, which is is a subtype of wolf spider but is 
completely eyeless.

- Subclasses in Eiffel are not necessarily subtypes and may not be 
substitutable for superclasses. If it's good enough for Eiffel, it's good 
enough for my hypothetical Borg subclasses.

You can always declare that Bertrand Meyer doesn't "understand OOP at 
all" too.


-- 
Steven



More information about the Python-list mailing list