natpryce
01/15/2021, 1:18 PMfun doSomethingWith(arg : SealedBaseClass, otherArg: Int) = when(arg) {
is SubclassA -> doSomethingWith(arg, otherArg)
is SubclassB -> doSomethingWith(arg, otherArg)
}
fun doSomethingWith(arg : SubclassA, otherArg: Int) = ...
fun doSomethingWith(arg : SubclassB, otherArg: Int) = ...
What do people think of the idea of a sealed function, where the compiler generates the when boilerplate for you?
E.g.
sealed fun doSomethingWith(arg : SealedBaseClass, otherArg: Int)
fun doSomethingWith(arg : SubclassA, otherArg: Int) = ...
fun doSomethingWith(arg : SubclassB, otherArg: Int) = ...
I’m imagining the same rules would apply as for sealed classes: all implementations of the sealed function have to be in the same source file. And the compiler would check them for exhaustiveness.streetsofboston
01/15/2021, 1:28 PMdoSomething
was part of class MyClass
, then you could add an abstract method abstract fun MyClass.doSomething(): Result
to the SealedBaseClass.natpryce
01/15/2021, 1:30 PMLammert Westerhoff
01/15/2021, 2:58 PMwhen
gives you more power since you can group multiple classes together and have an else. With such a sealed function that would be difficult. So if you’d have a sealed function like that and later subclasses are added or requirements change you might find yourself changing it to a when
for the extra functionality. So even though I think it’s a nice idea I think in reality it would come with some potential downsides and it doesn’t really add something you cannot already do.Matiasdelbel
01/15/2021, 3:01 PMnatpryce
01/15/2021, 3:16 PMNir
01/15/2021, 3:21 PMdoSomethingWith
as part of the interface of the sealed class and implementing it in each member; it accomplishes the exact same thing you wrote here, but it avoids almost all the boilerplate, without needing new language featuresnatpryce
01/15/2021, 3:24 PMNir
01/15/2021, 3:25 PMnatpryce
01/15/2021, 3:25 PMNir
01/15/2021, 3:26 PMdoSomethingWith
then there's no boilerplate at allnatpryce
01/15/2021, 3:28 PMwhen
boilerplate is still there, now the doSomethingWith is a big function, and you have to do a dispatch on type even when you have a subclass of the sealed class.Nir
01/15/2021, 3:30 PMfun doSomethingWith(arg : SealedBaseClass, otherArg: Int) = when(arg) {
is SubclassA -> // snippet foo
is SubclassB -> // snippet bar
}
Or
fun doSomethingWith(arg : SubclassA, otherArg: Int) { // snippet foo }
fun doSomethingWith(arg : SubclassB, otherArg: Int) { // snippet bar}
They are exactly equivalent. In both pieces of code, you mention each subclass once