Skip to content

Instantly share code, notes, and snippets.

@udalov
Created March 28, 2016 11:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save udalov/3c0d4a0f17eaf9ca2e2a to your computer and use it in GitHub Desktop.
Save udalov/3c0d4a0f17eaf9ca2e2a to your computer and use it in GitHub Desktop.
Spec: sealed + data

Summary

Allow data classes as sealed class subclasses.

sealed class Base {
    data class Derived(...) : Base()
}

Motivation / use cases

Description

data modifier should now be allowed on subclasses of sealed classes.

componentN, equals, hashCode, toString, copy are generated exactly as for usual data classes. Only primary constructor parameters of the data class itself should participate in all of those functions.

sealed class Base(val sealedParam: Any?) {
    data class Derived(val dataParam: Any?) : Base(null)
}

fun test(d: Base.Derived) {
    val (x) = d       // ok, x = d.dataParam
    val (x, y) = d    // error, no component2 in Derived
}

<...>

Effort

  • Front-end: little
    • relax the diagnostic
    • improve some existing diagnostics: "data class cannot inherit from class" is no longer true
  • Back-end (JVM):
    • always generate equals/hashCode/toString for data classes (KT-6206)
  • Standard library: none
  • IDE: ???
  • Tools: none

Drawbacks

None (?)

Open questions

  • Sealed class can have super-classes itself, will there be any problems with that? Consider sealed subclasses of sealed classes
sealed class Base {
    data class Derived(val s: String) : Base()
    override fun toString() = "Base"
}

Base.Derived("ok").toString() // should return "Derived(s='ok')", not "Base"
  • For uniformity consider generating toString() to object declarations, similar to data classes (KT-4107)

Related issues

Some issues were closed around 1.0 because data class inheritance had been forbidden. They should be located and investigated again wrt this proposal.

  • KT-11306: won't be able to e.g. specify abstract toString() in sealed class

<...>

Alternatives

We could support sealed interfaces. Some of the use cases will be covered because data classes can inherit from sealed interfaces. However, it's not possible to store data in an interface. Also it's possible to inherit such interface from Java, which would break exhaustive whens.

Possible future advancements

  • Allow data classes extend other classes?
  • Allow non-val/var (incl. vararg) trailing constructor parameters for data classes?

(???) Comparison to other languages?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment