The problem: repeated code
Suppose a teacher asks three students to write an apology on the board. Without functions, the program repeats the same three lines for each student and changes only the name:
println("This is Andy")
println("Andy made a mistake")
println("Andy suffers the consequences")
println("This is Mike")
println("Mike made a mistake")
println("Mike suffers the consequences")
println("This is Sally")
println("Sally made a mistake")
println("Sally suffers the consequences")
That works for three students. Now imagine ten students and a longer apology. Changing one word of the text means finding and editing it in ten places, and missing one gives you a program that is inconsistent in a way nobody notices until later.
The fix: one function with a parameter
The three lines differ only in the name, so the name becomes a parameter. The shared text is written once, inside the function:
def printMessage(name: String): Unit = {
println("This is " + name)
println(name + " made a mistake")
println(name + " suffers the consequences")
}
printMessage("Andy")
printMessage("Mike")
printMessage("Sally")
This prints exactly what the long version printed. Each call passes a different argument, and inside the function the parameter name holds it.
What this buys you
- Changing the students means changing only the arguments in the calls.
- Changing the apology means editing the function body once. Every call picks up the change.
- Adding a student is one new line, not a new copy of the text.
The same idea scales to several parameters. When the pieces that change are a name and a favourite language, you pass two arguments. The parameters in the definition list those pieces and their types, and the arguments in the call fill them in the same order.
The exercise, step by step
The lesson asks for a function introduceYourself that introduces any person, and two calls to it.
- Define the function with
def, twoStringparameters namednameandlanguage, and the return typeUnit, because it prints rather than returns. - Print the name line. Join
"My name is "andnamewith+. The space at the end of the literal matters:+adds nothing between the parts, so without it the output would readMy name isAndy. - Print the language line the same way:
"I code in "followed bylanguage. - Introduce John in
mainFunctionby calling the function with"John"and"Python". The first argument goes toname, the second tolanguage. - Introduce Mary with a second call using
"Mary"and"JavaScript". No printing code is repeated.
// Function goes here:
def introduceYourself(name: String, language: String): Unit = {
println("My name is " + name)
println("I code in " + language)
}
def mainFunction(): Unit = {
// Introduce John:
introduceYourself("John", "Python")
// Introduce Mary:
introduceYourself("Mary", "JavaScript")
}
Running mainFunction prints:
My name is John
I code in Python
My name is Mary
I code in JavaScript
Common mistakes
- Swapped arguments.
introduceYourself("Python", "John")compiles, because both are strings, and printsMy name is Python. The compiler can check types but not meaning, so keep the order of the parameters in mind. - Leaving out the space in
"My name is ", which glues the name to the word before it. - Putting the name in quotes inside the function.
println("My name is name")prints the wordnameevery time. A parameter is used without quotes.
Key takeaways
- When blocks of code differ only in some values, turn those values into parameters.
- The shared logic then lives in one place, so a change is made once.
- Callers supply the changing parts as arguments, matched to the parameters by position.
