Memory management

let vector @owner = Vector3@ref 1 3 8

Structure is initialized on the heap if @ref suffix is added to the type name. Binding vector is of type mut ref Vector3, which can also be written as MutRef<Vector3>. References of this kind in essence are pointers without arithmetics.

The @owner attribute frees memory before binding goes out of scope, @[owner function] — before containing function returns.

Objects

type App =
    val name : String

let app = App "Editor"

Automatic reference counting is applied to objects by default.

let app = App@mrc "Editor"

kd/retain app
kd/release app

The @mrc modifier switches object to manual reference counting, which is conducted through the kd/retain and kd/release functions.

let app = App@ref "Editor"

kd/free app

Here app refers to an object on the heap. Must be freed manually with the kd/free function.

let app = App@mem "Editor"
let app_ref = app
let app_copy = app@copy

The app binding of type mem App contains object's memory. Accessing app returns a reference of type App. Copying requires the @copy modifier.

def create = App@mem "Editor"

let app = create@arc

Although the create function returns mem App, the app binding points to a heap-allocated, reference-counted App object.

type App @mem =
    val name : String

let app = App@ref "Editor"

With @mem being the default option, reference counting can no longer be enabled for App, while @ref is still available.

Unified code for copy and move semantics

type List<mem T> =
    var size : u32 = 0
    let mut array = Array<mem T> 0

    fun get (i : u32) = array[i]

    def index_of (x : T) =
        for i = 0 until size do
            if array[i] == x then return i

        fail "no such item"

    def add (x : mem T) =
        if size == array.size then
            set_array_size (if size == 0 then 4 else size * 2)

        kd/retain x
        array[size] = x@move
        size += 1

    def remove_at (index : u32) =
        kd/clear array[index]

        if size > 1 then
            for i = index to size - 2 do
                array[i] = array[i + 1]@move

        size -= 1

    def remove (x : T) =
        let index = index_of x
        remove_at index

While mem T represents object's memory for reference types, for value types it equals the type itself, meaning mem T == T, with the @copy and @move operations doing nothing.

The kd/clear function destructs the mem types and decrements the counter for reference-counted objects.