Language syntax
Core syntax for Nyra — indentation-friendly blocks, minimal keywords. New to Nyra? Start with Language basics. See also Language reference and Standard library.
Hello World
fn main() {
print("Hello, world!")
}fn main() -> void {
print("Hello, world!")
}Variables
New to programming? Read the full walkthrough: Language basics → Variables.
let — immutable binding
Creates a name for a value. After initialization, you must not assign a new value to that name.
let x = 42 // x stays 42 unless you used let mutlet x: i32 = 42mut — mutable (changeable)
mut is short for mutable. Use let mut when the value will change (counters, loops).
let mut n = 0 // n can be reassigned
n = n + 1let mut n: i32 = 0
n = n + 1const — compile-time constant
const MAX = 100 // fixed name; value known when compilingconst MAX = 100 // fixed name; value known when compilinglet | let mut | const | |
|---|---|---|---|
| Reassign? | No | Yes | No |
| When set? | At runtime in code | At runtime; can change | At compile time |
string and heap-owned values are Move types — see Memory & ownership.
Functions
fn add(a, b) {
return a + b
}
fn greet(name) {
print(name)
}fn add(a: i32, b: i32) -> i32 {
return a + b
}
fn greet(name: string) {
print(name)
}Generic syntax is supported with monomorphization (fn id<T>(x: T)).
Template strings
let name = "Nyra"
let score = 42
print(`Hello, ${name}!`)
print(`score)let name: string = "Nyra"
let score: i32 = 42
print(`Hello, ${name}!`)
print(`score)Arrow functions
let add_one = (x) => x + 1
print(add_one(41))let add_one = (x) => x + 1
print(add_one(41))Emits warning[W001] unless you use --deny-extended in CI. Useful for HTTP handler slots — see net/http.
Control flow
if / else
if x > 0 {
print("positive")
} else {
print("non-positive")
}
while
let mut i = 0
while i < 10 {
print(i)
i = i + 1
}let mut i: i32 = 0
while i < 10 {
print(i)
i = i + 1
}break / continue
break exits the nearest loop; continue skips to the next iteration (while and range for).
let mut sum = 0
let mut i = 0
while i < 10 {
i = i + 1
if i == 5 { continue }
sum = sum + i
}let mut sum: i32 = 0
let mut i: i32 = 0
while i < 10 {
i = i + 1
if i == 5 { continue }
sum = sum + i
}for range
for i in 0..5 {
print(i)
}for i in 0..5 {
print(i)
}if expressions
let sign = if x >= 0 { 1 } else { -1 }let sign = if x >= 0 { 1 } else { -1 }match
Exhaustive-style matching on enums and values. Supports guards — see Match.
let n = match color {
Color.Red if x > 0 => 1
Color.Green => 2
Color.Blue => 3
}let n = match color {
Color.Red if x > 0 => 1
Color.Green => 2
Color.Blue => 3
}Methods
Defined with impl; desugared to Type_method functions:
impl Calculator {
fn add(self, n) {
Calculator { value: self.value + n }
}
}impl Calculator {
fn add(self, n: i32) {
Calculator { value: self.value + n }
}
}let c2 = c.add(10)let c2 = c.add(10)I/O
print("line") // stdout + newline
print(42) // integers
write("no newline") // buffered
println("line") // buffered + newline
flush() // flush buffer
let s = input("Name? ")print("line") // stdout + newline
print(42) // integers
write("no newline") // buffered
println("line") // buffered + newline
flush() // flush buffer
let s: string = input("Name? ")Colored output
Add an optional color: argument to print. Works in ANSI-capable terminals (macOS Terminal, iTerm, Windows Terminal).
print("Error!", color: red)
print("OK", color: green)
print("Custom", color: "#FF5733") // #RGB or #RRGGBB
print("RGB", color: "rgb(0,255,128)")
print(msg, color: myColor) // string variable
Named colors: red, green, blue, yellow, cyan, magenta, bold, dim, bright_red, … See I/O built-ins.
String escapes
Double-quoted strings support \n, \t, \\, \", octal (\033), hex (\x1b), and Unicode (\u{1b}).
Date & time
let d = date()
print(d.year)
print(d.month) // 1–12
print(d.day)
print(d.hour)
print(d.minute)
print(d.second)
print(d.week) // 0=Sunday … 6=Saturdaylet d: Date = date()
print(d.year)
print(d.month) // 1–12
print(d.day)
print(d.hour)
print(d.minute)
print(d.second)
print(d.week) // 0=Sunday … 6=SaturdayAliases: d.minutes, d.seconds, d.weekday. Full reference: Built-ins → date().
String & array built-ins
let parts = "a,b,c".split(",")
for p in parts { print(p) }
let arr = [10, 20, 30]
for n in arr { print(n) }
print(arr.length())let parts: VecStr = "a,b,c".split(",")
for p in parts { print(p) }
let arr: [i32; 3] = [10, 20, 30]
for n in arr { print(n) }
print(arr.length())String methods: .trim(), .contains(), .replace(), .to_upper(), … — full list.
defer (Extended — prefer Drop)
Run a call expression when the block ends (LIFO). Extended tier — emits warning[W001]. For memory, auto-drop already frees at }; for handles, use impl Drop RAII instead of defer free.
extern fn close_fd(fd){
let fd = open(path)
defer close_fd(fd) // OK: FFI teardown; prefer impl Drop for reusable types
read_into(fd)
}
// owned string locals: auto-dropped — no defer neededextern fn close_fd(fd){
let fd = open(path)
defer close_fd(fd) // OK: FFI teardown; prefer impl Drop for reusable types
read_into(fd)
}
// owned string locals: auto-dropped — no defer neededDetails: Memory → defer vs Drop · nyra-skill.md
Timing & memory (builtins)
No import required — same ergonomics as print and date():
time_start("loop")
mem_start("RAM")
// ... work ...
time_end("loop")
mem_end("RAM")
Full API: Standard library → Built-ins.
FFI
extern fn printf(fmt: string, ...) -> i32
export fn my_api() -> i32 { return 0 }
Tests
test fn adds() {
let sum = 1 + 2
print(sum)
}test fn adds() {
let sum = 1 + 2
print(sum)
}Comments
Line comments with //. Block comments are planned.
See Types & data for structs, enums, arrays, and references. Complete keyword/operator list: Language reference.