Companion object and function extension



One of my favorite feature in Kotlin is function extension. I especially like the fact that one can add extension function to a Companion object.


fun Int.Companion.random(max: Int): Int {
	return ThreadLocalRandom.current().nextInt(max)

However, some objects in the standard library do not have Companion, making it impossible to add an extension this way.

Example, the Boolean class:

fun Boolean.Companion.random(): Boolean { // Wrong ! Boolean Companion does not exist
	return ThreadLocalRandom.current().nextBoolean()

A simple solution could be to add Companion objects, even empty, to every relevant class in the standard library.

What do you guys think ? Or am I missing something ?


We’re going to address the problem with missing companion object for Boolean in Kotlin 1.1, here is the issue

However I’m not sure we have to introduce a companion for every class in the standard library. It looks like an overkill, if all what those companions are going to provide is to be a receiver for static-like extensions. Also there are a bunch of java classes which could benefit from having such extensions.

Maybe we should allow having companion extensions without requiring companion classes to exist at all?


That would be ideal indeed. I assumed it was not possible.


Along the same lines, would that be extendable to generics? For example:

val <T : Any?> T.TAG: String
  get() = (this as? Any)?.javaClass?.simpleName ?: "null"

So I could say something like Int.TAG


@eygraber What do you expect should be referred as this inside such generic function when it’s called on Int type (and not an instance of that type)?


@ilya.gorbunov I didn’t think about that. Perhaps KClass<T>, but it would need a new syntax. Something like:

val <T : Any?> T.Static.TAG: String
  get() = this.javaClass.simpleName


Any update on where we are with being able to have companion extension functions even if the receiving class has no companion object?

I just wrote an “extension” for KClass called forName() that works correctly even if the name represents one of the Kotlin primitive classes. However, since KClass has no companion object I ended up creating my own class called KClassCompanion and put a companion object on that. So, I have KClassCompanion.forName(), which will work and is somewhat intuitive.

However, this feels like a band-aid on a band-aid. There is no forName() equivalent and then when I try to write one it is ironically not pretty in a language whose stated goal is the opposite. The irony is that extension functions are called statically but it is not possible to use them statically. TBH, I somewhat question replacing simple static methods with a companion object because it appears to give rise to other issues and it is not clear to me what problem the companion object solves in the first place.

Or am I missing something?


This feature is not on the roadmap for Kotlin 1.2; we haven’t done any planning for subsequent versions yet.


Ok, thanks for the update!


Why would you need this. It seems like you just using a class as a namespace for top-level function. It seems like this could just be top-level function scoped using the file.