Skip to content
Kavachकवच

Interfaces

Also known as: interface trait protocol abstract class polymorphism dynamic dispatch virtual method duck typing implements inheritance

● Intermediate5 minBefore this: Methods, GenericsSpec 2.8

An interface names methods a type promises to have. A type keeps the promise only when it says so.

interface Describe {
    fn describe(self) -> String
}

type User: Describe {
    name: String

    fn describe(self) -> String { "User {self.name}" }
}

type Rect {
    width: Int
    height: Int
}

extend Rect: Describe {
    fn describe(self) -> String { "Rect {self.width}x{self.height}" }
}

fn show<T: Describe>(item: T) -> String {
    item.describe()
}

fn main() {
    print(show(User(name: "Asha")))
    print(show(Rect(width: 2, height: 3)))
}

The program ran and printed:

kavach run interfaces.kav

User AshaRect 2x3
interfaces.kav: Kavach code, then what running it prints
  • type User: Describe promises a describe method; leaving it out is an error.
  • extend Rect: Describe adds the promise to a type declared elsewhere.
  • <T: Describe> accepts any type that keeps it.

A type that happens to have the method but never said so doesn't count, and the message says what to write:

interface Describe {
    fn describe(self) -> String
}

fn show<T: Describe>(item: T) -> String {
    item.describe()
}

fn main() {
    print(show("text"))
}

The compiler refused the program:

kavach run interfaces-say-so.kav

error: `String` does not implement `Describe`: write `extend String: Describe`
interfaces-say-so.kav: Kavach code, then what running it prints

A method that keeps the promise has the interface's types: its parameters, its value and its error, with Self read as the type and the interface's type arguments put in. Getter<String> promises a get that gives a String:

interface Getter<T> {
    fn get(self) -> T
}

type Name: Getter<String> {
    text: String

    fn get(self) -> Int {
        self.text.len()
    }
}

fn main() {
    const g: Getter<String> = Name(text: "Ada")
    print(g.get())
}

The compiler refused the program:

kavach run interfaces-same-types.kav

error: `Name.get` gives `Int`, and `Getter<String>.get` gives `String`: they must match
interfaces-same-types.kav: Kavach code, then what running it prints

Other languages call this a trait or a protocol.