🌱 Beginner's Guide lesson 3 of 12

Variables

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..."):

[ try-it.sts ]
bongSlanhOun "boxes";
akthe name = "Sokha";
akthe age = 11;
jongyeytha name;
jongyeytha age;
jongyeytha name + " is " + age + " years old";
[ what it prints ]
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 highScore or high_score instead.
  • Capital letters matter: Age and age are different boxes.
  • You can't use a keyword like ber or akthe as 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):

[ try-it.sts ]
bongSlanhOun "change";
akthe lives = 3;
jongyeytha lives;
lives = 2;
jongyeytha lives;
lives = lives - 1;
jongyeytha lives;
[ what it prints ]
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;
[ try-it.sts ]
bongSlanhOun "shortcuts";
akthe coins = 10;
coins += 5;
coins *= 2;
jongyeytha "coins: " + coins;
akthe word = "steav";
word += "2";
jongyeytha word;
[ what it prints ]
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:

[ x_x broken on purpose ]
bongSlanhOun "wrong box";
akthe age = 11;
age = "eleven";
[ what it prints ]
[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:

[ try-it.sts ]
bongSlanhOun "explicit";
akthe city: Ahsor = "Phnom Penh";
akthe sunny: Boolean = ok;
akthe temperature: Lek = 34;
jongyeytha city + ", sunny: " + sunny + ", " + temperature + " degrees";
[ what it prints ]
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"), like 3, 0, -12.
  • LekThom: numbers that can have a decimal point, like 3.5 or 0.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:

[ try-it.sts ]
bongSlanhOun "two kinds";
akthe cookies: LekKut = 7;
akthe friends: LekKut = 2;
jongyeytha cookies / friends;
akthe pizza = 7;
jongyeytha pizza / 2;
[ what it prints ]
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.

[ x_x broken on purpose ]
bongSlanhOun "mixing";
akthe apples: LekKut = 5;
akthe weight = 1.5;
jongyeytha apples * weight;
[ what it prints ]
[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) turns x into a decimal number.
  • LekKut(x) turns x into a whole number, chopping off anything after the decimal point.
[ try-it.sts ]
bongSlanhOun "converting";
akthe apples: LekKut = 5;
akthe weight = 1.5;
jongyeytha LekThom(apples) * weight;
jongyeytha apples * LekKut(weight);
jongyeytha LekKut(2.99);
[ what it prints ]
7.5
5
2

Notice LekKut(2.99) is 2, not 3: it chops, it doesn't round.

Your turn

  1. Make a variable score that starts at 0. Add 10 to it three times using +=, then print Score: 30. Hint: score += 10;
  2. Make a LekKut variable holding 17 and print what you get when you divide it by 5. Then do it again as a LekThom. Hint: LekThom(x) / 5
  3. Swap two variables: start with akthe a = 1; and akthe b = 2;, and end with a holding 2 and b holding 1. Hint: you'll need a third box to hold one value for a moment.

Solution for exercise 3:

[ try-it.sts ]
bongSlanhOun "swap";
akthe a = 1;
akthe b = 2;
akthe spare = a;
a = b;
b = spare;
jongyeytha "a is " + a + ", b is " + b;
[ what it prints ]
a is 2, b is 1
  • steav2♡ help
  • Y2K✓ ready
  • wasminside
  • .stsvalid

best viewed at 1024x768 ☆ made with ♡ ☆ the reference is steav2's own docs