It would be helpful if we can a) access the compan...
# language-proposals
m
It would be helpful if we can a) access the companion object of the class of an instance without using reflection, and a) define that a type implementing an interface must also have their companion object implement a specific interface.
Copy code
interface WithCompanion<T : Any>

fun <T : Any> companionOf(instance: WithCompanion<T>): T =
    TODO() // intrinsic
Now the following would be possible:
Copy code
interface FooInterface: WithCompanion<Any>

fun bar(foo: FooInterface) {
   val companion: Any = companionOf(foo)
   // …
}
Which would be very useful for a frequent pattern, where you have instances of something that has a shared definition across all instances:
Copy code
// Types implement `Event` must also have their companion implement `Event.Type`
interface Event : WithCompanion<Event.Type> {
    interface Type {
        val id: String
    }
}

// We can get the companion of an Event instance without reflection.
val Event.type get() = companionOf(this)

// Example
class SunriseEvent : Event {
    companion object : Event.Type {
        override val id = "sunrise"
    }
}

fun storeEvent(event: Event) {
     // Not possible like this at the moment without manually adding `type` to every single class implementing `Event` 
    val typeId = event.type.id
    // …
}
👍 1
r
I don't understand what you gain by forcing the companion to represent the type. All you appear to get is your extension property, which would be cleaner and more flexible implemented as a property of the
Event
interface.
m
a) I gain consistency by defining that every companion of an
Event
implementation exists and implements
Event.Type
. So you can use
SunriseEvent.id
for example (and other functionality). You can also pass
SunriseEvent
around as an object, e.g.
loadEventsOfType(SunriseEvent)
. b) If I merely add
type: Type
as a property to the interface, every single of my dozens of classes must repeat the following:
Copy code
val type: Type get() = Companion.type
Instead of repeating myself over and over again I would like to simply state the relation between a class’s instance and its companion explicitly. There’s a relation between a class and its companion already. We simply cannot access it programmatically without reflection nor with static type safety.
h
This reminds me of some usecases of keep87, typeclasses. I have this requirement often with factories.. i require a type to have a No args constructor. Yes, this would be really really nice :)
d
Kotlin/Native can do this. Maybe it can be made MPP. iirc the annotation to achieve this is
@AnnotatedObject
or similar; kotlinx.serialization uses it.
m
Kotlin/Native can do this. Maybe it can be made MPP. iirc the annotation to achieve this is 
@AnnotatedObject
 or similar; kotlinx.serialization uses it.
I can’t find any info about this. Do you have any link?
d
m
Ah, yeah. That may be related to Objective-C’s associated objects.
h
I am interested in a discussion about this topic :) i see it is related to the "namespace" feature mentioned in the Roadmaps Presentation in future of kotlin. Namespaces would be the first step, but for me equally important would be to have namespaces somehow be part of the type contract, just like you propose, @Marc Knaup. I guess the most tricky part is implementing it on the jvm, as there is no instance of a class for static things, but just the class itself. Keep87 typeclasses implement that with an additional Parameter and seperating static and non static things into class and typeclass. That's very elegant and there are many use cases for that.