Best Practices to Avoid Shadowing Variables When Building a DSL

Hello Reddit. Bit new to Kotlin, though I’m pretty familiar with other languages that allow you to build DSLs easily. I’m currently working on a project with Jetpack Compose, and I’m really impressed with Kotlin’s ability to create DSLs that are very expressive.

However, I did notice that it’s super easy to accidentally have your DSL / blocks shadow different variables accidentally. In the code attached below, while we are in the outer block, foo has a value of 3, but which is changed to 4 temporarily within the inner block.

“`kotlin data class SetFoo(val foo: Int) data class SetFooAndBar(val foo: Int, val bar: Int)

fun setFooTo3AndBarTo42(exec: SetFooAndBar.() -> Unit) { SetFooAndBar(3, 42).exec() }

fun setFooTo4(exec: SetFoo.() -> Unit) { SetFoo(4).exec() }

fun main() { // Adds foo and bar into scope setFooTo3AndBarTo42 { println(“Foo is ${foo}”) println(“Bar is ${bar}”)

 // Leaves bar as it is, but shadows foo with a new value setFooTo4 { println("Foo is ${foo}") println("Bar is ${bar}") } // Back to the old values println("Foo is ${foo}") println("Bar is ${bar}") } 

} “`

While the example has clear names like setFooTo4, our codebase uses this for things like Theme() which might inject a primaryColor and defaultPadding variables.

My Questions: 1) Is it generally considered best practice to allow blocks to implicitly inject in variables? In the react community they went through something similar, where props would get injected by various higher order components, but now the renderProps way of explicitly naming every variable in the lambda is in fashion. What’s the best practice in the Kotlin world? 2) Is there a way I could force a compile error if a variable is shadowed in this way?

submitted by /u/tdinkar
[link] [comments]