Можно, конечно. Нужно в качестве коллбека передать лямбду с ресивером. А внутри ресивера определить экстеншн.
object Ctx {
fun String.hello() = "world"
}
fun contextFunction(block: Ctx.() -> Unit) {
Ctx.block()
}
fun main(args: Array<String>) {
contextFunction {
println("".hello())
}
}
Ещё можно упороться и добавлять функции в этот контекст извне. Не совсем обычным способом, но а что делать, если хочется странного.
val Ctx.hello2: String.() -> String get() = { "$this world" }
contextFunction{
"hi".hello2()
}