Flow.range(5, 1, -1) emits [5] instead of [5, 4, 3, 2, 1]. The continuation condition only handles ascending ranges.
Reproducer (scala-cli):
//> using scala 3.8.3
//> using dep com.softwaremill.ox::core:1.0.4
import ox.flow.Flow
@main def repro(): Unit =
println(Flow.range(5, 1, -1).runToList()) // List(5) — expected List(5, 4, 3, 2, 1)
println(Flow.range(10, 0, -2).runToList()) // List(10) — expected List(10, 8, 6, 4, 2, 0)
Source:
https://github.com/softwaremill/ox/blob/770bed97a247a2536832ff7485953d75f53ccbeb/core/src/main/scala/ox/flow/FlowCompanionOps.scala
def range(from: Int, to: Int, step: Int): Flow[Int] = usingEmitInline: emit =>
var t = from
repeatWhile:
emit(t)
t = t + step
t <= to // wrong direction when step < 0
For descending ranges (step < 0), the loop guard should be t >= to. Scala's own 5 to 1 by -1 follows that convention.
There's also a corner case in the other direction: Flow.range(1, 5, -1) would loop until Int underflow, since t <= to stays true. Probably worth a step != 0 precondition while in the area.
Suggested fix:
def range(from: Int, to: Int, step: Int): Flow[Int] =
require(step != 0, "step must be non-zero")
usingEmitInline: emit =>
var t = from
repeatWhile:
emit(t)
t = t + step
if step > 0 then t <= to else t >= to
Happy to PR.
Flow.range(5, 1, -1)emits[5]instead of[5, 4, 3, 2, 1]. The continuation condition only handles ascending ranges.Reproducer (scala-cli):
Source:
https://github.com/softwaremill/ox/blob/770bed97a247a2536832ff7485953d75f53ccbeb/core/src/main/scala/ox/flow/FlowCompanionOps.scala
For descending ranges (
step < 0), the loop guard should bet >= to. Scala's own5 to 1 by -1follows that convention.There's also a corner case in the other direction:
Flow.range(1, 5, -1)would loop until Int underflow, sincet <= tostays true. Probably worth astep != 0precondition while in the area.Suggested fix:
Happy to PR.