using context parameters, is there a way to tell a...
# getting-started
b
using context parameters, is there a way to tell an extension function for a DSL that this context is available inside the lambda?
✅ 1
I've got this piece of code
Copy code
val ctx = Context()
        val root = RecordProperty("", Props())
        val result = context(ctx) {
            root {
                test.set("value")
                nested {
                    -inner
                }
            }
        }
but when I move that thing into a function like this:
Copy code
fun <T> buildUpdate(properties: T, action: TypeSafeUpdateTest.Props.() -> Unit): Record<String, Any?> {
        val ctx = Context()
        val p = Props()
        val root = RecordProperty("", p)
        context(ctx) {
            root {
                p.action()
            }
        }
        return ctx.updates
    }
I'm getting this kind of error
the lambda on root { } also expects a context, modifying it
Copy code
context(ctx: Context)
    operator fun invoke(value: T.() -> Unit) {
        context(ctx.path(path)) {
            properties.value()
        }
    }
y
I think what you want is a contextual function type:
Copy code
fun <T> buildUpdate(properties: T, action: context(Context) TypeSafeUpdateTest.Props.() -> Unit): Record<String, Any?> {
    val ctx = Context()
    val p = Props()
    val root = RecordProperty("", p)
    context(ctx) {
        root {
            p.action()
        }
    }
    return ctx.updates
 }
today i learned 1
b
that's it, thanks!
❤️ 1
my first real use case for context parameters btw and mind blown
y
I know right! They're incredible!
b
alternative would have been to iterate over all class properties and partially apply their methods to pass down a parameter or add the context object as a constructor parameter to all dsl parts
y
Exactly, which would've been awful Context params really unlock a whole new dimension of dsl design imo