Implementing C-Style For-Loops In Kotlin
Kotlin does not have C-style for-loops. This is fine because I prefer using the idiomatic for-loops (built to use iterators) anyway. But there is a problem: Kotlin does not allow dynamic limiting conditions in its for-loops (discussion).You have to use a while loop to achieve the same functionality. It can be annoying.
Kotlin has two features that I love the most (among many many others):
- in case a lambda expression has a single parameter, kotlin puts its value in a special variable
it
(unless otherwise specified). - if the last parameter of a function is a lambda, that lambda can be put outside the function call.
We can use these to make a simple polyfill for C-style for-loops like this (oldFor
must be inline
, otherwise the generated bytecode has poor performance because of 4 lambda arguments):
1
2
3
4
5
6
7
8
9
10
11
12
13
package utils
inline fun oldFor(
initialSetter: () -> Int,
limitingCondition: (Int) -> Boolean,
updater: (Int) -> Int,
codeBlock: (Int) -> Unit) {
var i = initialSetter()
while (limitingCondition(i)) {
codeBlock(i)
i = updater(i)
}
}
Which can be driven like this:
1
2
3
4
5
6
7
8
9
10
11
package main
import utils.oldFor
fun main(args: Array<String>) {
var n = 12
oldFor({ 0 }, { it < n }, { it + 1 }) {
println(it)
n /= 2
}
}
Which prints out:
0
1
2
Notice how we use the special variable it
to make oldFor
terse. We specify the code block as a lambda expression outside the oldFor
call, giving the impression that oldFor
is an in-built language construct. Also notice that we can use dynamic limiting condition with oldFor
(n
gets updated on each pass).