Skip to content
Kavachकवच

Capabilities: Pure functions

● Intermediate2 min

A function without uses is pure: it can't affect the outside world at all.

pub fn price_with_tax(price: Decimal) -> Decimal {
    debug("working out tax on {price}")
    price * 1.18
}

fn main() {
    print(price_with_tax(100.00))
}

The program ran and printed:

kavach run cap-pure.kav

118.0000
cap-pure.kav: Kavach code, then what running it prints
  • A pure function gives the same result for the same arguments, every time. That makes it easy to test.
  • debug() needs no capability: it writes to the error output, and release builds leave it out.
  • Logging with std.log needs none either: the program's owner decides where log events go.

Functions given as values

A function value carries the rights of the code that made it. Naming a function as a value, or writing a lambda, needs what that function uses, as calling it would. Calling a function value needs nothing more:

fn twice(f: fn(Int) -> Int, n: Int) -> Int {
    f(f(n))
}

pub fn shout(n: Int) -> Int uses Console {
    const loud = x => {
        print("got {x}")
        x + 1
    }
    twice(loud, n)
}

fn main() {
    print(shout(1))
}

The program ran and printed:

kavach run cap-fn-values.kav

got 1got 23
cap-fn-values.kav: Kavach code, then what running it prints
  • twice stays pure: it only calls what it is given.
  • shout writes the lambda that prints, so shout needs Console.
  • So a library can call the functions it is given, as a web framework calls its handlers, without being granted what they use.

A function type can set a limit with uses: a function value may then use only what the type lists.

use std.net

fn fetch_count(n: Int) -> Int uses Net {
    n
}

fn run_quietly(f: fn(Int) -> Int uses Console, n: Int) -> Int {
    f(n)
}

fn main() {
    print(run_quietly(fetch_count, 1))
}

The compiler refused the program:

kavach run cap-fn-type.kav

error: `fetch_count` uses Net, but the function type it is given as allows only Console (spec 3.4)
cap-fn-type.kav: Kavach code, then what running it prints