Earlier quoted context omitted.
You can do something like this: class MyTransaction { fun begin() {} fun commit() {} } fun MyTransaction.query() {} fun MyTransaction.update() {} inline fun transaction(tblock: MyTransaction.() -> R): R { val t = MyTransaction() t.begin() try { return t.tblock() } finally { t.commit() } } fun test() { // update() doesn't compile, no such method val hello = transaction { query() update() query() "Hello" } println("$he…
I must admit I don't entirely understand how your approach works, but it seems like it requires all the functions you want to use in transactions to live on MyTransaction (even if only as extension methods)? I want to be able to write normal functions including quite high-level ones that take some business objects and return MustHappenInTransaction[SomeOtherBusinessObject], and pass these return values through generi…
typealias MustBeInTransaction = MyTransaction.() -> Unit
fun makeObject(i: Int): MustBeInTransaction {
return { /* do something with i or whatever in a transaction */ }
}
fun test() {
var genericArray = arrayOf(1, 2, 3).map { makeObject(it) }
//genericArray.forEach { it() } // fails to compile
transaction {
genericArray.forEach { it() }
}
}
Like that?