ashish@home:~$

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):

  1. in case a lambda expression has a single parameter, kotlin puts its value in a special variable it (unless otherwise specified).
  2. 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).