What the code is supposed to do
The program greets three students and then announces the class once. The expected output is:
Hey, Andy
Hey, Mike
Hey, Mary
Let's start the class!
The starter code compiles but prints the announcement after every greeting:
val students = Array("Andy", "Mike", "Mary")
for (student <- students) {
println(s"Hey, $student")
println("Let's start the class!")
}
Hey, Andy
Let's start the class!
Hey, Mike
Let's start the class!
Hey, Mary
Let's start the class!
What goes wrong
Both println calls are between the loop's braces, so both belong to the body. The body runs once per student, and with three students each call runs three times. The greeting needs that repetition, because it uses student. The announcement doesn't use the loop variable and should happen only once, when all the greetings are done.
That timing points to where it goes: after the loop. The program runs top to bottom, and the line below the closing brace runs when the loop has gone through every element.
Fixing it step by step
- Keep the greeting inside the loop. It must run for each student.
- Move the announcement below the closing brace. It is no longer part of the body, so it runs once.
The fixed code in Scala
val students = Array("Andy", "Mike", "Mary")
for (student <- students) {
println(s"Hey, $student")
}
println("Let's start the class!")
The flow is now: the loop prints three greetings, one per pass, then the loop ends and the last line prints once.
Before the loop or after it
This lesson and the one with the hungry line are mirror images. In both, a statement that should run once is stuck in the loop body. What differs is where it should go, and the expected output tells you which: a line that appears first in the output goes before the loop, a line that appears last goes after it. Reading the expected output top to bottom and matching each line to a statement is a reliable way to place everything.
Tracing the run
In the fixed program, the first pass sets student to "Andy" and prints Hey, Andy. The second and third passes do the same for Mike and Mary. After the third greeting there is no next element, so the loop ends and the flow continues with the first line below the closing brace, which prints the announcement. In the original, the announcement was part of every pass, which is why it appeared three times, once after each greeting.
Try changing the array to two names. The fixed code prints two greetings and one announcement. The original would print two announcements. A line inside the loop scales with the array; a line outside it doesn't.
Common mistakes
- Moving the announcement above the loop. It would print once, but before the greetings instead of after them.
- Moving the greeting out instead. The greeting uses
student, which exists only inside the braces, so the compiler reportsNot found: student. - Leaving the announcement inside the braces. Moving it a line down but before the closing brace changes nothing: it is still in the body, and the output is the same as the original.
