Modules and imports
import for stdlib, use for files or directories, and inline module blocks for declaring sub-namespaces.
Summary
Standard library modules require an explicit import math; the semantic analyzer rejects references to stdlib names without a matching import. File imports use use "path/to/file.xs"; the module name defaults to the filename stem. Both forms accept as alias and selective imports with from mod import { name }. Importing a directory with use "dir/" loads all .xs files in it. Inline modules are declared with module Name { ... } and accessed by name.
Canonical
Importing Standard Library Modules
import math
println(math.sqrt(16)) -- 4.0
println(math.PI) -- 3.141592653589793
-- with alias
import math as m
println(m.sqrt(16)) -- 4.0
-- selective import
from math import { sqrt, PI }
println(sqrt(25)) -- 5.0
println(PI) -- 3.141592653589793Importing Files
-- use "path" imports a file as a module (namespace derived from filename)
use "utils.xs"
println(utils.helper())
-- with alias
use "utils.xs" as u
println(u.helper())
-- selective import
use "utils.xs" { helper, VERSION }
println(helper())For directories, use "dir/" imports all .xs files in the directory.
Exporting Names
A file's public surface is whatever its export { ... } list names. Everything else stays file-local. The list goes wherever you want at the top level of the file (typically last); names can be aliased with as to publish under a different spelling.
-- math_utils.xs
fn double(x) { return x * 2 }
fn triple(x) { return x * 3 }
fn helper(x) { return x + 1 } -- not exported
let TAU = 6.2831
let seed = 42 -- not exported
struct Point { x: int, y: int }
fn rgb_to_hex(r, g, b) { ... }
export { double, triple, TAU, Point, rgb_to_hex as rgbToHex }use "math_utils.xs"
println(math_utils.double(5)) -- 10
println(math_utils.TAU) -- 6.2831
println(math_utils.helper) -- null (not exported)
println(math_utils.rgbToHex(255, 0, 0))-- callable under the alias
println(math_utils.rgb_to_hex) -- null (alias is the only public name)A file with no export { ... } list at all falls back to exposing every top-level binding -- scripts and quick experiments work without ceremony. Add an export list and strict filtering kicks in.
There is no pub modifier and no @export decorator. The export { } list is the one and only mechanism for marking a public surface.
Declaring Modules Inline
module Utils {
fn double(x) { return x * 2 }
fn triple(x) { return x * 3 }
}
println(Utils.double(5)) -- 10
println(Utils.triple(4)) -- 12