Subsumption at all costs

Gilad Bracha gives a pretty compelling argument with good examples on why we should favor subsumption over other things (ADT/inheritance) in "Subsuming Packages and other Stories".

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

It turns out...

It turns out that you cannot have ADTs, inheritance and subsumption in one language.

Is there another paper that argues this claim? I'm not sure you can reach this conclusion from a few examples all involving name shadowing.

I didn't get everything

Case 1 (and the other similar cases) is caused by overloading, there is a well-know 'tension' between overloading and inheritance.

Case 3 is interesting and IMHO a bug in Java specification: C shouldn't have access to foo!

A violation of subsumption or of something else?

The field shadowing problem is interesting. But I'm not totally convinced that it is a violation of subsumption. Bracha's "case 1" example:

class S { final int f = 42;}
class T extends S { final String f = “!”;}

new T().f; // “!”
((S) new T()).f; // 42

The first field access is for a field named "T.f" and the second is for a field named "S.f". They are different fields. The first part of the field name ("S." or "T.") is determined by the static type of the expression, which is fully under programmer control.

I see how this can be confusing, but it seems wrong to categorize it as a violation of subsumption.

What if you pass an instance

What if you pass an instance of S to code operating on a T? The old field is accessed, not the new field as some might expect.

The coercion S->T also happens implicitly, so you could argue that this is the source of the problem, but this shadowing behaviour is inconsistent with how methods overriding is treated in these languages, so a case for a violation of subsumption is certainly possible.

What is "semantic substitution"?

Taking another look at this, I think the problem here is that "semantic substitution" hasn't been defined. It seems like Bracha's definition is along the lines of simple context-ignorant AST substitution, which doesn't correctly compensate for the fact that Java uses static type information to perform slot lookup.

That's a reasonable definition of substitution, since it's probably close to how the human brain works. But this just means that the root problem is how the language's definition of safe substitution matches up with the programmer's intuition -- a fuzzier problem. The subsumption behavior is just a symptom.

And even if...

...you decide to call that subsumption failure, you could always choose to solve the problem by e.g. having a different syntax for accessing an object through its public interface than is used to access fields with local knowledge. Then public access would satisfy the subsumption property.

In any event, the claim I quoted above doesn't look warranted to me.