The problem: repeated code
Suppose a student named Andy has to write three lines on the whiteboard three times. As a Scala program, that is nine println statements:
println("This is Andy")
println("Andy made a mistake")
println("Andy suffers the consequences")
println("This is Andy")
println("Andy made a mistake")
println("Andy suffers the consequences")
println("This is Andy")
println("Andy made a mistake")
println("Andy suffers the consequences")
This works, but it doesn't scale. If the teacher asks for 10 or 100 copies, you paste the same lines 10 or 100 times. If the text changes, you must find and edit every copy, and missing one leaves a bug. The program says the same thing over and over.
The fix: put the lines in a function
A function gives a group of statements a name. You write the statements once and run them by calling the name:
def printMessage(): Unit = {
println("This is Andy")
println("Andy made a mistake")
println("Andy suffers the consequences")
}
printMessage()
printMessage()
printMessage()
The output is the same nine lines, but the program is much shorter. Each call to printMessage() runs the three println statements again.
What functions buy you
- More repetitions are cheap. Printing the text three more times means adding three short calls, not nine more lines.
- Changes happen in one place. To change the student's name to Mike, edit the three lines inside
printMessage. Every call picks up the change at once. - Names explain intent.
printMessage()says what is happening without the reader going through the three lines. - Smaller pieces. A long program becomes a set of small functions that each do one job.
The calls themselves are still repeated. Loops, which come later, remove that repetition too, but you still need the function to name the work.
Defining versus calling
The syntax is the same as in the previous lessons. A function is defined with def, a name, empty parentheses, the result type Unit and a body in braces. The definition alone prints nothing. The body runs once per call, and a call is the name followed by parentheses. Leaving the parentheses out is a compile error in Scala 3: method printMessages must be called with () argument.
The lesson's exercise
The starter code has mainFunction with a line that prints Sorry, I didn't hear you and two comments that mark where the introduction should happen. The task is to introduce yourself twice without writing the lines twice.
- Define
introduceYourselfbelow the first comment. Usedef, empty parentheses, the result typeUnitand= {. The body will hold the whole introduction, so it is written once. - Print the first line inside it:
println("My name is Andy"). - Print the second line next:
println("I love coding"). It stays inside the braces. - Call it first in
mainFunction, under the first comment, withintroduceYourself(). Both print lines run. - Call it again, under the second comment, after the "Sorry" line. Both lines are printed a second time, with no repeated code.
The solution:
// Function goes here:
def introduceYourself(): Unit = {
println("My name is Andy")
println("I love coding")
}
def mainFunction(): Unit = {
// Introduce yourself the first time:
introduceYourself()
println("Sorry, I didn't hear you")
// Introduce yourself again:
introduceYourself()
}
Running mainFunction() prints:
My name is Andy
I love coding
Sorry, I didn't hear you
My name is Andy
I love coding
If the introduction ever changes, only the body of introduceYourself needs an edit, and both calls follow.
Common mistakes
- Defining the function but not calling it. Nothing from the function appears in the output.
- Calling it only once. The expected output has the introduction twice.
- Leaving a
printlnoutside the braces. The line then belongs to the surrounding code instead of the function. - Calling the function at the wrong point. The calls must sit on either side of the "Sorry" line, because the output follows the order of the statements.
- Dropping the parentheses in the call.
introduceYourselfalone doesn't compile.
Key takeaways
- A function lets you write a group of statements once and run it as often as you need.
- Changing the behaviour means editing one body, not every copy.
- Defining a function runs nothing; each call
name()runs the whole body.
