# For-loop dynamic step

**URL:** <https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429>\
**Category:** Language Design\
**Created:** [January 29, 2018, 10:45am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429 "2018-01-29T10:45:06Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![drosbusch](https://avatars.discourse-cdn.com/v4/letter/d/3e96dc/32.png) [@drosbusch](https://discuss.kotlinlang.org/u/drosbusch)\
**Post date:** [January 29, 2018, 10:45am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/1 "2018-01-29T10:45:06Z")

</div>

Dear Kotlin community,

Is it possible to have a for-loop in Kotlin with a dynamic step (so it can change)?  
I’m having trouble translating the following Java-code into Kotlin:

```
    for(int i = 0; i < 500; i+= (i < 40 ? 10 : 20)) {
           System.out.println("Now at "+ i);
       }

```

Is this possible?

I’ve read in an older post ([How to for loop with var i](https://discuss.kotlinlang.org/t/how-to-for-loop-with-var-i/721)) that there is no way to mutate i, so am I right to assume I’ll have to use while?

Thank you.

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [January 29, 2018, 10:56am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/2 "2018-01-29T10:56:38Z")

</div>

I think, that you should have never used `for` loop for that in the first place and it is good that kotlin does not allow this usage. If I understand correctly, in your example variable `i` is not some kind of index, it has some meaning. And using such variables inside for loop could lead to some nasty side effects in a large code.

Variant using while is not much longer:

```kotlin
var i = 0
while( i < 500 ){
  println("Now at $i")
  i += if( i < 40 ) 10 else 20
}

```

---

<div class="post-metadata">

**Author:** ![drosbusch](https://avatars.discourse-cdn.com/v4/letter/d/3e96dc/32.png) [@drosbusch](https://discuss.kotlinlang.org/u/drosbusch)\
**Post date:** [January 29, 2018, 11:01am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/3 "2018-01-29T11:01:16Z")

</div>

Hm, did not see the danger in that, but that’s probably due to my inexperience.  
Thanks for the quick answer, much appreciated!

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [January 29, 2018, 11:10am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/4 "2018-01-29T11:10:01Z")

</div>

The problem arises when you have a large code.

Pitfall number one: You accidentally or intentionally changing `i` somewhere inside your loop. You should obviously never do it, but changing the increment is the first step in this direction.

Pitfall number two: For some reason, you want to change the behavior of your dynamic step. You do it in one place, but forget to do in another and now you have two iterations with different number of steps.

Pitfall number three: Suppose you want a more complicated behavior and need three different steps instead of two. You won’t be able to do it with `for` anymore. You will have to either delegate step calculation to additional function which is even worse, or rewrite everything. In my example you can do it easily by replacing `if` by `when`.

Pitfall number four occurs when you have some parallel operations messing with `i`. In my example, you can simply replace `i` by `AtomicInteger` and make your operations thread safe.

There could be additional motivation, but in general I think that classic `for` loop should be deprecated and replaced by functional-style operations wherever it is possible.

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [January 29, 2018, 11:50am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/5 "2018-01-29T11:50:42Z")

</div>

Try to switch your point of view, I hope this code is more readable.

```run-kotlin
fun main(args: Array<String>){
//sampleStart
    (0 until 40 step 10).asIterable()
            .plus(40 until 500 step 20)
            .forEach { i ->
                println("Now at " + i)
            }
//sampleEnd
}

```

Edit: use asSequence instead of asIterable, see below

---

<div class="post-metadata">

**Author:** ![drosbusch](https://avatars.discourse-cdn.com/v4/letter/d/3e96dc/32.png) [@drosbusch](https://discuss.kotlinlang.org/u/drosbusch)\
**Post date:** [January 29, 2018, 12:09pm UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/6 "2018-01-29T12:09:43Z")

</div>

Hey that looks very intuitive and readable indeed!  
Cheers!

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [January 30, 2018, 6:18pm UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/7 "2018-01-30T18:18:56Z")

</div>

> [@fvasco](#):
>
> (0 until 40 step 10).asIterable()  
> .plus(40 until 500 step 20)  
> .forEach { i -\>  
> println("Now at " + i)  
> }

The asIterable is not necessary as it is already an Iterable. This can be shortened to the following (and yes the parentheses are necessary):

```run-kotlin
fun main(args: Array<String>) {
//sampleStart
    ((0 until 40 step 10) + (40 until 500 step 20))
            .forEach { println("Now at $it") }
//sampleEnd
}
```

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [January 30, 2018, 9:22pm UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/8 "2018-01-30T21:22:10Z")

</div>

You are right,  
however an `Iterable` plus another one produces an `Iterable`,  
a `Range` plus another one produces a `List`.  
Your code allocates the entire array an some -generally- hundreds of `Integer` (but it is more readable).

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [January 30, 2018, 9:24pm UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/9 "2018-01-30T21:24:07Z")

</div>

@fvasco `Iterable` concatenated with another `Iterable` produces `List`, so again all its elements are materialized.  
Did you mean `asSequence()`?

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [January 31, 2018, 5:44am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/10 "2018-01-31T05:44:27Z")

</div>

Ops,  
You are right, thanks for reply.

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [January 31, 2018, 7:58am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/11 "2018-01-31T07:58:54Z")

</div>

I prefer this solution, I consider this enough readable and has minor memory impact than other implementations.

```run-kotlin
    import kotlin.coroutines.experimental.buildSequence

fun main(args : Array<String>){
//sampleStart
    buildSequence {
        yieldAll(0 until 40 step 10)
        yieldAll(40 until 500 step 20)
    }.forEach {
        println("Now at $it")
    }
//sampleEnd
}

```

This works if you are experimenting the “coroutinex” library. (False, see below)

---

<div class="post-metadata">

**Author:** ![kirill\_rakhman](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/kirill_rakhman/32/1692_2.png) [@kirill\_rakhman](https://discuss.kotlinlang.org/u/kirill_rakhman)\
**Post date:** [February 9, 2018, 4:23pm UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/12 "2018-02-09T16:23:14Z")

</div>

> This works if you are experimenting the “coroutinex” library.

This works without kotlinx.coroutines

---

<div class="post-metadata">

**Author:** ![mrtact](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mrtact/32/4751_2.png) [@mrtact](https://discuss.kotlinlang.org/u/mrtact)\
**Post date:** [February 13, 2018, 3:05am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/13 "2018-02-13T03:05:42Z")

</div>

This is more or less what I was about to go figure out how to respond, and you beat me to it. Well done!

---

<div class="post-metadata">

**Author:** ![vladimir\_schneider](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/vladimir_schneider/32/1420_2.png) [@vladimir\_schneider](https://discuss.kotlinlang.org/u/vladimir_schneider)\
**Post date:** [February 19, 2018, 9:59am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/14 "2018-02-19T09:59:05Z")

</div>

When I read threads like this I feel like I fell into a Bizzaro Universe where the simplicity of a C for loop with its explicitly exposed initialization, looping condition and next iteration stepping, without any hidden costs that you have to “keep in mind” beyond what you write, is considered undesirable.

Only to be followed by “new improved” language constructs that go into a long discussion of Iterable vs Sequence vs range operations, to wind up with a lot more code and hidden implications that must be considered (instantiation of the full list being one, foreach being about 3x slower than explicit for loop is another).

The while loop does create equivalent code but the beauty of C-for syntax was to eliminate such ugly boiler plate in the first place.

Please, don’t tell me that you are confused by C-for loop’s complex syntax or difficulty of intuiting its operation. The examples of Kotlin code you provide speak volumes to your ability to handle complexity and grasp non-intuitive constructs.

Why not admit that elimination of some language features in Kotlin, even when necessitated by other concerns, is a regression not evolution, which we live with to enjoy real improvements it offers.

Justifying it with code that resembles “perl poetry” or “obfuscated C” compared to the elegance of a C for loop is trying to put lipstick on a pig.

---

<div class="post-metadata">

**Author:** ![mrtact](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mrtact/32/4751_2.png) [@mrtact](https://discuss.kotlinlang.org/u/mrtact)\
**Post date:** [February 19, 2018, 8:55pm UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/15 "2018-02-19T20:55:16Z")

</div>

> [@vladimir\_schneider](#):
>
> Please, don’t tell me that you are confused by C-for loop’s complex syntax or difficulty of intuiting its operation.

Please, don’t tell me you’ve ever accidentally blown past the end of a C array and randomly written crap into memory.

All programming is about tradeoffs. On modern hardware, my preference is to favor constructs that protect developers from making dumb catastrophic mistakes.

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [February 26, 2018, 2:03am UTC](https://discuss.kotlinlang.org/t/for-loop-dynamic-step/6429/16 "2018-02-26T02:03:40Z")

</div>

> [@vladimir\_schneider](#):
>
> When I read threads like this I feel like I fell into a Bizzaro Universe where the simplicity of a C for loop with its explicitly exposed initialization, looping condition and next iteration stepping, without any hidden costs that you have to “keep in mind” beyond what you write, is considered undesirable.

For an entertaining explanation of why this other world is better see this video: [https://www.youtube.com/watch?v=Gsfmfeb2XW8](https://www.youtube.com/watch?v=Gsfmfeb2XW8)
