Vector
import kedr/f32
type Vector3 = struct
x : f32
y : f32
z : f32
Numeric type names are composed of a letter and a size, f32 is a 32-bit floating point number.
Structure can have fields and methods, but not a constructor or destructor. Vector3 contains three fields of type f32.
let vector = Vector3 1 3 7
vector.z = 8 # fails
vector is an immutable binding private to a file.
The values 1, 3 and 7 are positionally assigned to the x, y and z fields.
Single-line comments start with the number sign.
Mutability of a struct propagates to its fields. Binding vector is immutable, which makes vector.z immutable as well.
let mut vector = Vector3 1 3 7
vector.z = 8 # works
Binding is made mutable with the mut keyword.
type Vector3
def norm =
let sum = x * x + y * y + z * z
sum.sqrt
let length = vector.norm
There is no equals sign after the type name, hence it is an extension of the existing Vector3 type.
type Vector3
def norm = x * x + y * y + z * z |> sqrt
Binding sum can be eliminated using the pipe forward operator. Everything to the left of |> is computed first, and then sqrt method is invoked on the result.
type Vector3
def normalize @mut =
let l = norm
x = x / l
y /= l
z /= l
@mut is an attribute. It forces the method to be called only on the mutable instances of a struct and allows modification of its fields.
type Vector3
def with_x (x : f32) = Vector3 x y z
# fails
The x parameter shadows the x field, causing a compilation error.
type Vector3
def with_x self (x : f32) = Vector3 x self.y self.z
# works
Now explicit self is required to access fields and methods of the type.
type Vector3<T> = struct
x : T
y : T
z : T
We make Vector3 generic by replacing field types with the T parameter.
type Vector3<T>
def dot (rhs : Vector3<T>) = x * rhs.x + y * rhs.y + z * rhs.z
# fails
Type T does not support multiplication operator, constraint is required.
type Vector3<T> where T : Number
def dot (rhs : Vector3<T>) = x * rhs.x + y * rhs.y + z * rhs.z
# works
Number is a class with operations common to all numeric types.