Problem overview
The starting code prints three short introductions by writing nine println calls one after another:
fun mainFunction() {
println("My name is Andy")
println("I code in Python")
println("I have a dog")
println("My name is Mike")
println("I code in Java")
println("I have a cat")
println("My name is Sarah")
println("I code in JavaScript")
println("I have a parrot")
}
The task is to produce exactly the same output in a better way: write a function named printMessages that takes the varying parts as parameters, and call it three times from mainFunction.
Approach: find what changes
Compare the three groups of lines. Each group has the same shape:
My name isfollowed by a name;I code infollowed by a language;I have afollowed by an animal.
The fixed text stays the same and three values change: the name, the language and the animal. Each changing value becomes a parameter, and the fixed text moves into the function body, where it is written once.
Step by step
- Define the function above
mainFunction. Writefun printMessages(name: String, language: String, animal: String). In Kotlin each parameter is a name, a colon and a type, and the parameters are separated by commas. - Print the three sentences. In the body, use three
printlncalls. In each, put the fixed text in double quotes and insert the matching parameter with a string template:$name,$languageand$animal. Inside double quotes Kotlin replaces$namewith the value ofname, so no+is needed. - Call the function three times. In
mainFunction, callprintMessages("Andy", "Python", "dog"), thenprintMessages("Mike", "Java", "cat"), thenprintMessages("Sarah", "JavaScript", "parrot"). Arguments are matched to parameters by position, so the first is the name, the second the language and the third the animal.
The solution in Kotlin
// Define and implement the function printMessages here:
fun printMessages(name: String, language: String, animal: String) {
println("My name is $name")
println("I code in $language")
println("I have a $animal")
}
fun mainFunction() {
// Call printMessages 3 times here:
printMessages("Andy", "Python", "dog")
printMessages("Mike", "Java", "cat")
printMessages("Sarah", "JavaScript", "parrot")
}
Running mainFunction() prints the same nine lines the original code printed, in the same order.
String templates
A $ followed by a variable name inside a string literal inserts that variable's value. The name ends at the first character that can't be part of a name, so in "I have a $animal" the template runs to the closing quote. When text must follow a name directly, wrap the name in braces: "${animal}s" gives dogs for "dog". The template is the same as joining pieces with +, but it is shorter and easier to read.
Parameters and arguments
The names in the header are parameters. The values in a call are arguments. Each call runs the body again with new values in name, language and animal. Those variables are read-only and exist only while that call runs.
Edge cases and common mistakes
- Wrong argument order. All three parameters are
String, so the compiler can't notice a swapped order.printMessages("Python", "Andy", "dog")compiles and printsMy name is Python. - Missing arguments. A call with two arguments for three parameters is a compile error.
- Missing types. Kotlin requires a type on every parameter.
- Extra or missing spaces. The text must match exactly, including the single space before each inserted value, such as the space after
My name is. - Quoting the variable. Without the
$,"My name is name"prints the wordname. - Printing in the calls. The function does the printing. The calls pass only arguments.
Why this is better
The new version states the shape of an introduction once. To add a fourth person, you add one line with three arguments. To reword a sentence, you change one line in the function, and all introductions follow. The original version would need one edit per person.