Cella Documentation 0.1.0-dev Home Source

Built-in types

These are the types the language provides. Everything else, such as records, enums, unions and traits, is declared in code. Sizes and alignments are in bytes, as sizeOf and alignOf report them on the 64-bit targets Cella builds for. The default is the value a variable of the type starts with when it's declared without one.

Summary

TypeSizeAlignmentDefault
i8, u8110
i16, u16220
i32, u32440
i64, u64880
i128, u12816160
isize, usize880
f32440.0
f64880.0
bool11false
char44the character with code 0
str168the empty string
cstr88null
ptr, ptr[T]88null
ptr[dyn[K]]168null
array[T, N]N times the size of Tthe alignment of Tevery element at its default
imm[T], mut[T]88none
imm[dyn[K]], mut[dyn[K]]168none
fun[...], ref fun[...]168none
ext fun[...]88none
fstr[K]248none
dyn[K]no fixed sizenone
neverno sizenone

sizeOf and alignOf take a type or a value and give a usize:

main: fun{	printf("%zu %zu\n", sizeOf(i128), alignOf(i128))	printf("%zu %zu\n", sizeOf(str), alignOf(str))	printf("%zu %zu\n", sizeOf(array[u16, 5]), alignOf(array[u16, 5]))	printf("%zu %zu\n", sizeOf(fun[i32 -> i32]), sizeOf(ext fun[i32 -> i32]))}
Output
16 16
16 8
10 2
16 8

Integers

TypeSmallest valueLargest value
i8-128127
i16-3276832767
i32-21474836482147483647
i64-2⁶³2⁶³ - 1
i128-2¹²⁷2¹²⁷ - 1
isize-2⁶³2⁶³ - 1
u80255
u16065535
u3204294967295
u6402⁶⁴ - 1
u12802¹²⁸ - 1
usize02⁶⁴ - 1

Signed integers use two's complement. isize and usize are as wide as a pointer; usize is the type of sizes and lengths. Numbers covers literals, arithmetic and overflow.

Floating-point numbers

f32 and f64 are IEEE 754 single and double precision numbers. Numbers covers them.

bool and char

bool is true or false, stored in one byte. char is a Unicode scalar value: a code point from 0 to 0x10FFFF, other than the surrogates 0xD800 to 0xDFFF. Bool, char and strings covers both.

str and cstr

A str is a run of UTF-8 bytes it doesn't own, with two read-only properties: data, a ptr[u8] to the first byte, and byteLength, a usize. A cstr is a single pointer to zero-terminated bytes, the form C functions take. A string literal becomes either, depending on the type it's given. Bool, char and strings covers both.

Pointers

ptr[T] points to a T, and ptr points to memory of no particular type. Nothing is checked through a pointer. A pointer to a trait object, ptr[dyn[K]], also carries what it needs to call the trait's members, so it's twice as large. Pointers covers them.

Arrays

array[T, N] holds N values of type T in a row, with no padding between them, so its size is N times the size of T. N is a usize known at compile time and can be 0. Arrays covers them.

Borrow types

imm[T] and mut[T] borrow a T that lives somewhere else, without and with the right to write it. A borrow is the size of a pointer, or twice that when it borrows a trait object. Borrows covers them.

Function types

fun[A, B -> R] holds a function that takes A and B and returns R. ref fun[...] can also hold closures, which borrow the variables they capture. ext fun[...] holds a C function pointer, the only kind C can call. Function values and closures covers them.

Trait objects

dyn[K] is a value of some type that implements the trait K, chosen at run time. Its size depends on that type, so it's used only behind a borrow or a pointer, never by value. Trait objects covers it.

Templates

fstr[K] holds the pieces of an interpolated string, with every value it fills in implementing the trait K. String templates covers it.

never

never is the result type of a function that doesn't return, such as one that always exits or loops forever. It's only allowed as a result type, and it has no size. Functions covers it.

Defaults

Writing a built-in type's name with empty parentheses gives its default, and a variable declared with var and no value starts at its default. For every type that has one, the default is all zero bytes:

main: fun{	printf("%d %.1f %d %u\n", i32(), f64(), bool(), u32(char()))	printf("%zu %d %d\n", str().byteLength, cstr() == null, ptr[u8]() == null)	var counts: array[i32, 3]	counts[1] += 5	printf("%d %d %d\n", counts[0], counts[1], counts[2])}
Output
0 0.0 0 0
0 1 1
0 5 0

Borrows, function values, templates and trait objects have no default, since all zero bytes isn't a valid value of them. A variable of one of these types must be given a value before it's used:

main: fun{	val handler: fun[i32 -> i32]	printf("%d\n", handler(1))Cannot use uninitialized values}

The types with a default meet the T: default constraint, and an array has one when its element type does. Generics covers constraints.

Copies and borrows

Every built-in type other than dyn[K] and never can be copied, so they meet T: copy. Borrow types, str, ref fun[...], fstr[K], borrowed trait objects and arrays of any of them hold borrows, so they don't meet T: noref:

keep[T: noref]: fun(value: T) -> T => value main: fun{	val word: str = "hi"	val kept = keep(word)'keep' requires 'T: noref''str' holds borrows}

cstr and pointers hold no borrows: nothing is checked through them. Borrows explains what holding a borrow means.

Built-in names

None of these type names can be used to declare anything else, as Keywords shows.