val and var — names for things
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:
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:
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.
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
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:
1val name = "Ada"
2name = "Grace" // the compiler refuses thisThe 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 :
1var score = 0
2score = 10
3score = score + 5That 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.
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.
score2is fine,2scoreis not. - It cannot be a Kotlin keyword. You cannot call something
val,funorif. - Capitals matter.
scoreandScoreare 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.
The Output panel after pressing Run.
You are going to build a scratchpad you will keep using for the whole of Part 1. Set it up once now.
- Open Pocket Studio and tap the Projects tab.
- Tap New, then choose Kotlin file (some versions label this Scratch).
- Name it
KotlinLaband tap Create. The Editor tab opens with an emptyLab.kt. - 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. - Tap the Run triangle at the top of the editor.
- Look at the Output panel at the bottom. You should see two lines:
Ada, then10. - Now break it on purpose. Directly under the
val name = "Ada"line, addname = "Grace"and press Run again. Read the error. That is Kotlin holding you to a promise you made one line earlier. - Leave that new line where it is and change
val nametovar name. Press Run once more. It builds, and the first line of output is nowGrace. You have just made, by hand, the choice this whole lesson is about. - Keep this project. Every lesson in Part 1 reuses
Lab.kt.
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.
val, then tried to give it a different value later. val means set once.val to var. If it should not change, the error has just found a real bug — remove the line that reassigns it.Score and score are different names. Also check the declaration sits above the line that uses it.var score with no = something. Kotlin will not let you read a name that has never been given a value.var score = 0.} landed in the wrong place and ended main early.{ needs exactly one }. Pocket Studio highlights the matching bracket when you tap next to one.println — print, then the letters l and n. It is short for "print line".- 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
valby default and switch tovaronly 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.