# Data Class Composition without Inheritance

**URL:** <https://discuss.kotlinlang.org/t/data-class-composition-without-inheritance/26618>\
**Category:** Language Design\
**Created:** [April 2, 2023, 2:53pm UTC](https://discuss.kotlinlang.org/t/data-class-composition-without-inheritance/26618 "2023-04-02T14:53:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![smorescoder](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/smorescoder/32/10226_2.png) [@smorescoder](https://discuss.kotlinlang.org/u/smorescoder)\
**Post date:** [April 2, 2023, 2:53pm UTC](https://discuss.kotlinlang.org/t/data-class-composition-without-inheritance/26618/1 "2023-04-02T14:53:29Z")

</div>

Data class “inheritance” is one of the most sought-after features of Kotlin. Just take a look at the amount of discussion and upvotes across these sites:

- [Stack Overflow](https://stackoverflow.com/search?q=data+class+inheritance) (Especially [this question](https://stackoverflow.com/questions/26444145/extend-data-class-in-kotlin))
- [Kotlin Forum](https://stackoverflow.com/questions/26444145/extend-data-class-in-kotlin)

I’m aware that traditional inheritance for data class would cause **many issues** , such as inconsistent `componentN` functions, ambiguous `copy` signatures, impossible to define a correct `.equals` implementation, and just generally breaking the Liskov substitution principle. Nevertheless, developers often want to compose their data models, often to “extend” / augment a data class with just one or two additional fields.

Current work-arounds for a lack of data class extensibility include:

1. Declaring a base abstract class with shared fields, implementing the base class in two separate data classes.
2. Declaring a base interface with the shared fields, implementing the interface in two separate data classes.

But these methods involve repeating the full set of fields in the base definition at least three times – once in the base class/interface, and once in both implementations. This is cumbersome and tedious, especially with large data models with dozens of fields, and makes the process to add new fields error-prone.

I would love to see Kotlin have _some_ way to support data class composition without repetition, i.e. define a data class using all of the fields from another data class, plus some additional fields. Without being overly prescriptive, because I am open to any solution, I think one potential way to accomplish this is to define an `augments` keyword, which embeds the parameters of another class’ constructor into a new class definition:

```kotlin
data class MyModel(
  val prop1: String,
  val prop2: String,
)

data class MyAugmentedModel(
  val prop3: String,
) augments MyModel

val augmented = MyAugmentedModel("prop1", "prop2", "prop3")

```

Note that there is no inheritance happening here. Any instance of `MyAugmentedModel` will not also be an instance of `MyModel`, because they are separate data class and can never be considered equal. It could be helpful to automatically generate extension functions to convert between these two overlapping models, however:

```kotlin
fun MyAugmentedModel.toMyModel() = 
  MyModel(this.prop1, this.prop2)

fun MyModel.toMyAugmentedModel(prop3: String) = 
  MyAugmentedModel(this.prop1, this.prop2, prop3)

```

I am initially proposing `augments MyModel`, instead of typical `: MyModel()`, to avoid ambiguity with the existing syntax which defines inheritance and requires repetition of constructor parameters. `extends` could cause confusion with Java’s `extends`, which imlplies inheritance.

The `augments` syntax as a way to create constructors that have all the fields of another constructor could be useful outside of the contexts of data classes as well, because repetitive constructors is not just a data class problem, but I haven’t thought enough about that yet.

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [April 2, 2023, 7:47pm UTC](https://discuss.kotlinlang.org/t/data-class-composition-without-inheritance/26618/2 "2023-04-02T19:47:31Z")

</div>

Perhaps take a look at [https://youtrack.jetbrains.com/issue/KT-15471/Provide-support-for-dataarg-and-named-spread-convention](https://youtrack.jetbrains.com/issue/KT-15471/Provide-support-for-dataarg-and-named-spread-convention) and [https://youtrack.jetbrains.com/issue/KT-8214/Allow-kind-of-vararg-but-for-data-class-parameter](https://youtrack.jetbrains.com/issue/KT-8214/Allow-kind-of-vararg-but-for-data-class-parameter) which try to solve the same problem with a `dataarg` parameter modifier that hence will let you do:

```auto
data class MyAugmentedModel(
  dataarg val myModel: MyModel,
  val prop3: String,
)
```

---

<div class="post-metadata">

**Author:** ![smorescoder](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/smorescoder/32/10226_2.png) [@smorescoder](https://discuss.kotlinlang.org/u/smorescoder)\
**Post date:** [April 2, 2023, 8:07pm UTC](https://discuss.kotlinlang.org/t/data-class-composition-without-inheritance/26618/3 "2023-04-02T20:07:50Z")

</div>

Thanks @kyay10, those are very useful links, and does look like it would solve the problem I described! In probably a better way than the idea I had proposed as well, but no surprise there. 🙂

Judging by [this comment](https://youtrack.jetbrains.com/issue/KT-8214/Allow-kind-of-vararg-but-for-data-class-parameter#focus=Comments-27-5474969.0-0), it seems this feature is prioritized behind the K2 compiler, so I’ll just have to wait. 🥲
