FORMA programming language reference. Use when writing FORMA (.forma) code or answering questions about FORMA syntax, builtins, contracts, or CLI usage.
FORMA is an indentation-based, AI-optimized systems programming language. It uses
short keywords, design-by-contract, capability-based sandboxing, and a rich stdlib
of 316+ builtins.
Core Syntax
Indentation-based blocks (like Python), no braces needed
Comments: # single line
Variables: x := value (mutable by default), x: Type = value (annotated)
f name(a: Int, b: Int) -> Int
a + b
f single_expr(a: Int, b: Int) -> Int = a + b
as f async_fn() -> Str!Str # async function
aw some_future()?
f with_ref(ref data: [Int]) -> Int # shared ref param
f with_mut(ref mut data: [Int]) -> Unit # mutable ref param
# Closures (typed parameters required)
doubled := map([1, 2, 3], |x: Int| x * 2)
transform := |x: Int| -> Int x * 2 + 1
Struct, Enum, Trait, Impl
s Point
x: Float
y: Float
s Pair(Int, Int) # tuple struct
s Unit # unit struct
e Color = Red | Green | Blue
e Option[T] = Some(T) | None
t Printable
f to_string(&self) -> Str
i Point
f distance(&self) -> Float
sqrt(self.x * self.x + self.y * self.y)
i Printable for Point
f to_string(&self) -> Str
f"{self.x}, {self.y}"
Control Flow
if cond then expr else expr # inline expression form
if cond
block
else if cond
block
else
block
m value # match
Pattern -> expr
Variant(x) -> expr
Point { x, y } -> x + y # struct destructure
_ if guard -> expr # guard
_ -> default
wh condition # while
body
for x in collection # for-in
body
lp # infinite loop
if done then br
'outer: for x in xs # labeled loop
for y in ys
if x == y then br 'outer
Error Handling
# Propagate with ? (Result only)
f load(path: Str) -> Str!Str
content := file_read(path)?
Ok(content)
# Default with ?? (Option only)
name := env_get("USER") ?? "unknown"
val := str_to_int("abc") ?? 0
# Unwrap with ! (panics on error)
db := db_open("app.db")!
# Match on Result/Option
m result
Ok(v) -> use(v)
Err(e) -> handle(e)
m str_to_int(s)
Some(n) if n > 0 -> Ok(n)
Some(_) -> Err("not positive")
None -> Err("not a number")
Contracts (Design by Contract)
@pre(n >= 0)
@post(result > 0, "must be positive")
f factorial(n: Int) -> Int
if n <= 1 then 1 else n * factorial(n - 1)
@post(old(balance) + delta == result)
f deposit(balance: Int, delta: Int) -> Int
balance + delta
@pre(values.len() > 0)
@post(forall i in 0..result.len()-1: result[i] <= result[i+1])
@post(permutation(values, result))
f sort(values: [Int]) -> [Int]
sort_ints(values)
as f work() -> Int
result := aw some_future()
result
task := sp work()
value := aw task
results := aw await_all(tasks)
Modules & Imports
us module.path
us module.{A, B}
us std.io # stdlib module
md name
pub f helper() -> Int = 0
Reference Parameters
f sum(ref arr: [Int]) -> Int # read-only reference
total := 0
for x in arr
total := total + x
total
f sort(ref mut arr: [Int]) -> Unit # mutable reference
# Calling with ref
total := sum(ref data)
sort(ref mut data)
Main Function
f main()
# program logic here
print("hello")
f main() -> Int # explicit exit code
if ok then 0 else 1
CLI Commands
forma run <file> # run program
forma run <file> --allow-all # all capabilities
forma run <file> --allow-read --allow-network # specific capabilities
forma run <file> --no-check-contracts # disable contract checking
forma check <file> # type check only
forma check <file> --error-format json # JSON diagnostic output
forma explain <file> --format json # contract explanations
forma verify <path> --report # verify contracts with examples
forma build <file> # build native binary (LLVM)
forma fmt <file> # format source code
forma new <name> # create new project
forma init # init project in current dir
forma repl # interactive REPL
Security: Prefer least-privilege flags over --allow-all. The --allow-exec
flag permits shell command execution and should be treated as full shell access.
Do not use --allow-all on untrusted code.
316+ builtins total across I/O, math, string, collection, file, JSON, HTTP, TCP, UDP,
TLS, DNS, database, async, random, time, regex, compression, hashing, FFI, and more.
Run forma complete <file> --position 1:1 for a full list.
Stdlib Modules
us std.core # clamp, gcd, lcm
us std.io # file_read_lines, file_write_lines, puts
us std.string # str_join, str_replace_first, str_index_of
us std.vec # int_vec_index_of, int_vec_sum, int_vec_max
us std.iter # range, enumerate
us std.map # map_get_or, map_update
Common Patterns
File I/O
f main()
# Read a file (returns Result — use ? or !)
content := file_read("input.txt")!
lines := str_split(content, "\n")
for line in lines
print(line)
# Write a file
file_write("output.txt", "hello world")!
# Append to a file
file_append("log.txt", f"entry: {time_now()}\n")!
# Check existence
if file_exists("config.json")
cfg := json_parse(file_read("config.json")!)
print(json_get_str(cfg, "name"))
HTTP Server
f handler(req: HttpRequest) -> HttpResponse
m req.path
"/" -> http_response(200, "OK")
"/json" -> http_json_response(200, json_object())
_ -> http_response(404, "Not Found")
f main()
http_serve(8080, handler)!
Database
f main()
db := db_open("app.db")!
db_execute(db, "CREATE TABLE t (id INTEGER, name TEXT)")!
rows := db_query(db, "SELECT * FROM t")!
for row in rows
print(row_get_str(row, 1))
db_close(db)
Struct with Methods
s Point
x: Float
y: Float
i Point
f distance(&self) -> Float
sqrt(self.x * self.x + self.y * self.y)
f translate(&self, dx: Float, dy: Float) -> Point
Point { x: self.x + dx, y: self.y + dy }
f main()
p := Point { x: 3.0, y: 4.0 }
print(f"distance: {p.distance()}")
p2 := p.translate(1.0, 2.0)
print(f"moved to: {p2.x}, {p2.y}")