Built-in Functions

These functions are built into the language and always available — no imports needed.

Output Functions

println()

(values ...type) -> void

Prints one or more values to stdout, followed by a newline.

println("Hello, World!")
println("The answer is:", 42)
println("x =", x, "y =", y)

Parameters: Any number of values of any type.

Returns: Nothing.

print()

(values ...type) -> void

Prints one or more values to stdout without a trailing newline.

print("Enter your name: ")
mut name = input()
println("Hello, " + name)

Parameters: Any number of values of any type.

Returns: Nothing.

eprintln()

(values ...type) -> void

Prints one or more values to stderr, followed by a newline.

eprintln("Error:", "something failed")
eprintln("Warning: invalid input")

Parameters: Any number of values of any type.

Returns: Nothing.

eprint()

(values ...type) -> void

Prints one or more values to stderr without a trailing newline.

eprint("Error: ")
eprintln("connection failed")

Parameters: Any number of values of any type.

Returns: Nothing.

Program Control

exit()

(int) -> void

Exits the program with the specified status code.

// Exit with success
exit(0)

// Exit with failure
exit(1)

// Exit with custom code
exit(42)

Parameters: An integer status code (0 for success, non-zero for failure).

Returns: Does not return (terminates the program).

panic()

(string) -> void

Terminates the program immediately with a panic message. The message is prefixed with [PANIC].

panic("something went wrong")
// Output: [PANIC] something went wrong

Parameters: A string message describing why the program is panicking.

Returns: Does not return (terminates the program).

Error CodeCondition
E5021Panic called

assert()

(bool, string) -> void

Checks that a condition is true. If the condition is false, terminates the program with an assertion failure message prefixed with [ASSERT].

mut x = 5
assert(x > 0, "x must be positive")  // Passes

mut y = -1
assert(y > 0, "y must be positive")  // Fails: [ASSERT] y must be positive

Parameters:

  • condition: A boolean expression to check
  • message: A string message to display if the assertion fails

Returns: Nothing if the condition is true; terminates the program if false.

Error CodeCondition
E5022Assertion failed

Input Functions

input()

() -> string

Reads a line of text from stdin.

print("Enter your name: ")
mut name = input()
println("Hello, " + name)

Utility Functions

len()

(value) -> int

Returns the length of a string, array, or map.

mut name = "Hello"
println(len(name))  // 5

mut nums [int] = {1, 2, 3}
println(len(nums))  // 3

mut ages map[string:int] = {"Alice": 30, "Bob": 25}
println(len(ages))  // 2

range()

Generates a sequence of numbers for for loops. Requires at least 2 arguments.

// range(start, end) - end is exclusive
for i in range(0, 5) {
    println(i)  // 0, 1, 2, 3, 4
}

// range(start, end, step)
for i in range(0, 10, 2) {
    println(i)  // 0, 2, 4, 6, 8
}

type_of()

(value) -> string

Returns the type of a value as a string.

mut x = 42
println(type_of(x))  // "int"

mut arr [string] = {"a", "b"}
println(type_of(arr))  // "array"

size_of()

(Type) -> int

Returns the size of a type in bytes.

println(size_of(int))     // 8
println(size_of(bool))    // 1
println(size_of(float))   // 8

addr()

(variable) -> ^T

Returns a pointer to a variable’s memory address.

mut x = 42
mut ptr = addr(x)
println(ptr)  // memory address

copy()

(value) -> value

Creates a deep copy of a value. Since EZ uses copy-by-default semantics, this function is primarily useful when you want to be explicit about copying.

const Person struct {
    name string
    age int
}

mut a = Person{name: "Alice", age: 30}
mut b = copy(a)  // Explicit copy (same as just `mut b = a`)
b.age = 31
// a.age is still 30 - b is an independent copy

Note: With copy-by-default behavior, mut b = a already creates an independent copy. Use copy() when you want to be explicit about your intent, or use ref() when you need shared data.

Deep copy behavior:

  • Primitives return themselves
  • Nested structs are recursively copied
  • Arrays are copied with all elements
  • Maps are copied with all key-value pairs

ref()

(value) -> reference

Creates a reference to a value, enabling shared data between variables. The mutability of the reference depends on the variable declaration.

const Person struct {
    name string
    age int
}

mut a = Person{name: "Alice", age: 30}

// mut ref is mutable - can modify through the reference
mut b = ref(a)
b.age = 31
// a.age is now 31 - both variables share the same data

// const ref is read-only - can read but not modify
const c = ref(a)
mut val = c.age    // OK - can read
// c.age = 32      // ERROR - cannot modify through const ref

Works with all types:

// Reference to an array
mut original [int] = {1, 2, 3}
mut shared = ref(original)
shared[0] = 100
// original[0] is now 100

// Reference to a primitive
mut count = 0
mut counter = ref(count)
counter++
// count is now 1

Note: Without ref(), assignments create independent copies by default.

new()

(StructType) -> ^Type

Allocates a new instance of a struct with all fields set to their zero values. Returns a pointer to the struct.

const Person struct {
    name string
    age int
    active bool
}

mut p = new(Person)
// p is ^Person (pointer to Person)
// p^.name = ""
// p^.age = 0
// p^.active = false

Zero values by type:

  • string""
  • int, uint, float0
  • boolfalse
  • char'\0'
  • Arrays → empty array
  • Maps → empty map

c_string()

(ptr ^u8) -> string

Converts a C char* return value to an EZ string. Used with C interop.

import c"stdlib.h"

do main() {
    mut home = c_string(c.getenv("HOME"))
    println(home)
}

Sleep Functions

sleep_s()

(int) -> void

Pauses execution for the specified number of seconds.

println("Starting...")
sleep_s(2)
println("Done!")  // Printed 2 seconds later

Parameters: Number of seconds to sleep (must be non-negative).

sleep_ms()

(int) -> void

Pauses execution for the specified number of milliseconds.

sleep_ms(500)  // Sleep for half a second

Parameters: Number of milliseconds to sleep (must be non-negative).

sleep_ns()

(int) -> void

Pauses execution for the specified number of nanoseconds.

sleep_ns(1000000)  // Sleep for 1 millisecond

Parameters: Number of nanoseconds to sleep (must be non-negative).

Type Conversion Functions

Convert values between types. These are essential for working with user input, formatting output, and data transformations.

cast()

(value, type) -> value

Converts a value to the specified type. Unlike other conversion functions, cast() accepts any valid EZ type as its second argument, including sized integers and array types.

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

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

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

Parameters:

  • value — The value or array to convert
  • type — Target type (e.g., u8, int, string, [u8])

Returns: The converted value in the target type.

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”)

Error handling: Invalid conversions produce errors with details:

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

Note: cast() is technically a language keyword because the type argument is validated at check-time (before execution). See also: cast in Keywords.

int()

(value) -> int

Converts a value to an integer.

mut s = "42"
mut n = int(s)  // 42

mut f = 3.9
mut i = int(f)  // 3 (truncates)

float()

(value) -> float

Converts a value to a float.

mut n = 42
mut f = float(n)  // 42.0

mut s = "3.14"
mut pi = float(s)  // 3.14

string()

(value) -> string

Converts a value to a string.

mut n = 42
mut s = string(n)  // "42"

mut b = true
mut bs = string(b)  // "true"

char()

(int) -> char

Converts an integer (ASCII/Unicode value) to a character.

mut x = 65
mut c = char(x)  // 'A'

mut newline = char(10)  // newline character

byte()

(int) -> byte

Converts an integer to a byte (constrained to 0-255).

mut n = 65
mut b = byte(n)  // 65

mut max = byte(255)  // 255
mut wrapped = byte(256)  // Error: value out of range

Behavior:

  • Values 0-255 convert directly
  • Values outside 0-255 range produce an error
  • Useful when working with the @bytes module

to_char()

(s string, index int) -> int

Returns the Unicode codepoint at character position index (not byte position). Panics if index is out of bounds.

mut s = "日本語"
mut cp = to_char(s, 0)   // 26085 (codepoint for '日')
mut cp2 = to_char(s, 1)  // 26412 (codepoint for '本')

char_count()

(s string) -> int

Returns the number of Unicode characters (codepoints) in a string. Unlike len(), which returns byte count, char_count() counts decoded UTF-8 characters.

mut s = "日本語"
println(len(s))         // 9 (byte length)
println(char_count(s))  // 3 (character count)

mut ascii = "hello"
println(len(ascii))        // 5
println(char_count(ascii)) // 5 (same for ASCII)

Sized Integer Conversions

These functions convert values to explicitly sized integer types with range validation. They accept int, float, string, byte, or char values. Out-of-range values produce error E3022.

i8()

(value) -> i8

Converts to a signed 8-bit integer. Range: -128 to 127.

mut small = i8(42)       // 42
mut neg = i8(-100)       // -100
mut from_str = i8("50")  // 50
// i8(200)  // Error E3022: value 200 out of i8 range (-128 to 127)

i16()

(value) -> i16

Converts to a signed 16-bit integer. Range: -32,768 to 32,767.

mut val = i16(1000)      // 1000
mut neg = i16(-30000)    // -30000
// i16(40000)  // Error E3022: out of i16 range

i32()

(value) -> i32

Converts to a signed 32-bit integer. Range: -2,147,483,648 to 2,147,483,647.

mut val = i32(100000)    // 100000
mut neg = i32(-100000)   // -100000

i64()

(value) -> i64

Converts to a signed 64-bit integer. Range: -9.2 quintillion to 9.2 quintillion.

mut val = i64(1000000000)  // 1000000000

i128()

(value) -> i128

Converts to a signed 128-bit integer. Range: -2^127 to 2^127-1.

mut val = i128(1000000000000)  // 1000000000000

i256()

(value) -> i256

Converts to a signed 256-bit integer. Range: -2^255 to 2^255-1.

mut val = i256(1000000000000)  // 1000000000000

u8()

(value) -> u8

Converts to an unsigned 8-bit integer. Range: 0 to 255.

mut val = u8(200)          // 200
mut from_char = u8('A')   // 65
// u8(-1)   // Error E3022: value -1 out of u8 range (0 to 255)
// u8(256)  // Error E3022: value 256 out of u8 range (0 to 255)

u16()

(value) -> u16

Converts to an unsigned 16-bit integer. Range: 0 to 65,535.

mut val = u16(50000)  // 50000
// u16(-1)  // Error E3022: out of u16 range

u32()

(value) -> u32

Converts to an unsigned 32-bit integer. Range: 0 to 4,294,967,295.

mut val = u32(3000000000)  // 3000000000

u64()

(value) -> u64

Converts to an unsigned 64-bit integer. Range: 0 to 18,446,744,073,709,551,615.

mut val = u64(10000000000)  // 10000000000

u128()

(value) -> u128

Converts to an unsigned 128-bit integer. Range: 0 to 2^128-1.

mut val = u128(1000000000000)  // 1000000000000

u256()

(value) -> u256

Converts to an unsigned 256-bit integer. Range: 0 to 2^256-1.

mut val = u256(1000000000000)  // 1000000000000

Accepted Source Types (all sized integers)

Source TypeExample
inti8(42)
floatu16(3.14) → truncates to 3
stringi32("100")
byteu8(byte(65))
chari16('A')65

Sized Float Conversions

f32()

(value) -> f32

Converts to a 32-bit floating-point number. Truncates precision to float32 range.

mut val = f32(3.14159265358979)  // 3.1415927 (reduced precision)
mut from_int = f32(42)           // 42.0
mut from_str = f32("2.5")       // 2.5

f64()

(value) -> f64

Converts to a 64-bit floating-point number. Full double-precision range.

mut val = f64(3.14159265358979)  // 3.14159265358979 (full precision)
mut from_int = f64(42)           // 42.0
mut from_str = f64("2.5")       // 2.5

Accepted Source Types (f32/f64)

Source TypeExample
floatf32(3.14)
intf64(42)
stringf32("2.5")
bytef64(byte(65))
charf32('A')65.0

Error Handling

Error Type

The Error type represents an error value that can be returned from functions.

FieldTypeDescription
messagestringThe error message
codestringError code (empty for user errors, E-codes for stdlib errors)

Checking for errors:

mut err = validate("")
if err != nil {
    println("Error: ${err.message}")
}

error()

(string) -> Error

Creates a user-defined error. Returns an Error with .message set to the argument and .code set to empty string.

Single error return:

do validate(name string) -> Error {
    if len(name) == 0 {
        return error("name cannot be empty")
    }
    return nil
}

do main() {
    mut err = validate("")
    if err != nil {
        println(err.message)  // "name cannot be empty"
    }
}

Tuple return (value + error):

do divide(a int, b int) -> (int, Error) {
    if b == 0 {
        return 0, error("division by zero")
    }
    return a / b, nil
}

do main() {
    mut result, err = divide(10, 0)
    if err != nil {
        println("Failed: ${err.message}")
    } otherwise {
        println("Result: ${result}")
    }
}
Error CodeCondition
E7001Wrong number of arguments
E7003Argument is not a string

Quick Reference

Functions

FunctionDescriptionExample
println(values...)Print with newlineprintln("Hello", 42)
print(values...)Print without newlineprint("Name: ")
eprintln(values...)Print to stderr with newlineeprintln("Error:", msg)
eprint(values...)Print to stderr without newlineeprint("Error: ")
exit(code)Exit program with status codeexit(0)
panic(msg)Terminate with panic messagepanic("error")
assert(cond, msg)Assert condition is trueassert(x > 0, "must be positive")
input()Read line from stdinmut name = input()
len(x)Length of string, array, or maplen("hello")5
range(start, end)Number sequence for loopsrange(0, 5)0,1,2,3,4
range(start, end, step)Number sequence with steprange(0, 10, 2)0,2,4,6,8
type_of(x)Type name as stringtype_of(42)"int"
size_of(Type)Size of type in bytessize_of(int)8
addr(x)Pointer to variableaddr(myVar)^T
copy(x)Explicit deep copy of a valuecopy(myStruct) → independent copy
ref(x)Create reference for shared dataref(myStruct) → shared reference
new(Type)Allocate zero-initialized structnew(Person)^Person
c_string(ptr)Convert C char* to stringc_string(c.getenv("HOME"))
sleep_s(n)Sleep for n secondssleep_s(2)
sleep_ms(n)Sleep for n millisecondssleep_ms(500)
sleep_ns(n)Sleep for n nanosecondssleep_ns(1000000)
cast(x, type)Convert to any typecast(42, u8)42 as u8
int(x)Convert to integerint("42")42
float(x)Convert to floatfloat(42)42.0
string(x)Convert to stringstring(42)"42"
char(x)Convert int to characterchar(65)'A'
byte(x)Convert int to byte (0-255)byte(65)65
i8(x)Convert to signed 8-bit inti8(42)42 as i8
i16(x)Convert to signed 16-bit inti16(1000)1000 as i16
i32(x)Convert to signed 32-bit inti32(100000)100000 as i32
i64(x)Convert to signed 64-bit inti64(val) → value as i64
i128(x)Convert to signed 128-bit inti128(val) → value as i128
i256(x)Convert to signed 256-bit inti256(val) → value as i256
u8(x)Convert to unsigned 8-bit intu8(200)200 as u8
u16(x)Convert to unsigned 16-bit intu16(50000)50000 as u16
u32(x)Convert to unsigned 32-bit intu32(val) → value as u32
u64(x)Convert to unsigned 64-bit intu64(val) → value as u64
u128(x)Convert to unsigned 128-bit intu128(val) → value as u128
u256(x)Convert to unsigned 256-bit intu256(val) → value as u256
f32(x)Convert to 32-bit floatf32(3.14) → reduced precision
f64(x)Convert to 64-bit floatf64(42)42.0 as f64
error(msg)Create user-defined errorerror("invalid input")Error