Next iteration of resolution proposal
Here I will try to combine best parts of all current proposal and account for backward compatibility. The resolution could be done in following steps:
-
Create a list of actual contexts
G, A, B, C, ...
whereG
is a global context. Top level non-extension functions have onlyG
as context. Class members have that class as context. Extension function have their receivers added to context where they are defined. Running a function with receiver adds that receiver to the list of contexts where this function is defined.Types in the list could be duplicating. We will call those actual typesCy
wherey
is the index -
Normalize context list by walking list from left to right an removing elements which have the same type or subtype to the right. Meaning
G, A, B, A
will be reduced toG, B, A
. Context list uses compile-types so types with different parameters are considered to be different types soList<Int>
won’t replaceList<Double>
. -
Checking the definition of the function. Function receiver list is written in form of
[R1, R2, R3]
. Duplicate types or ambiguities throw compile error. Types could have parameters defined outside type list likefun <T> [T, Operation<T>].doSomething()
. We will call receiver typesRx
wherex
is the index. -
Binding of extension function. Each of types
R
in receiver set is matched against the elements of context list from right to left, binding it to first match and thus creating a mapRx to Cy
. If there is a bound pair for each ofRx
then function is considered resolved and bound to context. MultipleR
could be bound to the same contextC
, so it is possible to have just one context for multiple receiver types if it matches them both.
The normalization step is probably could be avoided in this scheme. The results of this procedure are the decision about binding and binding map Rx to Cy
.
This resolution is done via declared receiver types Rx
which are then substituted by actual runtime objects representing Cy
.
Compatibility check
-
[A].f === A.f
.Extension function with single argument should work exactly like existing extension function. It seems like it does. It is resolved and bound to the closest context matching its type. -
Match current member receivers strategy. Seems to be working the same way. It resolves to the closest context even if this context implements both receivers.