Alpha. Vary is under active development and not ready for production use. Syntax, APIs, performance, and behaviour may change between releases.
Modules and imports
Each .vary file is a module and directories are packages. You use imports to pull in functions, classes, and other definitions. The compiler resolves the full dependency graph at compile time.
The prelude
A small set of types and functions is available in every file without imports. Everything else requires an explicit import statement.
Prelude types (always available):
| Category | Types |
|---|---|
| Primitives | Int, Float, Bool, Str, None |
| Collections | List, Dict, Set |
| Results | Result, Ok, Err |
| Special | Never |
Prelude functions (always available): print, input, len, str, int, float, bool, range, abs, min, max, sorted, map, filter, reduce, any, all, sum, and others.
Non-prelude types require imports. If you use Json, Path, Clock, Rng, Decimal, or any other stdlib type, you must import the owning module. The compiler tells you which module to import:
error: Type 'Json' requires 'import json'
Common imports:
| Type | Required import |
|---|---|
Json, JsonValue, JsonError | import json |
Decoder, DecodeError | import json |
Path | import path |
ReadPath, WritePath, DirPath | import fs |
Clock, Duration, Date, Instant | import time |
Rng | import random |
TemplateEngine, TemplateError | import template |
HttpResponse, HttpError | import http |
Decimal | import decimal |
Money | import money |
Url | import url |
CryptoHash | import crypto |
Command, ProcessResult | import process |
This makes dependencies visible: you can tell which modules a file uses by reading its import block.
Imports
import math_utils
import math_utils as m
from math_utils import square, cube
from math_utils import square as sq
Modules are files. A file math_utils.vary defines module math_utils.
Access control
Names starting with _ are private and not exported:
def public_func() -> Int {
return _helper()
}
def _helper() -> Int {
return 42
}
Controlling exports
By default, all non-underscore names are exported. Use __all__ to restrict:
let __all__ = ["public_func", "CONSTANT"]
def public_func() -> Int {
return 42
}
def internal_func() -> Int {
return 0
}
let CONSTANT: Int = 100
Only public_func and CONSTANT are importable from this module.
Relative imports
Use dots to import relative to the current file's directory:
from .sibling import helper # same directory
from ..parent_module import Config # parent directory
from .subpkg.util import format # subdirectory
One dot (.) means the current directory, two dots (..) means the parent, and so on. Relative imports only resolve within the project - they cannot escape the module root.
Module root discovery
The compiler finds the module root by walking up from the entry file until it finds a vary.toml file or the filesystem root. All absolute imports (e.g., import utils) resolve relative to this root. If no vary.toml exists, the entry file's directory is the root.