Developer preview. Vela, Facet, and Quire are pre-release and in active development — syntax, APIs, and availability may change, and they are not yet generally available.
SStretch Dev Docs
Vela

From Python

A Python-to-Vela migration guide for Stage-0 syntax and common idioms.

Vela is Python-adjacent: comments use #, blocks use significant indentation, and scripts run top to bottom. The important differences in Stage-0 are immutability by default, explicit boolean conditions, and Option / Result values instead of None sentinels or exceptions.

1. Variables and bindings

Python rebinds names freely. Vela requires mut for same-scope reassignment.

mut x = 10
x = x + 1

name = "Ada"
# name = "Grace"  # error: immutable binding

Inner scopes may shadow immutable bindings. Reassigning an outer mutable binding updates the outer binding.

2. Collections

Lists are immutable values. push returns a new list. Use array() or array_from when mutation is the point.

xs = [1, 2, 3]
ys = push(xs, 4)
print(xs[0], xs[-1], xs.len)

a = array()
array_push(a, 10)
array_set(a, 0, 99)
print(to_list(a))

Records cover fixed fields and immutable string-keyed maps. Mutable dictionaries use dict().

person = { name: "Ada", age: 36 }
print(person.name)

mut counts = {}
counts = set(counts, "red", get_or(counts, "red", 0) + 1)

d = dict()
dict_set(d, "red", 1)
dict_set(d, "red", dict_get_or(d, "red", 0) + 1)

3. Comprehensions become functions or pipelines

Use map, filter, reduce, and |>.

squares = map([1, 2, 3, 4], x => x * x)
evens = filter([1, 2, 3, 4], x => x % 2 == 0)
result = [1, 2, 3, 4] |> filter(x => x % 2 == 0) |> map(x => x * x)

4. No truthiness

Conditions must be Bool. Use explicit checks.

xs = [1, 2, 3]
if xs.len > 0:
    print("non-empty")

5. Exceptions become Result values

Stage-0 supports Ok, Err, and postfix ? propagation.

fn checked_div(a, b):
    if b == 0:
        return Err("divide by zero")
    return Ok(a / b)

fn ratio(a, b, c):
    x = checked_div(a, b)?
    y = checked_div(x, c)?
    return Ok(y)

6. Classes become records, functions, or tagged unions

Use records for plain data and type plus match for variant shapes.

type Shape:
    Circle(r)
    Rect(w, h)

fn area(shape):
    match shape:
        Circle(r) => 3.14 * r * r
        Rect(w, h) => w * h