Pocket Studio Academy
HomePart 11.1

val and var — names for things

Free lesson9 min read·4 questions

Programs are mostly about giving names to values. Kotlin makes you say, every single time, whether that name is allowed to change — and that one small decision prevents a surprising number of bugs.

A number with no name is a mystery

Here is a line of that works perfectly and is completely useless:

kotlin
println(9.81)

It prints 9.81. But what is 9.81? Gravity? A price? A version number? Nobody can tell — not another person, and not you in three weeks.

Now here is the same number with a name on it:

kotlin
1val gravity = 9.81
2println(gravity)

Identical behaviour. Wildly different meaning. That is what names are for: they carry the why, which the number alone cannot.

Almost everything you write from now on starts by naming something. Kotlin gives you exactly two ways to do it, and choosing between them is the first real decision you will make as a programmer.

Think of it like this

Picture the fridge in a kitchen.

On the door is a whiteboard. Somebody wrote MILK: 2 LEFT. Tomorrow someone rubs out the 2 and writes a 1. The word MILK stays put; the number beside it changes as often as you like.

Inside the fridge is a tin with TOMATOES printed on the label. You cannot rub that out. That tin is tomatoes. It was tomatoes when it arrived, it will be tomatoes when it leaves.

Kotlin has both. is the whiteboard — a name whose you can rewrite. is the printed label — a name set once and never changed.

The interesting part is that a real kitchen has far more printed labels than whiteboards. Code is the same, and for the same reason: things that never change are things you never have to double-check.

Making a name that never changes

kotlin
val name = "Ada"

Read it out loud as three pieces:

  • val — "I am creating a name that will not change."
  • name — the name itself. You choose this.
  • = "Ada" — the value that goes with it, right now and forever.

The = here is not the equals sign from maths. It does not mean "these two are the same". It means put the thing on the right into the name on the left. Programmers call this assignment, and reading it as "gets" helps: name gets "Ada".

Try to change it later and the stops you before the app is ever built:

kotlin
1val name = "Ada"
2name = "Grace"   // the compiler refuses this

The error is Val cannot be reassigned. That is not Kotlin being awkward. It is Kotlin holding you to a promise you made one line earlier.

Making a name that can change

Some things genuinely have to move. A score goes up. A countdown goes down. For those, use :

kotlin
1var score = 0
2score = 10
3score = score + 5

That last line is worth staring at, because it is nonsense as maths and perfect as code. It says: take whatever is currently in score, add 5 to it, and put the answer back into score. The right-hand side is worked out first, then stored. score ends up as 15.

Which one should you use?

Use val. Every time. Change to var only when the code will not work otherwise.

This sounds like a style preference. It is not — it is a debugging strategy. When you see a val, you know its value once and you know it forever; you can stop thinking about it. When you see a var, you have to ask "does anything change this between here and there?" — and somewhere in that question live most of the bugs you will ever write.

Names that never change are called . Prefer them.

Tip

Kotlin actually nudges you. If you declare something var and never change it, Pocket Studio underlines it with the message Variable is never modified and can be declared as 'val'. Take the hint.

Rules for names

A name — programmers say , even for a val — has to follow a few rules:

  • Letters, digits and underscores only. No spaces.
  • It cannot start with a digit. score2 is fine, 2score is not.
  • It cannot be a Kotlin keyword. You cannot call something val, fun or if.
  • Capitals matter. score and Score are two different names.

And one convention that is not a rule but might as well be: Kotlin names start with a small letter, and every following word starts with a capital. topScore, playerName, isGameOver. This is called camelCase, because of the humps.

Above all: make names say what the thing is. n costs you nothing to type and costs you a minute every time you read it. remainingLives costs a second and saves the minute.

Your first program, line by line

Run that and you get two lines: Ada, then 10.

9:41▲ ▮
Lab.kt
▶ Run
fun main() {
  val name = "Ada"
  var score = 0
  score = score + 10
  println(name)
  println(score)
}
OUTPUT
Ada
10
Process finished with exit code 0

The Output panel after pressing Run.

Try it in Pocket Studio

You are going to build a scratchpad you will keep using for the whole of Part 1. Set it up once now.

  1. Open Pocket Studio and tap the Projects tab.
  2. Tap New, then choose Kotlin file (some versions label this Scratch).
  3. Name it KotlinLab and tap Create. The Editor tab opens with an empty Lab.kt.
  4. Type in the six-line program from the walkthrough above, exactly as it is written. Watch the brackets — every { needs its }. Use the Copy button on the code block if you are reading this on the same phone.
  5. Tap the Run triangle at the top of the editor.
  6. Look at the Output panel at the bottom. You should see two lines: Ada, then 10.
  7. Now break it on purpose. Directly under the val name = "Ada" line, add name = "Grace" and press Run again. Read the error. That is Kotlin holding you to a promise you made one line earlier.
  8. Leave that new line where it is and change val name to var name. Press Run once more. It builds, and the first line of output is now Grace. You have just made, by hand, the choice this whole lesson is about.
  9. Keep this project. Every lesson in Part 1 reuses Lab.kt.
Note

If your version of Pocket Studio offers no plain Kotlin file option, use an Android project instead: put the same lines inside MainActivity's onCreate, press Run, and read the output in Logcat rather than the Output panel. Everything in Part 1 works either way.

Error Doctor5 common errors
e: Val cannot be reassigned
MeansYou declared this name with val, then tried to give it a different value later. val means set once.
FixDecide which you actually want. If the value genuinely needs to change, go back to the declaration and change val to var. If it should not change, the error has just found a real bug — remove the line that reassigns it.
e: Unresolved reference: nmae
MeansKotlin cannot find anything with that name. In a lesson this short it is always a typo, or a name used before it was declared.
FixCheck the spelling character by character, including capitals — Score and score are different names. Also check the declaration sits above the line that uses it.
e: Variable 'score' must be initialized
MeansYou wrote var score with no = something. Kotlin will not let you read a name that has never been given a value.
FixGive it a starting value on the same line: var score = 0.
e: Expecting a top level declaration
MeansThere is code sitting outside any function — usually because a closing } landed in the wrong place and ended main early.
FixCount your brackets. Every { needs exactly one }. Pocket Studio highlights the matching bracket when you tap next to one.
e: Unresolved reference: printn
MeansKotlin has no function by that name.
FixThe function is println — print, then the letters l and n. It is short for "print line".
Recap
  • A name carries meaning that a bare cannot. Name things after what they mean.
  • sets a name once, for good. lets you change it later.
  • = means "gets", not "is equal to". The right-hand side is worked out first, then stored.
  • Reach for val by default and switch to var only when the code forces you. Fewer moving parts means fewer bugs.
  • Names use camelCase, cannot contain spaces, cannot start with a digit, and are case-sensitive.
  • Next: every value has a kind — whole number, decimal, text, yes/no. That is called its , and knowing it is how Kotlin catches your mistakes before your users do.