Sealed Nested Level Inconsisencies


#1

Are there any issues I can follow to address the inconsistencies around sealed class vs where the extender is?

For example, this works:

sealed class Foo
class Bar : Foo()

But this doesn’t:

class SomeClass {
    sealed class Foo
    class Bar : Foo()
}

I have an advanced multilevel data hierarchy I need to build and was hoping Kotlin would be as reasonable as Scala wrt sealed (i.e. same file is enough). I understand sealed constructors are private, I wish they would have been package private or some other way this would be supported. Is there an issue I can follow for this or will it never be fixed? Also, is there an issue to correct the documentation that says “A sealed class can have subclasses, but all of them must be declared in the same file as the sealed class itself” to mention this caveat?


#2

I would just open a new issue: https://youtrack.jetbrains.com/issues/KT
As for the documentation, you can either send a pr yourself or just add it to the issue if you are not sure how it should properly behave.

It think this should be allowed

class SomeClass {
    sealed class Foo
    class Bar: Foo()
}

but this shouldn’t

class SomeClass {
    sealed class Foo
}
class Bar: Foo()

but that’s just my opinion.


Anyways, as a workaround you can still use

class SomeClass {
    sealed class Foo {
        class Bar: Foo() 
    }
}

Not always true, if Bar is not nested in Foo but just in the same file, Kotlin will create a public constructor for Foo which is marked as synthetic.


#3

Done: https://youtrack.jetbrains.com/issue/KT-25478. I was expecting one to already be open I could follow, hence the question, but I couldn’t find one. Hopefully it’s not a dupe.

Disagree personally. For instance, for Kotlin AST you might have:

class File {
    sealed class TopLevelObject
}

class Class : TopLevelObject

I know it may seem weird, but sadly I have to work this way until sealed interfaces are built. I am a bit disappointed that Kotlin is so JVM hamstrung for those that use it on other platforms.

While true, my API looks bad when I am forced to conflate the idea of a subclass with a nested class.

Good to know! I didn’t check the bytecode. But often synthetic constructors are used for inner classes anyways, so it makes sense.