while Loops and Stopping Early
Asha wants to know on which run of the week she passed 20 km. Nobody can say in advance how many runs that takes, so a for over a fixed range is the wrong shape. A while loop keeps going until a condition says stop.
The rule
A while loop needs a condition that can turn false and a var that moves it there.
val runs = List(5.0, 8.5, 3.2, 10.0)
var total = 0.0
var i = 0
while total < 20 && i < runs.length do
total += runs(i)
i += 1
// total is 26.7 and i is 4: she passed 20 km on her 4th run- The condition is checked before each pass. If it is false at the start, the body never runs.
- Something in the body must move the condition towards false. Here
i += 1steps to the next run andtotalgrows. Leave out thei += 1in a loop such aswhile i < runs.length do println(runs(i))and it prints the first run forever. - The
i < runs.lengthhalf guards against a goal that is never reached. With a goal of 30 km the total would never get there, and without that second test,runs(4)would throw.
Two things from Java or C are missing:
- No do-while. Scala 3 dropped it, so put the test at the top.
- No
breakkeyword. When a loop must end early, Scala 3 offersboundaryandbreakfromscala.util:
import scala.util.boundary, boundary.break
val firstLong = boundary:
for km <- runs do
if km >= 8 then break(km)
0.0
// firstLong is 8.5break(km) jumps out of the boundary block and makes km its value. If the loop finishes without breaking, the block's last expression, 0.0, is the value.
Often a collection method says the same thing more directly: runs.find(km => km >= 8) returns Some(8.5). Loops are still worth knowing, because they are the fallback when no method fits.
The shortcut
Before writing a while, answer three questions: What stops it? What moves it towards stopping on each pass? What if the stop never comes? If you cannot answer all three, the loop is not finished.
Pass 1
total is 0.0, under 20, and i = 0 is in range. Add 5.0: total is 5.0 and i becomes 1.
Drills
Answer fast — trust the rule.
After the 20 km loop above finishes, what is i?
var i = 0; while i < runs.length do println(runs(i)) — what happens?
Does Scala 3 have a do-while loop?
In the boundary example, what is firstLong?
The goal is 30 km, but the week only adds up to 26.7. Which condition stops safely?
Remember
- A while loop checks its condition before each pass, and a var must move it towards false.
- Ask: what stops it, what moves it, and what if the stop never comes?
- Trap: Scala 3 has no do-while and no
breakkeyword; test at the top, and useboundaryandbreakto leave early.
