Nyra Keywords
Every reserved word and type name the lexer treats as a keyword — plus how to reuse those names as variables with a leading @, and how compiler attributes differ (#[…], not @).
@ vs #[ ]
Nyra uses two different prefix forms. They are not interchangeable.
| Syntax | Role | Example |
|---|---|---|
@name | Raw identifier — use a reserved word or type name as a variable / field name | let @module = 10 |
#[attr] | Compiler attribute — metadata on functions, structs, or parameters | #[derive(Copy)] |
module … | Keyword — declare a module path | module my.app |
clone x | Keyword — explicit heap duplicate at a call site | save(clone user) |
@module and @clone in source are not special builtins — they are ordinary identifiers whose names happen to match keywords. See Raw identifiers below.
Raw identifiers (@name)
When a name is reserved (keyword or built-in type), you cannot use it bare as an identifier. Prefix it with @ — the same idea as Rust r#name.
The lexer strips the @ and treats the token as a normal Identifier. The compiler stores the name without the prefix.
fn main() {
let @module = 10
let @clone = @module
print(@clone) // prints 10
}fn main() -> void {
let @module = 10
let @clone = @module
print(@clone) // prints 10
}Here @module is a variable named module; @clone is a variable named clone. This is unrelated to the module declaration keyword or the clone ownership prefix.
When @ is required
Any name that the lexer would otherwise parse as a keyword or type token needs @ to be used as an identifier:
Without @ | With @ |
|---|---|
module → module keyword | @module → variable named module |
clone → clone prefix | @clone → variable named clone |
fn → function keyword | @fn → variable named fn |
i32 → type i32 | @i32 → variable named i32 |
Rules
@must be followed by a letter or_(not a digit).let x = @alone is a lexer error (Expected identifier after '@').let x = @1is invalid for the same reason.- C bindings from
nyra pkg c addmay append_to reserved C names instead of using@(see C Bindgen).
Reserved words list
The table below matches the compiler’s reserved-name list used by C bindgen (c-bindgen/src/names.rs). These names cannot appear as bare identifiers in Nyra source.
let mut fn if else while return true false print import
module struct impl self for const extern export inst enum
match spawn in test async await trait macro defer unsafe asm
as move clone void bool string ptr char type out
i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 isize usize f64
The lexer also reserves additional tokens (e.g. break, continue, pub, priv, dyn, f32, benchmark, parallel, progress). Treat any keyword from the language reference as requiring @ when used as an identifier.
Bindings & constants
| Keyword | Purpose |
|---|---|
let | Immutable binding — value cannot be reassigned |
mut | Used with let mut for a reassignable binding |
const | Compile-time constant name |
true / false | Boolean literals |
Control flow
| Keyword | Purpose |
|---|---|
if / else | Conditional branches |
while | Loop while condition is true |
for / in | Iteration — for i in 0..10 or for x in arr |
match | Pattern match on enums and values |
return | Return from the current function |
Types, modules & functions
| Keyword | Purpose |
|---|---|
fn | Function definition |
struct | Product type with named fields |
enum | Sum type with variants |
impl | Methods on a type; impl Trait for Type |
trait | Trait definition (Extended) |
self | Method receiver inside impl |
import | Load another .ny file — import "path", import "path" as alias, or import { a, b } from "path" |
module | Module path declaration — see Modules |
extern | Declare an external (C) function |
export | Export a symbol for FFI |
inst | Generic instance / monomorph hook (tooling) |
type | Type alias or associated type surface |
macro | Macro definition (Extended) |
test | Test function — run with nyra test |
print | Built-in stdout; optional color: for ANSI output |
as | Type cast expr as Type; import alias import "…" as m; selective rename import { a as b } from "…" |
unsafe | Block for raw pointers and low-level operations |
asm | Inline assembly (inside unsafe) |
defer | Scope-exit call (LIFO) — Extended; prefer impl Drop |
out | Output / FFI direction marker in bindings |
Memory & ownership
| Keyword | Purpose |
|---|---|
move | Unary prefix at a call site — transfer ownership explicitly (guide) |
clone | Unary prefix or .clone() — heap duplicate; original stays valid |
clone user and let @clone = user mean completely different things: the first duplicates a value; the second binds a variable whose name is the word clone.
Concurrency & async
| Keyword | Purpose |
|---|---|
spawn | Start a concurrent block |
async / await | Async functions and suspension (Extended) |
Type names
These tokens are parsed as type names, not ordinary identifiers. Use @ if you need a variable with the same spelling.
| Type | Notes |
|---|---|
i8 … i128 | Signed integers; i32 is the default for int literals |
u8 … u128 | Unsigned integers |
isize, usize | Pointer-sized integers |
f64 | IEEE-754 double; default float literal type |
char | Unicode scalar — 'a', '\n' |
bool | true / false |
string | UTF-8 heap string (Move) |
void | Functions with no return value |
ptr | Opaque FFI pointer handle |
Full type reference: Types & data · Language reference → Type names
Compiler attributes (#[…])
Attributes attach to items in source. They start with #, not @.
| Attribute | Purpose |
|---|---|
#[derive(Copy)] | Document / validate that a struct is Copy-safe |
#[derive(Clone)] | Synthesize .clone() when fields allow it |
#[comptime] | Evaluate this function at compile time; strip from binary — Comptime guide |
#[inline] | Hint inlining at call sites |
#[hot] / #[cold] | LLVM branch-hint attributes for hot / cold paths |
#[no_escape] | On &T parameters — value must not escape the function — Escape analysis |
#[derive(Copy)]
struct Point { x: i32 y: i32 }
#[comptime]
fn table_size() { return 256 }
fn process(#[no_escape] data) { ... }#[derive(Copy)]
struct Point { x: i32 y: i32 }
#[comptime]
fn table_size() -> i32 { return 256 }
fn process(#[no_escape] data: i32) { ... }Quick reference
| You write | Meaning |
|---|---|
@module | Variable (or field) named module |
module my.app | Declare module path my.app |
@clone | Variable named clone |
clone user | Duplicate user for a call; keep user valid |
#[derive(Copy)] | Compiler attribute on a struct |
@i32 | Variable named i32 (not type annotation) |
LLVM @ (not Nyra source)
Generated LLVM IR uses @symbol for global functions (e.g. @i32_to_string). That is LLVM notation, not something you write in .ny files.