Type system
Programmer can define types of the following kinds:
- object
- structure
- union
- class
- named tuple
- symbol
- sum
- flags
Object
type Buffer =
val type : BufferType
var object : VkBuffer
var size : u32
val offset : u64
val usage : BufferUsageFlags
The Buffer type has five fields, which are also constructor parameters.
type StorageBuffer =
inherit Buffer type = BufferType/Storage
offset = 0
val device : VkDevice
val memory : VkMemory
def discard =
vk/destroy_buffer device object null
vk/free_memory device memory null
When inheriting, we passed in values for the type and offset fields, the three remaining fields become constructor parameters for StorageBuffer, joined by device and memory.
type AttachmentFormat @data =
val format : VkFormat
val samples : SampleCountFlags
val usage : ImageUsageFlags
Equality and hash of objects with @data attribute are derived from fields.
type App @move =
val name : String
let app = App "Editor"
let app_ref = app
let app_copy = app@copy
The app binding of type mov App contains object's memory. Accessing app returns a reference of type App. Copying requires the @copy modifier.
type Slice<T> @byval =
val ptr : Ptr<T>
val size : u32
Objects with @byval attribute are passed by value.
Multiple inheritance is supported, but each type can be inherited only once.
Structure
type ClearDepthStencilValue = struct
depth : f32
stencil : u32
Can inherit other structures.
Union
type ClearValue = union
color : ClearColorValue
depth_stencil : ClearDepthStencilValue
All fields point to the same memory address. Value of one field needs to be provided on initialization.
Class
type Compare = class
def compare (other : Self) : Ordering
def (>) (rhs : Self) =
let result = compare rhs
result == Ordering/Greater
...
type TextPos = struct
line : u32
char : u32
def compare (other : TextPos) = when
line < other.line -> Ordering/Less
line > other.line -> Ordering/Greater
char < other.char -> Ordering/Less
char > other.char -> Ordering/Greater
else -> Ordering/Equal
is Compare
Type can be declared as belonging to a class if it corresponds to all of the class's requirements.
Named tuple
type CString = ptr CChar
Most of the time has only one element, as otherwise a structure might be a better choice.
Symbol
Also known as a unit type. In essence, it is a named tuple with zero elements.
type None = symbol
Is used in sum types.
Sum
Differs from union by containing information about an active field.
type BufferType =
| Vertex
| Index
| Storage
| Image
| Uniform
Enumeration is a sum of unit types.
type Target =
| Buffer VkBuffer
| Image image : VkImage
width : u32
height : u32
Target/Buffer is a named tuple, Target/Image is a structure.
type Option<T> =
| None
| Some T
type Result<T, E> =
| Ok T
| Error E
Option allows for representing an absence of a value. Function returns Result to pass an error message in case of a failure.
type Metal @open = enum
Iron | Copper | Nickel
type Metal
Silver | Gold
type Platinum = symbol
inherit Metal
Fields can be added to open sum types at any moment. Modifier enum restricts types of fields to symbols.
Flags
type QueueFlags = flags
| Graphics
| Compute
| Transfer
| SparseBinding
| Protected
let queue_flags = QueueFlags/Graphics | QueueFlags/Transfer
assert queue_flags.contains QueueFlags/Graphics