Documentation menu
Language

Modules

Every .sz file is a module. export marks what other files may use, and import pulls those exports into the current scope.

export and import

Prefix a function with export to make it reachable from another file:

// src/math.sz
export fn int double(int n) { return n * 2 }
export fn int quadruple(int n) { return double(double(n)) }

Then import the module by path, without the extension:

// index.sz
import "src/math"

out double(5)      // → 10
out quadruple(5)   // → 20

Imported names land directly in the importing scope — there is no namespace object and no as alias. import "src/math" loads src/math.sz.

Paths are relative to the importing file

Import paths resolve against the directory of the file doing the importing, not the project root. This is the usual stumbling block in a package with index.sz at the root and modules under src/:

// index.sz       →  import "src/parser"    ✅
// src/lexer.sz   →  import "parser"        ✅  sibling, simple name
// src/lexer.sz   →  import "src/parser"    ❌  looks for src/src/parser.sz

The wrong form often passes your own tests — those run with the repo as the working directory, which happens to resolve it — and only fails once someone consumes the package by name.

Importing a package by name

A bare name is looked up across several roots in order: the app's directory, the current working directory, <cwd>/packages, SEREZ_HOME, the directory of the sz executable, and ~/.serez/packages — trying <root>/<pkg>/index.sz at each:

import "serez-ui"

Export every function reached from another file

This is the one rule that bites hardest. A function without export is invisible when an exported function that calls it is invoked from a different module — even though both live in the same file. The error shows up at the call site, not at the import:

// src/math.sz
fn int helper(int n) { return n + 1 }              // not exported
export fn int useHelper(int n) { return helper(n) }
// index.sz
import "src/math"
out useHelper(5)

// ❌ ERROR: Variable not found: helper
//     called from 'useHelper'

The fix is export fn int helper(...). It applies transitively: if a calls b calls c, all three need export — private helpers included.

Classes vs functions

Classes become visible globally once their module is imported. Functions are bound per importer, so import order matters when two modules export the same name — the last import wins.