So far every value in our programs has been typed straight into a jongyeytha. Real programs need to remember things: a score, a name, how many lives are left. For that we use variables.
What is a variable?
A variable is a named box that holds a value. You make one with akthe (meaning let, as in "let there be a box called..."):
bongSlanhOun "boxes";
akthe name = "Sokha";
akthe age = 11;
jongyeytha name;
jongyeytha age;
jongyeytha name + " is " + age + " years old"; Sokha
11
Sokha is 11 years old Read akthe age = 11; as "make a box called age and put 11 in it". After that, whenever you write age, steav2 looks inside the box and uses whatever it finds.
A few rules for names:
- Use letters, digits and underscores (
_), and don't start with a digit:score,player2,high_score. - No spaces. People often write
highScoreorhigh_scoreinstead. - Capital letters matter:
Ageandageare different boxes. - You can't use a keyword like
beroraktheas a name.
Changing a variable
Once a box exists, you can put a new value in it with = (no akthe this time, the box is already there):
bongSlanhOun "change";
akthe lives = 3;
jongyeytha lives;
lives = 2;
jongyeytha lives;
lives = lives - 1;
jongyeytha lives; 3
2
1 That last one, lives = lives - 1;, looks strange if you read = as "equals". In programming, = means "becomes": work out the right side first (lives - 1 is 2 - 1, so 1), then put the answer in the box on the left.
Changing a variable by a little bit is so common that there are shortcuts:
| shortcut | same as |
|---|---|
x += 5; |
x = x + 5; |
x -= 5; |
x = x - 5; |
x *= 5; |
x = x * 5; |
x /= 5; |
x = x / 5; |
bongSlanhOun "shortcuts";
akthe coins = 10;
coins += 5;
coins *= 2;
jongyeytha "coins: " + coins;
akthe word = "steav";
word += "2";
jongyeytha word; coins: 30
steav2 Types
Every value in steav2 has a type: what kind of value it is. You've already met a few:
| type | what it holds | examples |
|---|---|---|
Lek |
a number ("lek" means number) | 11, 3.5, -2 |
Ahsor |
text | "hello" |
Boolean |
yes or no | ok, ort |
When you write akthe age = 11;, steav2 looks at the 11, sees a number, and decides the box age is a number box, forever. This is called type inference: steav2 figures out the type so you don't have to say it.
And "forever" really means forever. A number box can't suddenly hold text:
bongSlanhOun "wrong box";
akthe age = 11;
age = "eleven"; [line 3] Error at '"eleven"': expected LekThom but got Ahsor This is steav2 being statically typed: it checks all the types before your program runs, and refuses to start if something doesn't fit. It might feel strict, but it catches lots of mistakes early. (Don't worry about the name LekThom in the message, we'll get to it in a second.)
Saying the type yourself
You can also write the type explicitly, with a colon after the name:
bongSlanhOun "explicit";
akthe city: Ahsor = "Phnom Penh";
akthe sunny: Boolean = ok;
akthe temperature: Lek = 34;
jongyeytha city + ", sunny: " + sunny + ", " + temperature + " degrees"; Phnom Penh, sunny: ok, 34 degrees Most of the time inference is enough. Writing the type is useful when you want a specific kind of number, which brings us to...
Whole numbers and decimal numbers
steav2 has two main kinds of number:
LekKut: whole numbers only ("integers"), like3,0,-12.LekThom: numbers that can have a decimal point, like3.5or0.25.
Lek is just another name for LekThom, and it's what you get when you don't say otherwise. To get a whole-number box, say so:
bongSlanhOun "two kinds";
akthe cookies: LekKut = 7;
akthe friends: LekKut = 2;
jongyeytha cookies / friends;
akthe pizza = 7;
jongyeytha pizza / 2; 3
3.5 Dividing whole numbers gives a whole number: 7 cookies shared between 2 friends is 3 each (the leftover one is thrown away, sadly). Pizza is a Lek, so it can be cut into halves.
Numbers never mix
Here's a steav2 rule that surprises people: you can't mix a LekKut and a LekThom in a calculation.
bongSlanhOun "mixing";
akthe apples: LekKut = 5;
akthe weight = 1.5;
jongyeytha apples * weight; [line 4] Error at '*': no operator '*' for LekKut and LekThom (numbers never mix implicitly, convert one with LekThom(x) / LekKut(x)) The error even tells you the fix: convert one of them, by using the type's name like a machine you feed a value into:
LekThom(x)turnsxinto a decimal number.LekKut(x)turnsxinto a whole number, chopping off anything after the decimal point.
bongSlanhOun "converting";
akthe apples: LekKut = 5;
akthe weight = 1.5;
jongyeytha LekThom(apples) * weight;
jongyeytha apples * LekKut(weight);
jongyeytha LekKut(2.99); 7.5
5
2 Notice LekKut(2.99) is 2, not 3: it chops, it doesn't round.
Your turn
- Make a variable
scorethat starts at0. Add10to it three times using+=, then printScore: 30. Hint:score += 10; - Make a
LekKutvariable holding17and print what you get when you divide it by5. Then do it again as aLekThom. Hint:LekThom(x) / 5 - Swap two variables: start with
akthe a = 1;andakthe b = 2;, and end withaholding2andbholding1. Hint: you'll need a third box to hold one value for a moment.
Solution for exercise 3:
bongSlanhOun "swap";
akthe a = 1;
akthe b = 2;
akthe spare = a;
a = b;
b = spare;
jongyeytha "a is " + a + ", b is " + b; a is 2, b is 1