Let's begin with literals and variables, two basic building blocks for any expression. Along the way, additional concepts will be introduced, such as types, permissions, variable declarations, assignment, and scope.


A literal is a specific, unchangeable value. Each of these numbers is a literal:

1e6          // 1000000.0
-1_000_000   // underscores are ignored
0x1000       // Hexadecimal
1p10         // 1024. (power-of-two exponent)

Beyond numbers, other forms of literals will be introduced later, including:


Every value has a type it belongs to. Although we will cover types more thoroughly later, let's simply say for now that each type corresponds to a specific collection of allowed values. Thus, the Bool type only supports true and false as values. Integer types only support integer number values. Floating point types support floating point number values. ... and so on.

Each type also establishes what operations can be performed on values of that type. Thus, an integer type permits two integers to be added together, the result of which is another integer value.

For the next few pages, examples will only use Cone's built-in number types, which specify their bit-size as part of the type's name. Here they are:

Typed Number Literals

To explicitly specify the type for a numeric literal, append the type name right after the number:

65u8       // 8-bit unsigned integer
1f64       // 64-bit floating point number

If the type is omitted, the number is understood to be 32-bits. When the number explicitly includes a decimal point or exponent, it is treated as a floating point number (f32). Otherwise, it is considered to be a signed integer (i32).

3.14159    // f32 (because of the decimal point)
1e6        // f32 (because of the exponent)
1_000_000  // i32 (no decimal point or exponent)

Type name shortcuts are also supported:

1000u      // u32
1f         // f32
1d         // f64


A variable is a named container which holds a value of some specific type.

Variable declarations

Before a variable can be used, it must first be declared and initialized. This example explicitly does both:

imm height f32 = 1.86

Let's examine each part of this variable declaration statement:

When an initial value is specified, the type can usually be omitted. It will be inferred, as this example shows:

imm height = 1.86     // f32 type is inferred
imm width  = height   // its value is 1.86 and type is f32

Notice that the second statement makes use of the variable 'height' after it has been declared and initialized.

Delayed initialization

It is often preferable to initialize a variable as part of declaration. When that is not realistic, initialization may be performed later using an assignment:

imm height f32
// ... some statements here ...
height = 1.86         // Initialize height now

An assignment essentially copies the evaluated value of the expression to the right of the = into the value container specified to the left. In this case, the value container is a variable. Other sorts of containers are possible and will be described later. Any assignment is itself an expression, and may be used wherever expressions are allowed.

It is worth pointing out that any attempt to re-assign 'height' later to another value will trigger an error message:

height = 2.12         // **ERROR** since height is immutable and initialized

Mutable Variables

What if we need to change a variable's value after initialization? To allow that, use mut (instead of imm) on the declaration statement:

mut age = 23      // type is i32
// ... some statements here ...
age = 24          // alters age to hold 24 instead

mut and imm are called permissions. Cone supports a number of other permissions. These are discussed more fully on the Permissions page.

Note: If we had tried to re-assign age to 24.0, we would have gotten an error message. This is because age is declared to only hold integer values, and 24.0 is a floating point number. Type safety of variables requires that the expression's type be the same or coerceable.

Scope and Visibility

As we have seen, variables have a name, permission, type and value. They also have a scope and visibility. Scope and visibility restrict (isolate) where a variable may be referenced and used in a program.