# Compound extension

**URL:** <https://discuss.kotlinlang.org/t/compound-extension/10722>\
**Category:** Language Design\
**Created:** [December 10, 2018, 11:19pm UTC](https://discuss.kotlinlang.org/t/compound-extension/10722 "2018-12-10T23:19:29Z")\
**Posts on this page:** 1\
**Showing post:** 24

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [December 29, 2018, 7:30am UTC](https://discuss.kotlinlang.org/t/compound-extension/10722/24 "2018-12-29T07:30:55Z")

</div>

## 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:

1. **Create a list of actual contexts** `G, A, B, C, ...` where `G` is a global context. Top level non-extension functions have only `G` 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 types `Cy` where `y` is the index
2. **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 to `G, B, A`. Context list uses compile-types so types with different parameters are considered to be different types so `List<Int>` won’t replace `List<Double>`.
3. **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 like `fun <T> [T, Operation<T>].doSomething()`. We will call receiver types `Rx` where `x` is the index.
4. **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 map `Rx to Cy`. If there is a bound pair for each of `Rx` then function is considered resolved and bound to context. Multiple `R` could be bound to the same context `C`, 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](https://discuss.kotlinlang.org/t/compound-extension/10722/17). Seems to be working the same way. It resolves to the closest context even if this context implements both receivers.

---

_[View the full topic](https://discuss.kotlinlang.org/t/compound-extension/10722)._
