Idiomatic Kotlin…


#1

A loop over a range can be written:

for (i in two..x) { total *= i }

or:

(two..x).forEach{i -> total *= i}

Are there any efficiency/performance considerations?

Which is currently deemed to be more idiomatic Kotlin?


#2

There isn't much of a style guide right now.

You can see what they compile down to in the Kotlin Bytecode window (bottom right of the screen in IntelliJ). They should both turn into something pretty equivalent once you tick the enable inlining box, so there’s little difference from an efficiency perspective. Thus it becomes a matter of readability. I find the first form more readable as it fits what I’m used to. I only use forEach when it’s at the end of a map/filter/collect type pipeline.


#3

More idiomatic in functional style would be using fold, which Kotlin provides


#4

If range is primitive (for example, int), it's better to use first version, because it will be faster: ss fast as old-style int for-loop in Java. Second version will involve manipulating iterator, and redundant boxing-unboxing. The latter case may be optimized in the future, it hardly will be as fast as for loop.

If you have non-primitive collection-like structure, both variants should be equally fast, and you can choose one you like more. Personally, I use the following heuristic: if loop body is really simple, than I prefer forEach (usually one statement), otherwise I choose for loop.


#5

As in:

(one .. x).fold(one){t, n -> t * n}

true, but I always wonder if constructs such as this compile to equally efficient code. Certainly they can do, but do they?

I am assuming that, like Python, there are named functions for things like t, n -> t * n, mul or some such, but that I haven’t found them consciously as yet.


#6

Data is a sequence of BigInteger, so it may be that the "loop control" is small comapred to the actual calculation. I guess I should benchmark.


#7

Though I think I prefer:

(one .. x).reduce{t, i -> t * i}