I'm trying to do something with Kotlin just for th...
# announcements
m
I'm trying to do something with Kotlin just for the sake of learning (and not for practical reasons). What I thought was: I want to see if I can have some sort of class built with mixins in Kotlin. That's not possible per-se since there's no multiple inheritance or any specific tool that allows it, but I tried to have a similar effect with delegates, knowing that
by
exists. So, my idea was to have, for example, something like this...
Untitled
s
Yup, that would work. In your example, you can make
Humanoid
and
interface
as well.
👍 1
m
the issue comes when I want to give it the behaviour of actual mixins - that is, I want to simulate it by allowing each interface/implementation of them have access to the
Person
class
for example
If I want the interfaces to have access to
Person.name
, I need to give them a reference to that instance of
Person
. The issue is, I can only do so by sacrificing some null safety, because, for example, in the constructor for
Person
,
talker
and
walker
need a reference to the
Person
- which is not possible because it's still being created (it's the constructor, after all, and there's no
this
for
Person
yet)
so I'm not saying it's not possible to have "the effect I want"
but I only found two solutions, and I'm wondering if Kotlin can help me. I'm basically pushing the language to see what it can do for me
this is one of them:
Which looks a bit silly to me.
basically, make
Person
just wrap the data, and give the implementations for the interfaces some constructors so it can be passed to them as well
so no issue there: everything is still immutable and safe, etc. and "just werks"
s
Kotlin does not have true mixins like that…..
👍 1
m
the other solution is making it look like Java: either by not using
by
and setting all the methods myself and/or make the interfaces have nullable properties, so I can pass them the reference after building the
Person
ah, okay, I get it
I was just having fun and that was technically all I wanted to know, thanks
s
Or something like this?.. More kotliny… 🙂
Copy code
interface Trait<M> {
    var m: () -> M
}

interface CanMove {
    fun move()
}

interface CanCommunicate {
    fun communicate()
}

interface TraitCanMove : CanMove, Trait<Person> {
    override fun move() {
        println("Moving person ${m().name}")
    }
}

interface TraitCanCommunicate : CanCommunicate, Trait<Person> {
    override fun communicate() {
        println("Talking to person ${m().name}")
    }
}

class Person private constructor(
    walker: TraitCanMove,
    talker: TraitCanCommunicate,
    val name: String
) : CanMove by walker, CanCommunicate by talker {
    companion object {
        operator fun invoke(
            walker: TraitCanMove,
            talker: TraitCanCommunicate,
            name: String
        ): Person {
            return { Person(walker, talker, name) }.prepareTraits(walker, talker)
        }
    }
}

fun <T> (() -> T).prepareTraits(vararg traits: Trait<T>): T {
    traits.forEach { it.m = this }
    return this()
}
m
Oh... I see the idea, but there's probably something about Kotlin I'm not aware of. The
companion object
works as a factory there, but
TraitCanMove
and
TraitCanCommunicate
are interfaces, which is what it asks for. So should I implement classes with them as base too, @streetsofboston?
s
Yes, you can do that. Using the companion object and the operator function invoke, you can define so-called smart-constructors.
Also, the code snippet I posted is just an idea.... not tested or vetted at all 😀
m
ah, I see
s
You may want to replace the `() -> T`s with `Lazy<T>`s....
m
anyway, it showed me some things I didn't think about, so it's still great for me, Kotlin is still alien to me in some basic areas, even though I think I can read most of it without issues
so I'm grateful to learn
many thanks