Skip to content
Kavachकवच

Coming From Another Language

● Beginner3 min

Coming from Python, JavaScript, C++, Rust or Go: the same small program in each language and in Kavach, and what changes.

Pick the language you know best. Each page shows one program in that language and in Kavach, then a table of what changes, with a link to the page that teaches each part.

  • Python: classes, exceptions and None.
  • JavaScript: classes, null, === and async.
  • C++: pointers, exceptions and undefined behaviour.
  • Rust: borrowing, Result and Option.
  • Go: if err != nil, nil and goroutines.

What changes whichever language you know

In most languagesIn KavachLearn it
a class that inheritsno inheritance: a field, or an interfaceClasses and Inheritance
null, nil or Nonenone, only in a type that ends in ?Optionals
errors that pass up unseenthe error type in the signature, ! OrderError, and try at each call that passes it ontry
two names for one listvalues: b = a copies, so changing b leaves a as it wasValues, Not References
any function may touch files or the networka function says what it may touch: uses FsCapabilities

The program each page uses, in Kavach:

type Order {
    item: String
    qty: Int
    cents: Int

    fn cost(self) -> Int {
        self.qty * self.cents
    }
}

type OrderError = BadQty(item: String)

fn total(orders: [Order]) -> Int ! OrderError {
    for o in orders {
        if o.qty <= 0 {
            fail OrderError.BadQty(item: o.item)
        }
    }
    orders.sum(o => o.cost())
}

fn main() {
    const codes = ["SPRING": 10, "VIP": 25]
    const orders = [Order(item: "pen", qty: 3, cents: 150), Order(item: "cup", qty: 1, cents: 900)]

    const sum = total(orders) catch _ => 0
    const off = codes["SPRING"] ?? 0
    print("total {sum}, with {off}% off {sum * (100 - off) / 100}")
    print("WINTER gives {codes["WINTER"] ?? 0}%")

    const broken = [Order(item: "kite", qty: 0, cents: 500)]
    match total(broken) {
        ok(t) => print("total {t}"),
        err(OrderError.BadQty(item)) => print("refused: no quantity for {item}"),
    }
}

The program ran and printed:

kavach run orders.kav

total 1350, with 10% off 1215WINTER gives 0%refused: no quantity for kite
orders.kav: Kavach code, then what running it prints
  • total says in its signature that it can fail with OrderError, and the caller decides what happens then: catch gives a value, match looks at each case.
  • codes["WINTER"] may be missing, so its type is Int?, and ?? 0 says what to use then.

What you give up

  • Kavach is young. It has far fewer packages than pip, npm, Cargo or Go modules, so you lean on its standard library and on code you write.
  • It runs on Linux and Windows on x86-64 today. macOS and ARM64 are planned for a later phase of the roadmap.
  • Some habits are refused on purpose: there is no inheritance, no exception that passes up unseen, and no null.

No decorators

Kavach has no @decorator: nothing written above a function can change what it does, so its signature stays the whole story. What decorators do elsewhere is said in the signature or in plain code:

Decorator use elsewhereIn Kavach
Checking arguments and results (@validate)require, ensure, invariant (chapter 7)
Permissions, rate limitsuses (8.1); an agent's can, limit and approve (8.3)
Tests and examples (@test)example clauses and test blocks (chapter 11)
Tracing and timinglog.span("name") { … } (4.8, 14.12)
Generated equality, printing, JSON (@dataclass, derive)Every record has them already (1.8, 2.12)
Registering a route (@app.route)A call that adds it to a router

One page for each form