What the code is supposed to do
The program has an array named languages holding three strings and a for loop that should print one sentence per language. The expected output is:
I think Python is cool!
I think Java is cool!
I think JavaScript is cool!
The code you start with produces three lines too, but every line is the same:
let languages = ["Python", "Java", "JavaScript"]
for language in languages {
print("I think language is cool!")
}
It prints I think language is cool! three times. Your job is to make the sentence change with each pass of the loop.
What goes wrong
The loop itself is correct. for language in languages runs its body once per element, and on each pass the constant language holds the current element: first "Python", then "Java", then "JavaScript".
The bug is inside the body. The text between the quotes is a string literal, and Swift prints a literal exactly as written. The word language in "I think language is cool!" is just seven letters of text, not a reference to the loop variable. The variable is created on every pass and then never used.
The compiler notices this and warns that the immutable value language was never used and suggests replacing it with _. A warning about an unused loop variable is often the first clue that a loop body ignores its element.
Fixing it step by step
- Find the part of the message that must change. The words
I thinkandis cool!stay the same on every line. Only the language name differs. - Cut that part out of the literal. The string now has a gap between
I thinkandis cool!. - Fill the gap with string interpolation. Writing
\(language)inside the quotes tells Swift to put the value oflanguageat that spot. - Keep everything else. The array, the loop header and the
printcall are already right.
The fixed code in Swift
let languages = ["Python", "Java", "JavaScript"]
for language in languages {
print("I think \(language) is cool!")
}
A few Swift details are worth knowing here:
- Interpolation is a backslash and parentheses. Inside a string literal,
\( ... )evaluates the expression between the parentheses and inserts the result as text. It can hold more than a name:"\(language.count) letters"inserts the length of the name. - Plain quotes never interpolate. Without the backslash, parentheses inside a string are ordinary characters. Interpolation needs the exact form
\(...). - The loop variable is a constant.
languageis declared by the loop as alet, so the body can read it but cannot assign to it. - Unused loop variables. When a loop only needs to repeat and does not need the element, write
for _ in languages. The underscore means "I don't need a name for this". - The scope is the loop body.
languageexists only between the braces, so the name is not available after the closing brace.
Common mistakes
- Putting the variable inside the quotes without interpolation. This is the bug in the lesson.
"I think language is cool!"prints the word, not the value. - Using the wrong quotes or no backslash.
"I think (language) is cool!"prints the parentheses and the word literally, because without the backslash they are ordinary characters. - Printing outside the loop. Moving the
printcall after the closing brace would not compile, becauselanguagedoes not exist there. - Changing the array. The output depends on the strings in
languages. Keep them in this order: Python, Java, JavaScript. - Mismatched text. The lesson's tests compare the output exactly, so the capital
I, the spaces and the exclamation mark all count.
Checking your fix
Run the program in the editor above. A correct fix prints the three sentences, each with a different language, and the unused-variable warning disappears because the loop variable is now used.
