Problem overview
The quiz shows two functions and asks what the code prints when it runs:
def greetCoder(): Unit = {
println("Hello!")
println("Let's code!")
}
def mainFunction(): Unit = {
greetCoder()
greetCoder()
}
The options differ in the order and the number of lines:
- A:
Hello!,Let's code!,Hello!,Let's code! - B:
Hello!,Hello!,Let's code!,Let's code! - C:
Hello!,Let's code! - D: the pair of lines three times
You answer by declaring a string with the letter of the right option.
Approach: trace the execution
Work through the program the way Scala does, one statement at a time.
- The two
defblocks only define functions. Nothing prints while they are being defined. - Running
mainFunctionexecutes its body from top to bottom. The first statement is the callgreetCoder(). - That call runs the whole body of
greetCoder: it printsHello!, thenLet's code!, and the call ends. The output so far is two lines. - Control returns to
mainFunction, which reaches its second statement, anothergreetCoder(). The whole body runs again, printing the same two lines.
The complete output is:
Hello!
Let's code!
Hello!
Let's code!
That is option A.
A quick way to count
The number of printed lines is the number of calls times the number of println statements in the body: 2 calls times 2 lines gives 4 lines. A third call would add two more lines, which is what option D describes.
Anything written between the calls shows up between the copies of the output. If mainFunction had a println("---") between the two calls, the output would be:
Hello!
Let's code!
---
Hello!
Let's code!
The body of greetCoder stays intact in both copies, because a call finishes its whole body before the next statement of mainFunction runs.
Why the other options are wrong
- B would mean the function's two lines are interleaved across the calls. A call finishes its whole body before the next statement runs, so the two
Hello!lines can't come back to back. - C counts one call. The code makes two, and each runs the body in full.
- D counts three calls. Count the lines of the form
greetCoder()insidemainFunction: there are two.
The solution in Scala
val answer: String = "A"
/* Explanation:
In the first 4 lines of code we only define the function, so no "println()" statement will actually get executed.
Then, inside the main function, we call the function for the first time, so all the statements inside the function body will get executed from top to bottom.
So, the first function call will print "Hello!", then it will print "Let's code!" on two separate lines, and then this function call ends.
The output so far is:
Hello!
Let's code!
Then we call the function for the second time, and again all the statements inside the function body will get executed from top to bottom.
So the second function call will again print "Hello!", then it will print "Let's code!" on two separate lines, and then the function call ends.
So the output is:
Hello!
Let's code!
Hello!
Let's code!
*/
The Scala details in this line:
valdeclares a value that can't be reassigned. It is the natural choice for an answer you set once.varwould also work.- The type annotation is optional.
val answer: String = "A"andval answer = "A"mean the same, because Scala infersStringfrom the literal. - The letter is a string. It needs double quotes. A bare
Ais treated as a name, and the compiler reportsNot found: A. - The comment block is ignored. Everything between
/*and*/is skipped by the compiler.
Common mistakes
- Reading the function as printing once. The body runs once per call, so two calls give two copies of the output.
- Merging the calls. Each call prints its two lines together, in the body's order.
- Counting the definition as a call. The line
def greetCoder(): Unit = {doesn't run anything. OnlygreetCoder()with parentheses does. - Running the code to find the answer. Tracing the code by hand is the skill being practised here.
