Skip to content
Kavachकवच

Coming From Another Language: Rust

● Beginner6 minBefore this: Coming From Another Language

From Rust: Result and Option are written ! E and T?, there is no borrowing to plan, and tasks need no async runtime.

Here is one small program twice: in Rust as you would write it, then in Kavach. Orders with a quantity and a price, a total that refuses an order with no quantity, and discount codes that may be missing. Both print the same three lines.

use std::collections::HashMap;

struct Order {
    item: String,
    qty: i64,
    cents: i64,
}

impl Order {
    fn cost(&self) -> i64 {
        self.qty * self.cents
    }
}

enum OrderError {
    BadQty { item: String },
}

fn total(orders: &[Order]) -> Result<i64, OrderError> {
    for o in orders {
        if o.qty <= 0 {
            return Err(OrderError::BadQty { item: o.item.clone() });
        }
    }
    Ok(orders.iter().map(|o| o.cost()).sum())
}

fn main() {
    let codes = HashMap::from([("SPRING", 10), ("VIP", 25)]);
    let orders = vec![
        Order { item: "pen".to_string(), qty: 3, cents: 150 },
        Order { item: "cup".to_string(), qty: 1, cents: 900 },
    ];

    let sum = total(&orders).unwrap_or(0);
    let off = *codes.get("SPRING").unwrap_or(&0);
    println!("total {sum}, with {off}% off {}", sum * (100 - off) / 100);
    println!("WINTER gives {}%", codes.get("WINTER").unwrap_or(&0));

    let broken = vec![Order { item: "kite".to_string(), qty: 0, cents: 500 }];
    match total(&broken) {
        Ok(t) => println!("total {t}"),
        Err(OrderError::BadQty { item }) => println!("refused: no quantity for {item}"),
    }
}
orders.rs: rust code
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

What changes

In RustIn KavachLearn it
let mut count = 0let count = 0: a let can already change, and const can'tlet
struct and impltype Order { … } with its methods inside, or in an extendRecords
traitsinterfacesInterfaces
Result<i64, OrderError>-> Int ! OrderErrorErrors
?try before the calltry
Option<T> and unwrap_or(0)T? and ?? 0Optionals
&, &mut, lifetimes and .clone()none of them: values are copied, and inout marks a parameter a function changesValues, Not References
impl Droptype Guard: DropFreed immediately
HashMap::from([("SPRING", 10)])["SPRING": 10]Making a map
iter().map(…).sum()orders.sum(o => o.cost())map, filter, sum
async and a runtime such as Tokiospawn, with no asyncTasks
Cargo and cratespackages in kavach.toml, each granted only the capabilities its can listsPackages
unsafeunsafe { … } too, and kavach audit lists every useUnsafe

Habits from other languages get a clear error that says what to write instead: see Habits from other languages.