Deprecated range syntax

Hmm… that was all mildly confused and had some subtle bugs.

Here’s the mental model I think makes more sense:

0.0 to 3.1415 in 4 is equivalent to taking the integer range 0 to 4 and remapping it to an evenly spaced double range where 0 => 0.0 and 4 => 3.1415.

0.0 until 3.1415 in 4 is equivalent to taking the integer range 0 until 4 and remapping it to an evenly spaced double range where 0 => 0.0 and 4 => 3.1415, thereby omitting 3.1415 (since 4 gets omitted in the integer range).

a to b in 0 is ill-defined, you could make an argument for any of a, (a+b)/2, and b, but I think a is the right call.

a until b in 0 is empty.

a to|until b in k for k>0 is well defined.

Corresponding code (hopefully without bugs :wink: ):

case class MyDoubleRange3(start: Double, end: Double, steps: Int, inclusive: Boolean) {
  def foreach(f: Double => Unit): Unit = {
    if (steps == 0) {
      if (inclusive) f(start) // or f(end) or f((start+end)/2)
    } else if (steps > 0) {
      f(start)
      for (i <- 1 until steps) f(start + ((end - start) / steps) * i)
      if (inclusive) f(end)
    }
  }
}

We can bikeshed if the integer range should start at 0 or 1 - C vs Pascal anyone!? :wink:

I guess it depends on if you interpret k as the “steps between the points” (= start at 0), or the “number of points I encounter in the foreach()” (= start at 1).

For the latter:

case class MyDoubleRange4(start: Double, end: Double, steps: Int, inclusive: Boolean) {
  def foreach(f: Double => Unit): Unit = {
    if (steps == 1) {
      if (inclusive) f(start) // or f(end) or f((start+end)/2)
    } else if (steps > 1) {
      f(start)
      for (i <- 1 until (steps - 1)) f(start + ((end - start) / (steps - 1)) * i)
      if (inclusive) f(end)
    }
  }
}