Destructuring multiple components


#1

Just a suggestion.

On this moment,we destruct by calling the functions componentN() where N appoints to the component we need.

class Test(val a: A, val b: B, val c:C){
    operator fun component1() = a.first.toUpperCase()
    operator fun component2() = b.first.toUpperCase()
    operator fun component3() = c.first.toUpperCase()
    operator fun component4() = a.second % 5 + 1
    operator fun component5() = b.second % 5 + 1
    operator fun component6() = c.second % 5 + 1
}
my current solution

On this moment, to make the above easier, I’m using an interface and its implementation to make it more clear:

interface Destruct6<out A, out B, out C, out D, out E, out F> {
    operator fun component1() : A
    operator fun component2() : B
    operator fun component3() : C
    operator fun component4() : D
    operator fun component5() : E
    operator fun component6() : F
}
class Destruct6Impl<out A, out B, out C, out D, out E, out F>(
    private val comp1: ()->A,
    private val comp2: ()->B,
    private val comp3: ()->C,
    private val comp4: ()->D,
    private val comp5: ()->E,
    private val comp6: ()->F
) : Destruct6<A, B, C, D, E, F> {
    override operator fun component1(): A = comp1()
    override operator fun component2(): B = comp2()
    override operator fun component3(): C = comp3()
    override operator fun component4(): D = comp4()
    override operator fun component5(): E = comp5()
    override operator fun component6(): F = comp6()
}

Now I can write the above class as:

class Test(val a: A, val b: B, val c:C)
    :Destruct6<String,String,String,Int,Int,Int> 
    by Destruct6Impl(
         {a.first.toUppercase()},
         {b.first.toUppercase()},
         {c.first.toUppercase()},
         {a.second % 5 + 1},
         {b.second % 5 + 1},
         {c.second % 5 + 1}
    )

To make it more clear, I would like to have a function for destructing, where you can return a dataclass:

class Test(val a: A, val b: B, val c:C){
    operator fun components() = Destruct6(
         a.first.toUppercase(),
         b.first.toUppercase(),
         c.first.toUppercase(),
         a.second % 5 + 1,
         b.second % 5 + 1,
         c.second % 5 + 1
    )
}

The adventage over the seperated components is:

  • Removed boilerplate, which makes it clearer
  • When Destruct6 is a data class, maybe in the future the destruction names can be inferred (just like variables in constructors)?
  • By calling a function for creating Destruct6, the representation of the destruction variables can easily be delegated.

The advantage over my solution is:

  • You don’t need the interface anymore (was needed for not having Destruct6 as parent)
  • In my solution, everyting has to be known at class declaration without workaround.

#2

Can you please describe a real scenario where you need to manually implement multiple componentN() functions in such a way?