Vector

import kedr/f32

type Vector3 = struct
    x : f32
    y : f32
    z : f32

Имена числовых типов состоят из буквы и размера в битах. f означает число с плавающей точкой, i — целое число со знаком, u — целое число без знака.

Модификатор struct определяет тип, передаваемый по значению. Он может содержать поля и методы, но не конструктор или деструктор. Vector3 имеет три поля типа f32.

let vector = Vector3 1 3 7

vector.z = 8 # ошибка

Ключевое слово let задаёт неизменяемую привязку, видимую только внутри файла.

Значения 1, 3 и 7 присваиваются полям x, y и z, исходя из порядка, в котором указаны поля и значения.

Символ решётки начинает однострочный комментарий.

Изменяемость структуры передаётся её полям. Привязка vector неизменяема, поэтому vector.z также изменить нельзя.

let mut vector = Vector3 1 3 7

vector.z = 8 # работает

let привязку можно сделать изменяемой с помощью ключевого слова mut.

type Vector3
    def norm = 
        let sum = x * x + y * y + z * z
        sum.sqrt
        
let length = vector.norm        

После имени типа нет знака равенства, значит это расширение уже существующего типа Vector3.

type Vector3
    def norm = x * x + y * y + z * z |> sqrt

Привязку sum можно устранить с помощью оператора конвейера. Здесь он вызывает метод sqrt на результате вычисления левой части.

type Vector3
    def normalize @mut =
        let l = norm
        x = x / l
        y /= l
        z /= l        

@mut это атрибут. Он позволяет изменять поля структуры внутри метода. Метод при этом может быть вызван только для изменяемых структур.

type Vector3
    def with_x (x : f32) = Vector3 x y z
    
# ошибка

Параметр x затеняет поле x, что приводит к ошибке компиляции.

type Vector3
    def with_x self (x : f32) = Vector3 x self.y self.z
    
# работает

Теперь для доступа к полям и методам self нужно указывать явно.

type Vector3<T> = struct
    x : T
    y : T
    z : T

Мы сделали Vector3 обобщённым, заменив типы полей параметром T.

type Vector3<T>
    def dot (rhs : Vector3<T>) = x * rhs.x + y * rhs.y + z * rhs.z
    
# ошибка

Тип T не поддерживает оператор умножения, пока мы не ограничим его соответствующим образом.

type Vector3<T> where T : Number
    def dot (rhs : Vector3<T>) = x * rhs.x + y * rhs.y + z * rhs.z

# работает

Number это класс, содержащий общие для всех чисел операции.