What a constant is
A constant is a name whose value is set once and then never changes while the program runs. In Kotlin you create one by declaring the variable with val instead of var:
val ourName = "AlgoCademy"
println(ourName) // AlgoCademy
Reading the value is no different from reading any variable. The only restriction is on writing: a name declared with val can't be reassigned.
In Kotlin's own vocabulary, val declares a read-only name. People often call it a constant in everyday speech, as this lesson does. The distinction matters in one place, covered below.
What happens when you try to change it
val ourName = "AlgoCademy"
ourName = "Andy"
The compiler refuses to build the program:
error: 'val' cannot be reassigned.
ourName = "Andy"
^^^^^^^
The error comes before the program runs, so there is no moment where the wrong value is used. Compound forms such as ourName += "x" are reassignments too and fail the same way.
Why limit yourself?
A constant looks like a variable with a handicap, so why use it? Because the handicap is a guarantee. Imagine a large project where hundreds of people edit millions of lines. Early on, someone wrote:
val companyName = "Apple"
val foundingDate = "April 1st, 1976"
val founderName = "Steve Jobs"
Years later, a careless change somewhere else tries companyName = "Microsoft". With val, that line doesn't compile, and the mistake is found immediately and at the exact line. With var, it would silently change what every other part of the program reads.
When you read code, val also tells you something: you don't have to scan the rest of the function to see whether the value changes. It doesn't. That is why Kotlin programmers declare names with val by default and switch to var only when a value must change.
A val does not have to be known when you write the code. Its value may be computed when the program runs, and it is still assigned only once:
val price = 20
val tax = price * 5 / 100
val total = price + tax
println(total) // 21
Each of the three names receives its value exactly once. None of them can be changed afterwards, but each can be read as often as you like.
The exercise
The starter code reassigns a constant:
val pi = 3.14
pi = 5
println(pi)
The compiler's first complaint is 'val' cannot be reassigned, pointing at pi = 5. It may add more messages about the line, for example that the integer 5 doesn't fit a Double. Those all come from the same line. The task asks for the program to print 3.14, and the lesson gives the fix: delete the line that reassigns pi. The declaration and the println stay unchanged:
val pi = 3.14
println(pi)
It prints 3.14. The other possible fix, changing val to var, would make the assignment legal but print 5 and defeat the point of a constant. When the compiler rejects a reassignment, first ask whether the reassignment was meant to happen.
What val does not mean
- It fixes the name, not the object. A
valholding a mutable list can't be pointed at another list, but the list can still be changed:val list = mutableListOf(1, 2)followed bylist.add(3)is fine and gives[1, 2, 3]. A plain number or string can't be modified, so for thosevalfixes the value completely. - A delayed first assignment is allowed. Inside a function,
val x: Intfollowed later byx = 4works once, as long as the compiler can see it happens once. A second assignment is an error. const valis the compile-time kind. A top-levelconst val MAX_USERS = 100is substituted at compile time and may only hold a number, a string or another basic type. It can't go inside a function: the compiler saysmodifier 'const' is not applicable to 'local variable'. Constants written this way are conventionally named in capital letters.
Key takeaways
valcreates a name that can be assigned only once.- Reassigning it is a compile error:
'val' cannot be reassigned. - The restriction is useful: it guards against accidental changes and makes code easier to read.
- Use
valby default andvarwhen the value must change.