sealed class Command { class Function(val name:String): Command() class Test(val nr: Int, val name:String): Command() sealed class Foo: Command(){ class FooBar(val x:Int, val y: Int, val z: Int): Foo() class FooFoo(val coords:Coords): Foo() class Default: Foo() } class Repeat(val times:Int, val command: Command): Command() class DoAs(val selector:Selector, val command: Command): Command() class Coords(val x:Int, val y: Int, val z:Int) } class Selector private constructor(){ companion object{ fun parse(string: String) : Selector = TODO() } } fun main(){ // these should be equivalent // function test // function "test" Command.Function("test") // function main:test.second // function "main:test.second" Command.Function("main:test.second") // test 15 hi Command.Test(15, "hi") // test 16 "hello there" Command.Test(16, "hello there") // foo foobar 100 200 15 Command.Foo.FooBar(100, 200 ,15) // foo foofoo 100 200 15 Command.Foo.FooFoo(Command.Coords(100,200,15)) // foo (I used Foo.Default as a default here, if another way would be better that would be cool too) Command.Foo.Default() // repeat 2 function test Command.Repeat(2, Command.Function("test")) // doas @e[tag=blue] foo // doas @e[tag=blue,] foo // doas @e[ tag= blue,] foo Command.DoAs(Selector.parse("@e[tag=blue]"), Command.Foo.Default()) }