Types

In Ki, a type is a union of representation and behavior. In plain terms, typically a type includes a struct and functions that deal with it, although types can be based on any other Ki data type (u8, dynarray, etc.).

A type's representation must either be an scalar, a sequence, a struct, or a constant.

Conceptually, a type in Ki is very similar to a class in object-oriented languages. The main difference is that Ki does not provide inheritance. Instead, programmers can add functionality to types using components.

An Example

struct Position {
    var x: int
    var y: int
    var z: int
}

struct Direction {
    var x: int
    var y: int
    var z: int
}

struct Vector {
    var direction: Direction
    var magnitude: int
}

struct Actor {
    var speed:     u8
    var health:    u8
    var strength:  u8
    var position:  Position
    var direction: Vector
}

struct Fireball {
    var strength:  uint
    var position:  Position
    var direction: Vector
}

component FireballShooter {
    :dependencies {
        var strength:  uint
        var speed:     uint
        var position:  Position
        var direction: Direction
    }

    fn shoot_fireball(): (Fireball) {
        return(Fireball(
            strength: self.strength * 2
            position: Position(
                self.position.x
                self.position.y
                self.position.z
            )
            direction: Vector(
                self.direction.x
                self.direction.y
                self.direction.z
                self.speed * 2
            )
        ))
    }
}

component Threatener {
    fn threaten() {
        echo("Grrrrr!")
    }
}

component ThreateningFireballShooter(FireballShooter, Threatener) {}

type Imp (Actor) {
    :defaults {
        speed:    50
        health:   30
        strength: 10
    }

    :components {
        ThreateningFireballShooter
    }

    fn threaten() {
        echo("I'm an imp!!")
    }
}

type Baron (Actor) {
    :defaults {
        speed:     50
        health:   300
        strength: 100
    }

    :components {
        ThreateningFireballShooter
    }

    fn threaten() {
        echo("I'm a baron!!")
    }

    fn shoot_fireball() {
        return(Fireball(
            strength: self.strength
            position: Position(
                self.position.x
                self.position.y
                self.position.z
            )
            direction: Vector(
                self.direction.x
                self.direction.y
                self.direction.z
                self.speed * 3
            )
        ))
    }
}

fn shoot_em_up(shooter: FireballShooter) {
    shooter.shoot_fireball()
}

fn main() {
    var imp: Imp()
    var baron: Baron()

    shoot_em_up(imp)
    shoot_em_up(baron)
}