Каждый файл — один модуль; entry и его transitive import closure образуют single-root compilation unit с visibility private-by-default.
Политика
Imports составляют top-level prologue. import a.b связывает последний segment как namespace, возможно с as; import a.b { name, other as local } выбирает exported names. Inline export применяется к одному объявлению или допустимому binding. Module path — dotted identifiers, отображаемые на точные Unicode-scalar пути под root. Namespace — compile-time resolution object для одного exported member или qualified type, не runtime value.
Определённое поведение
Проверяются только entry и transitive closure. Каждое import edge участвует в запрете циклов. Imported modules инициализируются один раз в нормативном dependency order до entry; const не добавляет runtime step, forward/self runtime-binding references в imported initializer блокируются статически. Imported module допускает declarations/bindings, но не runtime-bearing free statements. Имена private без export, imported bindings read-only, selected nominal names сохраняют defining identity.
Ограничения и явный отказ
Отклоняются side-effect-only import, use, string/template paths, alias вместе с selection, export lists, wildcard, re-export, export-site rename, export let mut, duplicate imports, cycles, выход из root, private access и namespace-qualified nominal brace construction. Root один, уровней visibility два, package manifest semantics и implicit parent module отсутствуют.
Отложенная граница
Package manifests, dependencies, registries, version constraints, multi-root, package visibility, re-export, side-effect imports, type-only cycle exceptions и foreign-syntax module forms отложены. Будущий interop остаётся module-granular и маркируется на producer/build boundary; import syntax остаётся обычным Topaz.
Пример
import math { add as sum }
import text.format as fmt
export function total(left: int, right: int) -> int {
return sum(left, right)
}
let label = fmt.number(total(2, 3))