Skip to content

Instantly share code, notes, and snippets.

@dmcg
Created March 8, 2023 10:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmcg/945c56dad9f8cebfc6d357c28ececca3 to your computer and use it in GitHub Desktop.
Save dmcg/945c56dad9f8cebfc6d357c28ececca3 to your computer and use it in GitHub Desktop.
Kotlin multiple receiver ordering
// Improving the ergonomics of dual receivers while we wait for
// context receivers
// This has a method with two receivers
class Thing {
fun Context.foo(s: String): Int {
// pretend it needs a Context for some reason
return s.length
}
}
interface Context
fun demo() {
// given a thing and a context
val thing = Thing()
val context = object : Context {}
// we would like to do this
with(context) {
// val i: Int = thing.foo("banana") doesn't compile
}
// but we have to do this, which is confusing
with(thing) {
val i: Int = context.foo("banana")
}
// run gets us closer
with(context) {
val i: Int = thing.run { foo("banana") }
}
// we can elide run with invoke
operator fun <T, R> T.invoke(block: (T).() -> R): R = run(block)
// getting us closer to the thing we wanted to say
with(context) {
val i: Int = thing { foo("banana") }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment