Every time you create a name in Scala, the language makes you answer one question first: will this value ever change? There are two keywords, one for each answer:
valdeclares a read-only name — it is assigned exactly once and can never be reassigned.vardeclares a variable — the value is allowed to change later.
This is not just style. When you write val, the compiler guarantees the value never changes — if any line of your program tries to reassign it, the program simply refuses to compile. Whole categories of bugs disappear before the code even runs. That is why Scala programmers reach for val by default and only use var when a value genuinely needs to change — a counter, a running total, a position that moves:
val pi = 3.14159 // fixed forever — perfect for val
var lives = 3 // will go down when the player is hit
lives -= 1 // OK — lives was declared with var
println(s"lives = $lives") // prints: lives = 2
Two things to notice. First, there are no type annotations: Scala infers that pi is a Double and lives is an Int from the values you assign. Second, the s in front of the quotes turns the string into an interpolator — $lives drops the current value straight into the text (without the s, Scala would print the literal characters $lives).
The trap:
Sooner or later you will try to reassign a val:
val maxLives = 3
maxLives = 5 // trying to change the rules mid-game
The compiler stops you with this exact error — read it carefully, because it underlines the precise line that tried to do the changing:
-- [E052] Type Error: p1.scala:4:13 --------------------------------------------
4 | maxLives = 5
| ^^^^^^^^^^^^
| Reassignment to val maxLives
|
| longer explanation available when compiling with `-explain`
1 error found
The carets underline the exact assignment that broke the rule, and the message names the guilty binding: Reassignment to val maxLives. The two honest ways out are: keep val and stop reassigning, or switch the declaration to var because the value really does need to change. Compound operators hit the same wall — maxLives += 1 fails with the very same Reassignment to val error, because += is just a reassignment in disguise.
Assignment
Follow the Coding Tutorial to build a tiny game setup with one constant and one variable:
- Declare a read-only
maxLivesequal to3— the rules of the game never change — and print it. - Declare a variable
scorestarting at0, add10and then5to it with+=, and print the total.
The exact expected output is:
maxLives = 3
score = 15
Hint
Use println(s"maxLives = $maxLives")-style interpolated strings: the s prefix lets $name drop a value into the middle of the text. And if the compiler says Reassignment to val, the name you are changing was declared with val — the one value that must change here is score, so declare it with var.
Free plan: 30 tutor messages. Premium is unlimited.