Types & data
Built-in types, user-defined structs and enums, arrays, and references.
let x = 42 or let x: i32 = 42 — same program. Annotations are erased at compile time (zero runtime cost). Use them when they help readers or when inference is ambiguous.
Complete type catalog
| Type | Ownership | Description |
|---|---|---|
i8 … i128 | Copy | Signed integers; i32 default for 42 literals |
u8 … u128 | Copy | Unsigned integers |
isize, usize | Copy | Pointer-sized integers (64-bit on common targets) |
f32 | Copy | IEEE-754 single; literals 1.5f32 or let x: f32 = 1.5 |
f64 | Copy | IEEE-754 double; literals 3.14, 1e-3 (default for floats) |
char | Copy | Unicode scalar; literals 'a', '\n', '\u{41}' |
bool | Copy | true / false |
string | Move | UTF-8 bytes; literals static, heap APIs auto-dropped |
VecStr | Copy (handle) | Split result from .split(sep); iterable string parts; auto-freed at scope end |
void | — | No return value |
ptr | Copy | Opaque FFI handle (maps, channels, malloc); Send |
*T, *const T, *mut T | Copy | Typed raw pointer for unsafe systems code; !Send / !Sync |
&T / &mut T | Borrow | Immutable / mutable reference to T |
&'a T | Borrow | Reference with explicit lifetime (Extended tier) |
[T; N] | Depends on T | Fixed-size array, e.g. [i32; 4] |
(T, U, …) | Depends on fields | Tuple — fixed arity product type |
Vec<T> | Depends on T | Generic growable vector (stdlib); monomorphized at compile time |
StructName | Copy or Move | User struct; auto-Copy when all fields Copy |
EnumName | Copy | User enum — tag + optional payload |
option / result | Copy | Built-in enum tags (Option.Some, Result.Ok, …) |
for<'a> fn(...) | — | Higher-ranked function pointer type (Extended tier) |
T (generic) | — | Type parameter on fn id<T>(x: T) -> T; inferred at call site |
Ownership rules: Memory & ownership · Ownership UX (auto-borrow, auto-Copy) · Quick lookup: Language reference → Type names
Built-in scalars
Full Rust-style integer families: i8–i128, u8–u128, plus isize / usize. All are optional — omit annotations and Nyra infers i32 for integer literals and f64 for floats.
VecStr (split lists)
string.split(sep) returns a VecStr — a heap-owned list of substring parts. You can iterate with for part in parts or annotate explicitly:
let parts = "api,ui,docs".split(",")
for part in parts {
print(part)
}let parts: VecStr = "api,ui,docs".split(",")
for part in parts {
print(part)
}Inferred without annotation; VecStr is optional sugar for documentation and APIs. See For loops and built-in string methods.
Structs
fn main() {
// Anonymous object literal — compiler infers struct shape
let p = { x: 1, y: 2 }
let q = p // Copy when all fields are Copy
print(p.x)
// Optional: declare struct for organization / impl / FFI
// struct Point { x: i32, y: i32 }
// let p = Point { x: 1, y: 2 }
}fn main() -> void {
// Anonymous object literal — compiler infers struct shape
let p = { x: 1, y: 2 }
let q = p // Copy when all fields are Copy
print(p.x)
// Optional: declare struct for organization / impl / FFI
// struct Point { x: i32, y: i32 }
// let p: Point = Point { x: 1, y: 2 }
}Anonymous { field: value } literals infer a compile-time struct (same LLVM layout as Point { ... }). Declare struct Point when you want a named type for impl, FFI, or clarity. Literal fields are comma-separated ({ x: 1, y: 2 }); struct definitions use newlines between fields. Constructor sugar: Point(1, 2) or User("Ada") desugars to struct literals (RFC 0006). Structs with any Move field (e.g. string) are Move.
Enums
enum Color {
Red
Green
Blue
}
fn main() {
let c = Color.Red
let tag = match c {
Color.Red => 1
Color.Green => 2
Color.Blue => 3
}
print(tag)
}enum Color {
Red
Green
Blue
}
fn main() -> void {
let c = Color.Red
let tag = match c {
Color.Red => 1
Color.Green => 2
Color.Blue => 3
}
print(tag)
}Variant names use the form Type.Variant (e.g. Color.Red).
Arrays & slices
let buf = [1, 2, 3, 4]
let first = buf[0]let buf: [i32; 4] = [1, 2, 3, 4]
let first = buf[0]Fixed-size arrays use [T; N]. Slice type [T] is parsed and type-checked (MVP stack semantics). Growable Vec<T> lives in the stdlib — see Vectors.
Tuples
let pair = (42, "ok")
print(pair.0)
print(pair.1)let pair = (42, "ok")
print(pair.0)
print(pair.1)Tuple fields are accessed with .0, .1, … See Learn → Tuples.
References
let x = 10
let r = &x
let m = &mut y // y must be let mutlet x: i32 = 10
let r = &x
let m = &mut y // y must be let mutBorrow rules enforced at compile time. Cannot return &local. See Memory & ownership.
Raw pointers (ptr vs *T)
| Type | Role | Send / Sync |
|---|---|---|
ptr | Opaque FFI handle (Vec internals, C addresses, malloc) | Send |
*T | Typed raw pointer for systems code (MMIO, drivers, kernels) | !Send / !Sync |
*const T / *mut T | Rust-style aliases for *T (same semantics today) | !Send / !Sync |
extern fn mmio_base(){
unsafe {
let addr = mmio_base()
return *addr
}
}extern fn mmio_base(){
unsafe {
let addr = mmio_base()
return *addr
}
}Obtain a raw pointer from a stack binding: &x as *i32 (inside unsafe). Full rules: Memory → unsafe.
Literals
- Integers:
42,1_000_000(separators) →i32 - Floats:
3.14,19.99,1e-3→f64 - Characters:
'a','\n','\u{41}'→char - Strings:
"hello" - Struct:
Point { x: 1, y: 2 } - Array:
[1, 2, 3]with type[T; N]
Built-in enum tags
option/Option and result/Result — tag-only in v0.2 (no stored payloads). See Match.
Generics
Monomorphization in v0.2 — see Generics.
Systems & stdlib types (Rust comparison)
All annotations below are optional. Nyra infers types by default; add names when you want clarity or FFI boundaries.
| Rust concept | Nyra | Status | Notes |
|---|---|---|---|
fn(i32) -> i32 | fn(i32) -> i32 | ✅ Language | Function pointers; closures that escape promote to fn(...) |
|x| x + 1 | (x) => x + 1 | ✅ Extended | Arrow closures; captures by value (Copy/Move) |
struct / enum | struct / enum | ✅ Language | User ADTs; enum payloads with generics (Extended) |
Option<T> | import "stdlib/option.ny" | ✅ Stdlib | Option.Some(v), ??, ?. |
Result<T,E> | stdlib/option.ny + stdlib/result.ny | ✅ Stdlib | ? operator for propagation |
Vec<T> | Vec_i32, import "stdlib/vec.ny" | ✅ Stdlib | Monomorph C-backed growable vector; generic Vec<T> syntax monomorphizes |
HashMap<K,V> | HashMap_str_i32, HashMap_str_str | ✅ Stdlib | import "stdlib/map.ny" |
HashSet<T> | HashSet_str | ✅ Stdlib | import "stdlib/collections/set.ny" |
BTreeMap<K,V> | BTreeMap_str_i32 | ⚠️ Stub | MVP wrapper over hash map; real B-tree in apps (Apps/Basics/BTree) |
Box<T> | stdlib/box.ny | ⚠️ Partial | Generic Box<T> struct; heap API ships for string |
Arc<T> | stdlib/arc.ny | ✅ Stdlib | Arc<i32>, Arc<string> |
Mutex<T> / RwLock<T> | Mutex, RwLock, Mutex_i32 | ✅ Stdlib | import "stdlib/sync/mutex.ny" |
AtomicI32 / AtomicBool | Atomic_i32, AtomicBool | ✅ Stdlib | import "stdlib/sync/atomic.ny" |
Rc<T> | — | ❌ | Use Arc for shared ownership; single-thread Rc planned |
Cell / RefCell | — | ❌ | Use mut + borrow checker, or Mutex across threads |
PhantomData / Pin / Cow | — | ❌ | Advanced Rust-only; not required for Nyra MVP |
! (never) | — | ❌ | Use void or a concrete return type |
() unit | void | ✅ Language | Inferred when a function has no return |
size_of::<T>() / align_of::<T>() | size_of<T>(), align_of<T>() | ✅ Language | Layout size / alignment in bytes; helpers in stdlib/mem/layout.ny |
size_of / align_of
Compiler intrinsics — no import. Returns layout size and alignment in bytes (×8 for bits).
fn main() {
print(size_of<i32>()) // 4
print(size_of<i64>()) // 8
print(align_of<i64>()) // 8
}fn main() -> void {
print(size_of<i32>()) // 4
print(size_of<i64>()) // 8
print(align_of<i64>()) // 8
}Output
4
8
8
Full guide: stdlib → size_of · Memory → Type layout
Example tour: examples/syntax/systems_types.ny · Full stdlib matrix: Standard library