Coming From Another Language: Python
● Beginner6 minBefore this: Coming From Another Language
From Python: records instead of classes, errors in the signature instead of exceptions, and none only where a type allows it.
Here is one small program twice: in Python 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.
from dataclasses import dataclass
@dataclass
class Order:
item: str
qty: int
cents: int
def cost(self) -> int:
return self.qty * self.cents
class BadQty(Exception):
def __init__(self, item: str):
self.item = item
def total(orders: list[Order]) -> int:
for o in orders:
if o.qty <= 0:
raise BadQty(o.item)
return sum(o.cost() for o in orders)
def main():
codes = {"SPRING": 10, "VIP": 25}
orders = [Order("pen", 3, 150), Order("cup", 1, 900)]
try:
total_ = total(orders)
except BadQty:
total_ = 0
off = codes.get("SPRING", 0)
print(f"total {total_}, with {off}% off {total_ * (100 - off) // 100}")
print(f"WINTER gives {codes.get('WINTER', 0)}%")
broken = [Order("kite", 0, 500)]
try:
print(f"total {total(broken)}")
except BadQty as e:
print(f"refused: no quantity for {e.item}")
main()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
What changes
| In Python | In Kavach | Learn it |
|---|---|---|
class Order: with @dataclass | type Order { … }, its methods inside it | Records |
raise BadQty(…) and except | fail OrderError.BadQty(item: …), with ! OrderError in the signature, and catch or match | Errors |
| an exception passes up by itself | try passes it on, so every call that can fail is marked | try |
None | none, only in a type that ends in ? | Optionals |
codes.get("SPRING", 0) | codes["SPRING"] ?? 0 | Reading a value |
f"total {x}" | "total {x}": every string can hold values | Interpolation |
sum(o.cost() for o in orders) | orders.sum(o => o.cost()) | map, filter, sum |
-7 // 2 is -4, rounded down | -7 / 2 is -3, towards zero; div_floor rounds down | Arithmetic |
b = a shares a list | b = a copies it | Values, Not References |
| types checked by a separate tool, if at all | every type checked before the program runs | Data Types |
threads and the GIL, or asyncio | spawn starts a task, spawn cores runs it on any core; there is no async | How Tasks Run |
pip and requirements.txt | kavach.toml, and kavach add | Packages |
| blocks by indentation | blocks in braces, { … } | Syntax |
Habits from other languages get a clear error that says what to write instead: see Habits from other languages.