Now that I understand your proposal better, let me go back and address some of the concerns I didn’t address directly.
I understand that calling
a.doSomething()
is equivalent to calling to callingdoSomething()
, but leaving it all up to compiler could make everything very complicated.
I am not sure the alternative you are proposing. In both proposals the compiler must decide what doSomething()
resolves to. We are just discussing what rules it would use to do so.
Consider situation where
B
is a subclass ofA
, then the function[A, B].f
will shadow[B].f
First, this problem already exists in extension and is dealt with by explicit resolution rules. The above example is equivalent to the following,
open class A {
fun B.f() {}
}
class B : A() {}
fun B.f() {}
fun t() {
val a = A()
val b = B()
with (b) {
with (a) {
f()
}
}
}
The scoping rules dictate that the fun B.f() {}
in A
will be called not the module level fun B.f() {}
. This is because the resolution stops looking for extensions once a match is found and the A
’s fun B.f() {}
is found as A
’s scope is consulted first. My proposal would not change this.
Second, shadowing will exist in any proposal and it exists in yours as well. Given the same example, with both [A, B].f
and [B].f
in scope, you will need a rule that decides which is applies when in a scope chain containing A, B
.
You are trying to mix type-based and order-based approach, which probably won’t end well.
My proposal is simply given [A, B].f
is in scope, A
is considered to have an extension member B.f
.
My proposal is recursive, in that, [A, B, C].f
implies A
has [B,C].f
which in turns implies B
has C.f
. My original syntax is more clear in this regard as it would then state that A.B.C.f
implies A
has an extension member B.C.f
which implies B
has an extension member C.f
. In other words, A.B.C.f
can be seen as extending A
with B.C.f
. With this understanding it is clear what is being extended, A
in this case, and what the extension is, B.C.f
, and when it applies, when A
is part of the unqualified scope.
It introduces no new concepts to the language or new ways to look up members in scope. It affects the collection of extensions.