A sketch of what Zeno might look like. Nothing here is final
The whole of examples/tour.zeno, and what zeno run prints for it.
# tour.zeno: a sketch of what Zeno might look like. Nothing here is final.
#
# Two rules:
# 1. Words over symbols. Keywords are whole words you can read aloud.
# 2. Punctuation has to earn its place. Braces mark blocks, and that's
# about it: no semicolons, no colons after if/for, no brackets around conditions.
from math import sqrt
# --- Variables: say once whether a value can change ---
let name = "Zeno" # let: set once, never changes
var count = 3 # var: can change later
count = count + 1 # plain = updates an existing variable
let ports: list[int] = [80, 443, 8080] # write the type only when you want to
const PI = 3.14159 # const: fixed when the program is built
# --- Functions ---
function greet(who: str, excited: bool = false) -> str {
if excited {
return f"Hello, {who}!"
}
return f"Hello, {who}."
}
# --- Classes: fields at the top, methods below ---
class Point {
x: float
y: float
function distance_to(self, other: Point) -> float {
return sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)
}
}
let origin = Point(0.0, 0.0)
let here = Point(x=3.0, y=4.0)
# --- Enums that carry data, and match to take them apart ---
enum Shape {
Circle(radius: float)
Rect(width: float, height: float)
}
function area(shape: Shape) -> float {
match shape {
case Circle(r) { return PI * r * r }
case Rect(w, h) { return w * h }
}
# Forget a case and the compiler tells you, before the program ever runs.
}
# --- Errors: try / except / raise, but checked ---
function parse_port(text: str) -> int raises ValueError {
let port = int(text) # int() may raise ValueError; it passes up
if not 1 <= port <= 65535 { # comparisons chain, as in maths
raise ValueError("port out of range")
}
return port
}
try {
let port = parse_port("8080")
print(f"listening on {port}")
} except ValueError as err {
print(f"error: {err}")
}
# Under the hood a `try` remembers one place to jump back to. There are no
# unwinding tables as in C++, so it is cheap enough for a microcontroller.
# --- No surprise none ---
function find_user(id: int) -> str or none {
if id == 1 {
return "partha"
}
return none
}
let user = find_user(2)
if user is not none {
print(user.upper()) # allowed only inside this check
}
# --- Loops ---
for shape in [Circle(1.0), Rect(2.0, 3.0)] {
print(f"area = {area(shape):.2f}")
}
var tries = 0
while tries < 3 and ports[tries] != 8080 {
tries += 1
}
let squares = [n * n for n in range(10) if n % 2 == 0]
print(greet(name, excited=true), count, squares, origin.distance_to(here))
# --- Functions are values, and units are types ---
function twice(f: function(int) -> int, x: int) -> int {
return f(f(x))
}
function describe(delay: ms) -> str { # only a quantity in ms is accepted
return f"waiting {delay}"
}
print(twice(function(n) { return n * 3 }, 2), describe(500 ms))zeno run examples/tour.zeno
listening on 8080
area = 3.14
area = 6.00
Hello, Zeno! 4 [0, 4, 16, 36, 64] 5.0
18 waiting 500 msSee it on GitHub: examples/tour.zeno.