# Method in companion object, or extension function?

**URL:** <https://discuss.kotlinlang.org/t/method-in-companion-object-or-extension-function/27443>\
**Category:** Language Design\
**Created:** [September 27, 2023, 5:55pm UTC](https://discuss.kotlinlang.org/t/method-in-companion-object-or-extension-function/27443 "2023-09-27T17:55:57Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nikclayton](https://avatars.discourse-cdn.com/v4/letter/n/67e7ee/32.png) [@nikclayton](https://discuss.kotlinlang.org/u/nikclayton)\
**Post date:** [September 27, 2023, 5:55pm UTC](https://discuss.kotlinlang.org/t/method-in-companion-object-or-extension-function/27443/1 "2023-09-27T17:55:57Z")

</div>

Is there any practical difference between defining a function inside a companion object, compared to creating it as an extension function on the same companion object?

For example, here:

```auto
data class Foo(val s: String) { 
    companion object {
        fun from_as_companion(s: String): Foo {
            return Foo(s)
        }
    }
}

fun Foo.Companion.from_as_extension(s: String): Foo {
	return Foo(s)
}

fun main() {
    val f1 = Foo.from_as_companion("hello,")
    val f2 = Foo.from_as_extension("world")
    
    println("${f1.s} ${f2.s}")
}

```

From a code-style perspective I think the from\_as\_extension() approach is slightly more readable, because the reader has fewer levels of nesting to consider; the function body is indented just one level, compared to the 3 levels that function\_as\_companion is nested to.

There is a byte code difference that I don’t understand – if I look at the generated bytecode in Android Studio the code for both functions is the same except for the entry. from\_as\_companion looks like:

```auto
[...]
  public final from_as_companion(Ljava/lang/String;)Lapp/pachli/network/model/Foo;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
    // annotable parameter count: 1 (visible)
    // annotable parameter count: 1 (invisible)
    @Lorg/jetbrains/annotations/NotNull;()
   L0
    ALOAD 1
    LDC "s"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V
[...]

```

while from\_as\_extension has an extra checkNotNullParameter:

```auto
  public final static from_as_extension(Lapp/pachli/network/model/Foo$Companion;Ljava/lang/String;)Lapp/pachli/network/model/Foo;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
    // annotable parameter count: 2 (visible)
    // annotable parameter count: 2 (invisible)
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
   L0
    ALOAD 0
    LDC "$this$from_as_extension"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V
    ALOAD 1
    LDC "s"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V

```

Assuming this isn’t in any performance sensitive code are there any other reasons to avoid extension functions in this case?

---

<div class="post-metadata">

**Author:** ![gidds](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/gidds/32/10865_2.png) [@gidds](https://discuss.kotlinlang.org/u/gidds)\
**Post date:** [September 28, 2023, 10:00pm UTC](https://discuss.kotlinlang.org/t/method-in-companion-object-or-extension-function/27443/2 "2023-09-28T22:00:34Z")

</div>

I think there’s a subtle difference in scoping: while _all_ code that has access to the companion object will automatically see all its (public) methods, code might not see the extension function if it’s not in scope (i.e. is not defined in this class/package, and hasn’t been `import`ed).

(The other major difference with extension functions is the behaviour around subclasses — but of course you can’t subclass an object, so that’s not relevant here.)

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [October 16, 2023, 7:10am UTC](https://discuss.kotlinlang.org/t/method-in-companion-object-or-extension-function/27443/3 "2023-10-16T07:10:26Z")

</div>

I imagine there’d be a difference for reflection… dunno if that’s relevant to you, though. If you use reflection to look at `Foo`’s companion object and list all methods, you wouldn’t get the extension method, I don’t think.

---

<div class="post-metadata">

**Author:** ![nikclayton](https://avatars.discourse-cdn.com/v4/letter/n/67e7ee/32.png) [@nikclayton](https://discuss.kotlinlang.org/u/nikclayton)\
**Post date:** [October 25, 2023, 10:53am UTC](https://discuss.kotlinlang.org/t/method-in-companion-object-or-extension-function/27443/4 "2023-10-25T10:53:52Z")

</div>

Thanks both. I hadn’t thought about the scoping issue.
