Keywords Reference

EZ uses plain English keywords designed to be readable and beginner-friendly. If you’re coming from another language, some of these will look different from what you’re used to.

Variables & Constants

temp

Declares a mutable variable — a value that can change.

temp count int = 0
count = 10  // allowed

Why “temp”? It stands for “temporary.” Use temp for values that will change during your program’s execution, like counters, user input, or calculated results.

const

Declares an immutable constant — a value that cannot change. Also used to define structs and enums.

const PI float = 3.14159
const MAX_SIZE int = 100

// Also used for type definitions
const Person struct {
    name string
    age int
}

Why “const”? It’s short for “constant.” Use const for values that should never change, like configuration settings, mathematical constants (PI), or type definitions.

Functions

do

Declares a function.

import @std

do greet(name string) {
    std.println("Hello, ${name}!")
}

do add(a, b int) -> int {
    return a + b
}

Why “do”? Functions do things. Reads naturally: “do greet” means “do the greet action.”

return

Exits a function and optionally returns a value.

do double(x int) -> int {
    return x * 2
}

do validate(n int) -> bool {
    if n < 0 {
        return false  // early return
    }
    return true
}

ensure

Guarantees a function call runs when the current function exits, regardless of how it exits. Used for cleanup like closing files or databases.

import @io

do process() {
    temp file, _ = io.open("data.txt", "r")
    ensure io.close(file)  // always runs when process() exits

    // ... work with file ...
    // io.close(file) runs automatically, even on early return
}

Multiple ensure statements run in reverse order (last registered runs first). See Functions - ensure for details.

Control Flow

if

Starts a conditional block. Executes code only if the condition is true.

import @std

if score >= 90 {
    std.println("A grade!")
}

or

Adds an alternative condition — like else if in other languages.

import @std

if score >= 90 {
    std.println("A")
} or score >= 80 {
    std.println("B")
} or score >= 70 {
    std.println("C")
}

Why “or”? Reads naturally: “if this, or that, or that.”

otherwise

The fallback case — like else in other languages.

import @std

if score >= 60 {
    std.println("Pass")
} otherwise {
    std.println("Fail")
}

Why “otherwise”? Reads like English: “if passing, celebrate; otherwise, study more.”

for

Numeric loop that iterates over a range.

import @std

for i in range(0, 5) {
    std.println(i)  // 0, 1, 2, 3, 4
}

for_each

Iterates over each item in a collection.

import @std

temp names [string] = {"Alice", "Bob", "Charlie"}

for_each name in names {
    std.println("Hello, ${name}")
}

Why “for_each”? Explicit about looping over each item in a collection.

as_long_as

Loops while a condition is true — like while in other languages.

import @std

temp count int = 0

as_long_as count < 5 {
    std.println(count)
    count++
}

Why “as_long_as”? Reads naturally: “keep going as long as this is true.”

loop

Infinite loop that runs until you break out of it.

temp attempts int = 0

loop {
    attempts++
    if attempts >= 3 {
        break
    }
}

break

Immediately exits the current loop.

import @std

for i in range(0, 100) {
    if i == 5 {
        break  // stop at 5
    }
    std.println(i)
}

continue

Skips to the next iteration of the loop.

import @std

for i in range(0, 10) {
    if i % 2 == 0 {
        continue  // skip even numbers
    }
    std.println(i)  // only odd numbers
}

in

Used with for to iterate over a range, or to check if a value exists in a collection (arrays, ranges, or maps).

import @std

// In a for loop
for i in range(0, 10) {
    std.println(i)
}

// Array membership
temp nums [int] = {1, 2, 3}
if 2 in nums {
    std.println("Found it!")
}

// Map key membership
temp ages map[string:int] = {"Alice": 30}
if "Alice" in ages {
    std.println("Key exists!")
}

not_in

Checks if a value does not exist in a collection (arrays, ranges, or maps).

temp nums [int] = {1, 2, 3}
if 5 not_in nums {
    std.println("Not found")
}

temp ages map[string:int] = {"Alice": 30}
if "Bob" not_in ages {
    std.println("Bob not in map")
}

when

Starts a pattern matching block — like switch in other languages.

import @std

temp day int = 3

when day {
    is 1 { std.println("Monday") }
    is 2 { std.println("Tuesday") }
    is 3 { std.println("Wednesday") }
    default { std.println("Other day") }
}

Why “when”? Reads naturally: “when day is 1, do this.”

is

Specifies a case in a when block.

when value {
    is 1 { /* matches 1 */ }
    is 2, 3, 4 { /* matches 2, 3, or 4 */ }
    is range(5, 10) { /* matches 5-9 */ }
    default { /* fallback */ }
}

default

The fallback case in a when block — executes when no is case matches.

when status {
    is "active" { /* handle active */ }
    is "pending" { /* handle pending */ }
    default { /* handle all other cases */ }
}

Note: default is required unless using #strict with an enum that has all cases covered.

Type Conversion

cast

Converts values between types. Works with single values and arrays.

// Single value conversion
temp x = cast(42, u8)        // int -> u8
temp y = cast(3.14, int)     // float -> int
temp z = cast(65, char)      // int -> char

// Array element-wise conversion
temp bytes [byte] = {65, 66, 67}
temp u8_arr = cast(bytes, [u8])  // [byte] -> [u8]

Why “cast”? Explicitly converts (casts) a value from one type to another.

Note: Although cast() uses function-like syntax, it is a language keyword, not a regular function. The second argument must be a valid EZ type, which the interpreter validates at check-time (before execution). This is why cast() is documented here rather than solely in built-in functions — though it also appears there for discoverability. See also: cast() in Built-in Functions.

Supported Conversions

Target TypeAccepted Source Types
intint, float, string, char, byte
floatfloat, int, string, byte, char
stringall types (uses string representation)
charchar, int, float, byte, string (len=1)
bytebyte, int, float, char, string
i8/i16/i32/i64/i128/i256int, float, string, byte, char
u8/u16/u32/u64/u128/u256int, float, string, byte, char
f32/f64float, int, string, byte, char
boolbool, int (0=false, else=true), string (“true”/“false”)

Array Conversions

For arrays, cast() applies the conversion to each element:

temp nums [int] = {1, 2, 3}
temp strs = cast(nums, [string])  // ["1", "2", "3"]

Error Handling

Invalid conversions produce errors:

// Range error with index info
temp result = cast([-1, 2, 3], [u8])
// Error: "cast failed at index 0: value -1 out of u8 range (0 to 255)"

Types

Primitive Types

KeywordDescription
intInteger (whole number)
floatFloating-point (decimal) number
stringText
charSingle character
boolBoolean (true or false)
temp age int = 25
temp price float = 19.99
temp name string = "Alice"
temp letter char = 'A'
temp active bool = true

Sized Integers

For when you need precise control over size:

SignedUnsignedSize
i8u88 bits
i16u1616 bits
i32u3232 bits
i64u6464 bits
i128u128128 bits
i256u256256 bits
temp byte u8 = 255
temp big i64 = 9223372036854775807

struct

Defines a composite type with named fields.

const Point struct {
    x int
    y int
}

temp p Point = Point{x: 10, y: 20}

enum

Defines a type with a fixed set of named values.

const Status enum {
    PENDING
    ACTIVE
    DONE
}

temp s int = Status.ACTIVE

map

Key-value collection type.

temp ages map[string:int] = {
    "Alice": 30,
    "Bob": 25
}

Modules

import

Brings a module into your file. Must be at the top.

import @std
import @math, @arrays
import "./mymodule"

using

Makes module contents available without a prefix.

import @std

do main() {
    using std
    println("No prefix!")  // instead of std.println()
}

module

Declares that a file belongs to a module (for files you want to import).

module myutils

do helper() {
    // ...
}

Visibility

By default, all user-declared functions, types, and variables are public — they can be accessed from other modules that import yours.

private

Makes a declaration private to its module. Private items cannot be accessed from outside the module.

module mylib

// Private variable — only accessible within this module
private temp internal_count int = 0

// Private function — only callable within this module
private do helper() {
    internal_count++
}

// Private type — only usable within this module
private const InternalState struct {
    value int
}

// Public function (default) — accessible from other modules
do get_count() -> int {
    helper()  // can call private function internally
    return internal_count
}

Why “private”? Hides implementation details so other modules only see what they need.

Boolean Values

true

Boolean true value.

false

Boolean false value.

temp isValid bool = true
temp hasError bool = false

nil

Represents the absence of a value. Used primarily with Error types to indicate success or check for errors.

import @std, @io

do main() {
    temp content, err = io.read("data.txt")
    if err != nil {
        std.println("Error:", err.message)
        return
    }
    // err is nil, meaning no error occurred
    std.println(content)
}

Functions that can fail return nil for the error on success, or an Error on failure.

Quick Reference Table

EZ KeywordOther LanguagesPurpose
templet, varMutable variable
constconst, finalImmutable value
dofunction, func, fn, defDeclare function
orelse if, elifAlternative condition
otherwiseelseFallback condition
for_eachfor...of, for...in, foreachIterate collection
as_long_aswhileConditional loop
loopwhile(true), loopInfinite loop
whenswitch, matchPattern matching
iscasePattern case
defaultdefault, _Fallback case
casttype casts, asType conversion
ensuredeferGuaranteed cleanup on function exit
nilnull, None, nilAbsence of a value
privateprivate, internalModule-private declaration

For attributes (#doc, #enum, #flags, #strict, #suppress), see Attributes.

See Also

  • Control Flow — detailed control flow usage and examples
  • Functions — detailed function usage and examples
  • Variables — detailed variable usage and examples
  • Modules — detailed module system usage