# Declaring external extension members

**URL:** <https://discuss.kotlinlang.org/t/declaring-external-extension-members/16445>\
**Category:** Language Design\
**Created:** [February 22, 2020, 6:01am UTC](https://discuss.kotlinlang.org/t/declaring-external-extension-members/16445 "2020-02-22T06:01:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kotlinIsland](https://avatars.discourse-cdn.com/v4/letter/k/9d8465/32.png) [@kotlinIsland](https://discuss.kotlinlang.org/u/kotlinIsland)\
**Post date:** [February 22, 2020, 6:01am UTC](https://discuss.kotlinlang.org/t/declaring-external-extension-members/16445/1 "2020-02-22T06:01:25Z")

</div>

I want to add an extension member to a class, but I believe this is currently impossible.  
example:

```kotlin
class Foo {
    fun String.foo() {}
}

fun Foo.String.bar() {} // hypothetical syntax

fun doFoo(fn: Foo.() -> Unit) { /* ... */ }

fun main() {
    doFoo {
        "asdf".foo()
        "asdf".bar()
    }
}

```

I found this limitation when I was using the HTML DSL and wanted to add additional functions to String.

---

<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:** [February 22, 2020, 6:08am UTC](https://discuss.kotlinlang.org/t/declaring-external-extension-members/16445/2 "2020-02-22T06:08:44Z")

</div>

It is called multiple receivers and discussed in [KEEP-176](https://github.com/Kotlin/KEEP/pull/176). I personally dislike dot syntax proposed by @chuckjaz and prefer bracket notation `[Foo, String].bar()`. The proposal has a lot of potential and covers most of type-class uses. Now all we need is to wait until new compiler is out (so there are some free kotlin language developers) and persuade @abreslav to consider it.

---

<div class="post-metadata">

**Author:** ![kotlinIsland](https://avatars.discourse-cdn.com/v4/letter/k/9d8465/32.png) [@kotlinIsland](https://discuss.kotlinlang.org/u/kotlinIsland)\
**Post date:** [February 22, 2020, 6:34am UTC](https://discuss.kotlinlang.org/t/declaring-external-extension-members/16445/3 "2020-02-22T06:34:04Z")

</div>

I don’t want to add the extension to Foo **and** String, I want to add the extension as an extension to String as a member of Foo.  
[https://kotlinlang.org/docs/reference/extensions.html#declaring-extensions-as-members](https://kotlinlang.org/docs/reference/extensions.html#declaring-extensions-as-members)

---

<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:** [February 22, 2020, 6:52am UTC](https://discuss.kotlinlang.org/t/declaring-external-extension-members/16445/4 "2020-02-22T06:52:50Z")

</div>

It is exactly the same. Member extension has two receivers: member receiver and extension receiver. The idea of multiple receivers is to detach what was previously member receiver from actual member. If you had a function `fun [Foo, String].bar()`, you can call it with `with(foo){ "ddd".bar() }` since you have two receivers - one provided by `with` function and one provided explicitly.

There are some details though. Multiple receivers could be implemented in different ways. The order could matter (break backward compatibility in some cases) or it could not (it is in my final proposal and it also breaks some rare corner cases).

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [February 22, 2020, 7:14am UTC](https://discuss.kotlinlang.org/t/declaring-external-extension-members/16445/5 "2020-02-22T07:14:24Z")

</div>

> [@kotlinIsland](#):
>
> I found this limitation when I was using the HTML DSL and wanted to add additional functions to String.

Working with the kotlinx-html library was also the first time when I direly needed this feature.

@darksnake is right, it is called multiple receivers. And the keep he linked to is what you need to wait for.

> [@kotlinIsland](#):
>
> I don’t want to add the extension to Foo **and** String, I want to add the extension as an extension to String as a member of Foo.

That’s more or less the multiple receivers. Multiple receivers does not mean that the extension is added to String and Foo separately. The extension cannot be called when only one of String or Foo is available in the context. Both must be available.

---

<div class="post-metadata">

**Author:** ![kotlinIsland](https://avatars.discourse-cdn.com/v4/letter/k/9d8465/32.png) [@kotlinIsland](https://discuss.kotlinlang.org/u/kotlinIsland)\
**Post date:** [February 22, 2020, 7:34am UTC](https://discuss.kotlinlang.org/t/declaring-external-extension-members/16445/6 "2020-02-22T07:34:45Z")

</div>

Ah I see, thanks.
