kota's memex

When declaring a variable, you must provide the initial value with an initializer, such as a constant like "42" or an arbitrary expression with a function call.

Constants

Constants are declared with the const keyword. They may not be modified after initialized.

Shadowing

Although you cannot "modify" a const, you can re-bind it by creating another variable with the same name:

const source = os::open("main.ha")!;
const source = io::drain(source)!;
const source = strings::fromutf8(source);
const source = strings::split(source, "\n");

In this example source refers to an io::file, an []u8, a str, and a []str in that order. This is a useful pattern for building up a variable from a series of intermediate values of various types. This technique is more generally called "shadowing" the variable.

Mutable

Variables declared with let can be modified with the = operator.

let i: int = 1337, j: int = 42;
j = i;

Types

Most of the time when declaring a variable the type will be automatically assumed from the right-hand statement. In some cases however, it may be necessary or helpful to state the type explicitly:

export fn main() = void {
	// Numeric types can be declared explicitely:
	let
		a: int = 10,    // Signed integer
		b: uint = 10,   // Unsigned integer
		c: u8 = 10,     // Unsigned 8-bit integer
		d: f32 = 13.37; // 32-bit floating point number

	// Or inferred from a suffix:
	let
		a = 10i,        // Signed integer
		b = 10u,        // Unsigned integer
		c = 10u8,       // Unsigned 8-bit integer
		d = 13.37f32;   // 32-bit floating point number

	// Some other types:
	let
		a: str = "hi",              // String
		b: (int, int) = (42, 24),   // Tuple
		c: struct {
			x: int,
			y: int,
		} = struct {
			x: int = 10,
			y: int = 20,
		},                          // Struct
		d: [4]int = [1, 2, 3, 4],   // Array
		e: []int = [1, 2, 3, 4];    // Slice
};

user defined types

type index = size;
type offs = size;

export fn main() void = {
	let z: (index | offs) = 1337: offs;
	assert(z is offs);
}

The type keyword defines a new type. Even if two types share the same underlying representation, they are considered distinct types in a tagged union.