gbracha / lessRestrictedMixins

Lift some, but not all, of the current restrictions on mixins in Dart.
Apache License 2.0
2 stars 2 forks source link

Subtype or subclass in 12.1? #5

Closed eernstg closed 9 years ago

eernstg commented 9 years ago

In the updates for section 12.1, I noted the words 'It is a static warning if the superclass of A is not a subtype of S.'

Let's assume the following setup:

abstract class M extends Ss {}  // Mixin with declared super.
abstract class A extends Sd with M .. {}  // Application of M to Sd.

If Sd is a subclass of Ss, all the inherited method implementations from Ss will also be available from Sd; some of them may be overridden, but there is some inherited implementation anyway.

This means that lookups for method/getter/setter implementations from Sd (that is, super.f(), super.f, super.f = .. for some f) will succeed.

In contrast, if Sd is just a subtype and not a subclass of Ss, no such guarantee exists. So super invocations may fail.

Wouldn't this justify a change to the wording 'It is a static warning if the superclass of A is not a subclass of S.'? In fact, it is always possible to determine with certainty at the mixin application site whether there are any super invocations that have no implementation to select, which could be a warning in its own right.

For other self-sends, I agree that it's sufficient to maintain the overall expectations from instances, i.e., it is enough to transfer implements from the mixin to the application.

gbracha commented 9 years ago

If Sd is a subtype of Ss, it must implement the public API of Ss. However, it might be abstract, in which case a super call might fail. Furthermore, there might be a private superclass that is accessible to M in Ss (because they come from the same library) but not in Sd. I assume these are the scenarios you are concerned with.

I don't think the solution is to require a subclass relation. As the proposal says, there are two reasons for the requirement. One is to maintain the simple rule that if you use a mixin, you are a subtype of it. Subtyping suffices for that. The other is to typecheck super calls. Maybe we should follow your suggestion and check those separately. This does violate encapsulation, and requires looking into the mixin's source code, which is regrettable.

gbracha commented 9 years ago

Actually, there is already wording in the spec to address this. In section 12.1:

Let K be a class declaration with the same constructors, superclass and interfaces as C, and the instance members declared by M (respectively M1, . . . , Mk). It is a static warning if the declaration of K would cause a static warning. It is a compile-time error if the declaration of K would cause a compile-time error.

This will in fact catch any problematic use of super calls (and does in fact give up on encapsulation).

I should reword the discussion to make this clear.

eernstg commented 9 years ago

OK, got it!