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.

SyntaxRoleExample
@nameRaw identifier — use a reserved word or type name as a variable / field namelet @module = 10
#[attr]Compiler attribute — metadata on functions, structs, or parameters#[derive(Copy)]
module …Keyword — declare a module pathmodule my.app
clone xKeyword — explicit heap duplicate at a call sitesave(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
}

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

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

KeywordPurpose
letImmutable binding — value cannot be reassigned
mutUsed with let mut for a reassignable binding
constCompile-time constant name
true / falseBoolean literals

Control flow

KeywordPurpose
if / elseConditional branches
whileLoop while condition is true
for / inIteration — for i in 0..10 or for x in arr
matchPattern match on enums and values
returnReturn from the current function

Types, modules & functions

KeywordPurpose
fnFunction definition
structProduct type with named fields
enumSum type with variants
implMethods on a type; impl Trait for Type
traitTrait definition (Extended)
selfMethod receiver inside impl
importLoad another .ny file — import "path", import "path" as alias, or import { a, b } from "path"
moduleModule path declaration — see Modules
externDeclare an external (C) function
exportExport a symbol for FFI
instGeneric instance / monomorph hook (tooling)
typeType alias or associated type surface
macroMacro definition (Extended)
testTest function — run with nyra test
printBuilt-in stdout; optional color: for ANSI output
asType cast expr as Type; import alias import "…" as m; selective rename import { a as b } from "…"
unsafeBlock for raw pointers and low-level operations
asmInline assembly (inside unsafe)
deferScope-exit call (LIFO) — Extended; prefer impl Drop
outOutput / FFI direction marker in bindings

Memory & ownership

KeywordPurpose
moveUnary prefix at a call site — transfer ownership explicitly (guide)
cloneUnary 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

KeywordPurpose
spawnStart a concurrent block
async / awaitAsync 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.

TypeNotes
i8i128Signed integers; i32 is the default for int literals
u8u128Unsigned integers
isize, usizePointer-sized integers
f64IEEE-754 double; default float literal type
charUnicode scalar — 'a', '\n'
booltrue / false
stringUTF-8 heap string (Move)
voidFunctions with no return value
ptrOpaque FFI pointer handle

Full type reference: Types & data · Language reference → Type names

Compiler attributes (#[…])

Attributes attach to items in source. They start with #, not @.

AttributePurpose
#[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) { ... }

Quick reference

You writeMeaning
@moduleVariable (or field) named module
module my.appDeclare module path my.app
@cloneVariable named clone
clone userDuplicate user for a call; keep user valid
#[derive(Copy)]Compiler attribute on a struct
@i32Variable 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.