Your Own Capabilities: Declaring a capability
● Intermediate3 min
A capability names methods. Every method can be refused, so its error type must have a Denied(reason: String) case.
Called where nothing implements it, a capability is refused: it never fails silently, and never does something unexpected:
type PayError = Declined | Denied(reason: String)
capability Payments {
fn refund(order: Int, amount: Int) ! PayError
}
fn main() {
Payments.refund(7, 499) catch e => print("refused: {e}")
}The program ran and printed:
kavach run own-declare.kav
refused: Denied(reason: "no implementation of Payments")A limit, a person who says no, or a missing implementation can refuse any call. So the compiler insists on the Denied case, and the refusal is visible to anyone reading the code:
type PayError = Declined | Unavailable
capability Payments {
fn refund(order: Int, amount: Int) ! PayError
}The compiler refused the program:
kavach run own-no-denied.kav
error: `Payments.refund` can be refused, so its error type needs a variant `Denied(reason: String)` (spec 8.2)