Melhorar a sintaxe DSL

votos
0

Para iniciar o projeto de DSLs usando recursos de linguagem KOTLIN aprendendo, tenho a tentativa abaixo em uma DSL brinquedo para a criação de grupos de membros com os membros ter nomes. Estou à procura de ponteiros / sugestões sobre o seguinte

  1. Como posso evitar ter de grupos separados por ponto e vírgula, se nenhum ponto e vírgula o compilador dá

Groups.kt: 31: 45: erro: não resolvido referência: GRP membro val = grupo {membro {nome ( Bob)} membro {nome ( areia)}}

  1. I pode começar a usar um lambda para definir nameem vez de chamada de função?

  2. Posso evitar ter que ter nameser mutável em sala de aula MEMBER?

Meu código é

fun group(create: GROUP.() -> Unit) = GROUP().apply(create)

class GROUP {
    private val members = mutableSetOf<MEMBER>()

    fun member(create: MEMBER.() -> Unit) {
        val member = MEMBER()
        member.create()
        members.add(member)
    }

    override fun toString() = members.toString()

}

class MEMBER() {
    var name = 
    set(value) {
        field = value
    }

    fun name(nameToSet: String) {
        name = nameToSet
    }
    override fun toString() = MEMBER( + name + )
}

fun main(args: Array<String>) {
    val grp = group { member { name (Bob) }; member { name (Sandy) } }
    println(grp)
}

Atualmente a saída do código acima é

[MEMBRO (Bob), MEMBRO (areia)]

Publicado 20/10/2018 em 13:48
fonte usuário
Em outras línguas...                            


1 respostas

votos
1

Como posso evitar ter de grupos separados por ponto e vírgula

Ao utilizar o formato idiomática, utilizando linhas separadas. Afinal de contas, todo o ponto de um DSL é para tornar o código muito legível, mostrando a estrutura hierárquica, e fazendo tudo em uma única linha derrota a finalidade Wole:

val grp = group { 
    member { 
        name ("Bob") 
    }
    member { 
        name ("Sandy") 
    } 
}

Posso começar a usar um lambda para definir nome em vez de chamada de função?

Seria mais lógico e idiomática para remover a função nome e simplesmente atribuir um valor à propriedade:

name = "Bob"

Mas sim, você também pode substituir a função nome por

fun name(block: () -> String) {
    this.name = block()
}

E use

name {
    "Sandy"
}

Posso evitar ter de ter o nome ser mutável em membro da classe?

Sim: o lambda passada para a função de membro () iria personalizar uma classe MemberBuilder adicional, que seria mutável, mas permitiria criar um MEMBRO imutável:

fun group(create: GROUP.() -> Unit) = GROUP().apply(create)

class GROUP {
    private val members = mutableSetOf<MEMBER>()

    fun member(configure: MemberBuilder.() -> Unit) {
        val memberBuilder = MemberBuilder()
        memberBuilder.configure()
        members.add(memberBuilder.build())
    }

    override fun toString() = members.toString()

}

class MEMBER(val name: String) {
    override fun toString() = "MEMBER($name)"
}

class MemberBuilder {
    var name = "";

    fun build() = MEMBER(name)
}

fun main(args: Array<String>) {
    val grp = group {
        member {
            name = "Bob"
        }
        member {
            name = "Sandy"
        }
    }
    println(grp)
}

Além disso, observe que as classes, por convenção, são PascalCased, não ALL_CAPS.

Respondeu 20/10/2018 em 14:02
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more