Youssef Shoaib [MOD]
04/12/2022, 10:39 AMTypeWrapper
that is passed to the lambda, effectively making all the receivers before it visible.
inline fun <A, B, C, R> withContexts(a: A, b: B, c: C, block: context(A, B, C) (TypeWrapper<C>) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(a, b, c, TypeWrapper.IMPL)
}
sealed interface TypeWrapper<out A> {
object IMPL: TypeWrapper<Nothing>
}
(Psst: here's a function to generate those up to an arity of 25):
fun generateDeclarations(index: Int): String {
val alphabet = "BCDEFGHIJKLMNOPQSTUVWXYZ"
val letters = ("A" + alphabet.take(index)).toList()
val lastType = letters.last()
val types = letters.joinToString(", ")
val receivers = letters.joinToString(", ") { it.lowercase() }
val parameters = letters.joinToString(", ") { "${it.lowercase()}: $it" }
@Language("kotlin") val codeTemplate = """
inline fun <$types, R> withContexts($parameters, block: context($types) (TypeWrapper<$lastType>) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block($receivers, TypeWrapper.IMPL)
}
""".trimIndent()
return codeTemplate
}
Richard Gomez
04/12/2022, 12:49 PMYoussef Shoaib [MOD]
04/14/2022, 3:47 PMsimon.vergauwen
04/20/2022, 6:47 AMwith
.
https://gist.github.com/nomisRev/6c31a24e6d0dbf0106b10a9048162929Youssef Shoaib [MOD]
04/20/2022, 7:00 AMwith
keyword would actually be (as in the one suggested in the KEEP). The n-arity with
works in nearly every syntactic place where a with
keyword would be useful.
For instance, if you want to be in a context depending on an if check, a simple if(condition) with(context1, context2) { }
suffices without extra indentation. Same with for
, while
, when
branches, even functions (you can do fun foo() = with(c1, c2) { }
). I don't think most users would need to include a context in the middle of a function based on nothing, they're more likely to already use something like if
or while
and then enter a context.
The only place where this falls short, and where a with
keyword would be nice, is inside lambdas. It's possible that a user wants to add an extra scope inside a lambda, and needing extra indentation for that would be quite bad.
Still, though, I don't see the need for a with
keyword, especially because its semantics would be a bit unnatural (as in it affects code coming right after it in the same scope. It is sort of like a variable being defined in the middle of a block and used afterward, except that it is implicit, which can make it hard to see a with
in the middle of like 50 lines of code)simon.vergauwen
04/20/2022, 8:11 AMYoussef Shoaib [MOD]
04/20/2022, 8:18 AMSummable
contexts or other various arithmetic contexts, and so 23 contexts could happen in production.simon.vergauwen
04/20/2022, 8:32 AM