What the code is supposed to do
The function printSum takes an array of integers and prints the total of all its numbers, once. Called with Array(1, 2, 3), it should print:
6
The starter code prints three lines instead:
1
2
3
The call in mainFunction is correct and must stay as it is. The two mistakes are both inside printSum.
def printSum(nums: Array[Int]): Unit = {
for (num <- nums) {
var sum = 0
sum += num
println(sum)
}
}
What goes wrong
Trace the loop for 1, 2, 3. Everything inside the braces of the for runs again on each pass, and that includes the line var sum = 0.
num | sum after var sum = 0 | sum after sum += num | Printed |
|---|---|---|---|
| 1 | 0 | 1 | 1 |
| 2 | 0 | 2 | 2 |
| 3 | 0 | 3 | 3 |
Mistake 1: the total is created inside the loop
A variable declared inside a block exists only for that pass of the block. On every pass the loop body creates a brand-new sum that starts at 0, adds one number to it and throws it away. Nothing is carried from one number to the next, so the earlier numbers are lost.
Mistake 2: the print is inside the loop
The call println(sum) is in the loop body too, so it runs once per number. Even with a total that carried over, it would print the partial sums 1, 3 and 6 on three lines. The total is only complete after the last number has been added, so the print belongs after the loop.
The fix
Move the declaration above the loop, so the total is created once and lives for the whole call. Move the print below the loop, so it runs once with the finished total.
def printSum(nums: Array[Int]): Unit = {
var sum = 0
for (num <- nums) {
sum += num
}
println(sum)
}
def mainFunction(): Unit = {
printSum(Array(1, 2, 3))
}
Now sum goes 0, 1, 3, 6 across the loop, and println prints 6 a single time.
Fixing only the first mistake is a half-fix. With the declaration above the loop but the print still inside it, the program prints the running totals:
1
3
6
The last line is the right answer, which makes this version easy to mistake for a fix. Both changes are needed.
Language details
var sum = 0must be avar, because+=reassigns it. Scala infers the typeInt.- The loop
for (num <- nums)goes through the array elements in order, from index 0 to the last one. - The return type
Unitmeans the function gives back no useful value. It produces output as a side effect.
Edge cases and common mistakes
- An empty array. The fixed function prints 0, since the loop never runs and
sumkeeps its starting value. - Negative numbers. They need no special handling.
Array(-4, 4, 10)prints 10. - Overflow. The sum is an
Int, so a total beyond 2147483647 wraps around without any error. - Tracing by hand. When a loop gives wrong output, write down the value of each variable at the start of every pass. A variable that is back at its starting value on every pass is declared too deep.
Key takeaways
- A variable that accumulates across iterations is declared before the loop.
- Code that should run once with the final result goes after the loop.
- A wrong output with the right last line, like 1, 3, 6, is still a bug.
