Basics · Lesson 1.11

Const

Source
Name a value the compiler works out before the program runs, and see where const differs from let.
You'll need: Variable, Literal, Console

let names a value while the program runs. const names one while the program is being compiled: the compiler works the value out once, and every use of the name is replaced by the answer. Nothing is left to compute at run time.

Declaring constants

A constant is declared like a variable, with const, and its type is inferred the same way — or written out when the inferred int is not the type wanted:

const Limit = 100;
const Greeting = "Hello from a constant";
const MaxPlayers: uint8 = 4;
const Pi: float32 = 3.1415927f32;

Constants are named in PascalCase, like types, so they stand out from variables.

Constants built from constants

A constant may be built from other constants, because all of them are known while compiling. Doubled costs nothing when the program runs — the compiler has already stored 200:

const Doubled = Limit * 2;
const Half = Limit / 2;

Where a constant can live

Constants can be declared outside any function, at the top of the file, where the whole file can use them. They can also live inside a function, where only that function sees them:

const SecondsPerHour = 60 * 60;

In an expression, a constant is used like any other value — here beside a run-time let:

let hours = 3;
let seconds = hours * SecondsPerHour;

const or let?

flowchart TD
    q{"Is the value known<br/>before the program runs?"}
    q -- "yes: a fixed number, a limit,<br/>a name, a conversion factor" --> c["const — computed once by the compiler,<br/>usable anywhere in the file"]
    q -- "no: it depends on input,<br/>a calculation, a variable" --> l["let — computed while the program runs"]

Because a constant's value is known before the program runs, it can go where the compiler itself needs a value: the length of an array (bool[Limit], in Part 5) and the condition of a compile-time when.

The program

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

Src/Main.rux
// `let` names a value while the program runs. `const` names one while the program is being
// compiled: the compiler works the value out once, and every use of the name is replaced by the
// answer. Nothing is left to compute at run time.
//
// That buys two things. A constant can be declared outside any function, at the top of the file,
// where all of the file can use it. And because its value is known before the program runs, it
// can go where the compiler itself needs a value: the length of an array, as in `bool[Limit]`,
// once arrays arrive in Part 5, and the condition of a `when`, which comes later still.
import Io::PrintLine;

// The type is inferred, exactly as with `let`.
const Limit = 100;
const Greeting = "Hello from a constant";

// Or written out, when the inferred `int` is not the type wanted.
const MaxPlayers: uint8 = 4;
const Pi: float32 = 3.1415927f32;

// A constant may be built from other constants, because all of them are known while compiling.
// `Doubled` costs nothing when the program runs: the compiler has already stored 200.
const Doubled = Limit * 2;
const Half = Limit / 2;

func Main() -> int {
    PrintLine("Limit       {}", Limit);
    PrintLine("Greeting    {}", Greeting);
    PrintLine("MaxPlayers  {}", MaxPlayers);
    PrintLine("Pi          {}", Pi);
    PrintLine("Doubled     {}", Doubled);
    PrintLine("Half        {}", Half);

    // A constant can also live inside a function, where only that function sees it.
    const SecondsPerHour = 60 * 60;

    // In an expression a constant is used like any other value, here beside a run-time `let`.
    let hours = 3;
    let seconds = hours * SecondsPerHour;
    PrintLine("3 hours     {} seconds", seconds);

    // Build a constant only from literals and other constants. A `let` or a `var` gets its
    // value while the program runs, which is too late for a `const`:
    //
    //     let hours = 3;
    //     const Seconds = hours * 3600;
    //         error: 'hours' is not a compile-time constant
    //         help: declare 'Seconds' with 'let' to compute it at run time
    //
    // Constants are named in PascalCase, like types, so they stand out from variables.
    return 0;
}

Run it

cd Examples/Basics/Const
rux run
Limit       100
Greeting    Hello from a constant
MaxPlayers  4
Pi          3.1415927
Doubled     200
Half        50
3 hours     10800 seconds

Common mistakes

Building a constant from a variable.
A let or var gets its value while the program runs, which is too late for a const. let hours = 3; const Seconds = hours * 3600; fails with error: 'hours' is not a compile-time constant, and the compiler suggests declaring Seconds with let instead.

Try it yourself

  1. Add const MinutesPerDay = 24 * 60; at the top of the file and print it.
  2. Make a const TaxRate = 0.2; and use it with a let price = 50.0; to print the tax.
  3. Try building a const from a let and read the error.

Learn more

  • Constants in the Rux Reference
  • When — choosing code at compile time