Basics · Lesson 1.4

Mutable

Source
Declare a variable that can change with var, and give it new values with =.
You'll need: Variable

A let variable keeps its first value for good. A var variable may change: after it is declared, = gives it a new value as often as the program needs. That is the whole difference — and the reason let is the default. Writing var tells the reader "watch this name, it moves".

Declaring and assigning

var is declared exactly like let, with the type inferred the same way. Assignment then replaces the value:

var score = 10;
score = 25;
score = score + 5;

The right-hand side is worked out first, so score = score + 5 reads the old value (25) and stores the new one (30).

Declaring now, assigning later

A var may be declared with a type and no value — as long as it gets one before anything reads it:

var bonus: int;
bonus = score * 2;

Assignment copies the value

saved takes the value level holds at that moment. Changing level afterwards does not reach back into it:

var level = 1;
let saved = level;
level = 2;
flowchart LR
    subgraph before ["after let saved = level;"]
        l1["level: 1"]
        s1["saved: 1"]
    end
    subgraph after ["after level = 2;"]
        l2["level: 2"]
        s2["saved: 1"]
    end
    before --> after

Each variable owns its own copy. Later, the Ownership part shows what happens with larger values, and how to move one instead of copying it.

let or var?

UseWhen
letThe value is set once — most variables.
varThe value has to change: a counter, a running total, a position.

Start with let. If the compiler tells you a variable needs to change, switch that one to var.

The program

The whole lesson is one package in the Examples repository. Its comments explain every step.

Src/Main.rux
// A `let` variable keeps its first value for good. A `var` variable may change: after it is
// declared, `=` gives it a new value, as often as the program needs. That is the whole difference,
// and it is why `let` is the default — `var` says "watch this name, it moves".
import Io::PrintLine;

func Main() -> int {
    // `var` is declared exactly like `let`, and its type is inferred the same way.
    var score = 10;
    PrintLine("score   {}", score);

    // Assignment replaces the value. The right-hand side is worked out first, so it may use the
    // variable's own old value.
    score = 25;
    PrintLine("score   {}", score);
    score = score + 5;
    PrintLine("score   {}", score);

    // A `var` may be declared with a type and no value, so long as it is given one before
    // anything reads it.
    var bonus: int;
    bonus = score * 2;
    PrintLine("bonus   {}", bonus);

    // Assigning copies the value. `saved` took the 1 that `level` held at that moment, and
    // changing `level` afterwards does not reach back into it.
    var level = 1;
    let saved = level;
    level = 2;
    PrintLine("level   {}", level);
    PrintLine("saved   {}", saved);

    // What may change is the value, never the type. `score` became an `int` when it was declared
    // and stays one, and a variable cannot be read before it has a value:
    //
    //     score = 2.5;
    //         error: cannot assign 'float64' to 'int'
    //
    //     var total: int;
    //     PrintLine("{}", total);
    //         error: variable 'total' is used before it is initialized
    return 0;
}

Run it

cd Examples/Basics/Mutable
rux run
score   10
score   25
score   30
bonus   60
level   2
saved   1

Common mistakes

Changing the type.
The value of a var may change; its type never does. score became an int when it was declared, so score = 2.5; fails with error: cannot assign 'float64' to 'int'.
Reading a variable before it has a value.
var total: int; followed by PrintLine("{}", total); fails with error: variable 'total' is used before it is initialized.

Try it yourself

  1. Start a var count = 0;, add 1 to it three times, and print it after each step.
  2. Declare var message: char8[..]; with no value, assign it on the next line, and print it.
  3. Change var score back to let score and read the message the compiler gives for the first assignment.

Learn more