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 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.