Open Manual

<!-- nytrix-doc: {"audience":"user","featured":true,"group":"spec","order":10,"summary":"Rules for source files, imports, modules, profiles, and entry points."} -->

Units

This page defines source-file structure. Use Programs

for project workflow.

File forms

FormMeaning
ScriptA file without module; its top-level expressions execute.
ModuleA file beginning with module name; it exports declared public names.
Generated moduleA module emitted by compile-time generation.

The module declaration follows the header comments. A source unit has one

module declaration at most.

;; Keywords: source module
module sample.units

pub fn answer() int { 42 }

A file is both a script and a module when it declares module and also keeps

direct-run statements in a #main block. Imported users see only the exports;

direct execution runs the startup block.

Module declaration forms

FormMeaning
module name *Export every pub declaration in the file.
module name (a, b, c)Export exactly a, b, c; pub elsewhere is ignored by imports.
module name { export group(a, b) internal(_helper) }Grouped exports; internal names stay private.
module name generated from Spec { key = value emit make_backend(Contract) }Attach compile-time configuration and emit generated declarations.

The export group(...) form names a profile. A use module:profile selects

the core surface plus that profile.

module sample.groups {
   export core(run)
   export debug(dump_state)
   internal(_state)
}

use sample.groups:debug

Imports

FormBinding
use std.coreImports the module namespace.
use std.core as coreImports it under an alias.
use std.core: printImports selected exported names.
use mod:debugSelects the debug profile when that module provides one.

Imports resolve before ordinary declarations. An unresolved module or export is

a diagnostic. Imports do not execute an entry point.

use std.core: assert
use std.math as math

assert(math.sqrt(9) == 3, "imported name")

Import forms apply to relative files as well as module paths:

use "./parser.ny" as parser
use "./parser.ny" (parse_node)
use "./parser.ny":debug

Exports and visibility

pub exports a declaration. Declarations without pub remain private to the

module. Selected imports may name only exported declarations.

module sample.visibility

pub def public_value = 1
def private_value = 2

Entry points

#main { body } gates body to the program entry path. It is equivalent to:

if comptime { __main() } { print("entry") }

The gate evaluates false for import-time evaluation. __main() is a

compile-time predicate; it is not a user-defined replacement for an entry

function.

A file without a module declaration runs its top-level statements directly on

the program entry path. A file with module runs only the #main body on the

entry path; imports of that module never execute that body.

Generated source

Generated source must declare its module identity when it forms a module. The

generated declaration participates in the same import and export rules as a

handwritten module. See compile-time execution.

Diagnostics

ConditionResult
More than one module declarationSource-unit diagnostic.
Import after a declaration requiring resolved importsSource-order diagnostic.
Missing selected exportImport diagnostic naming the module and export.
Profile unavailableImport diagnostic naming the requested profile.
module name (a, b) selects a missing nameExport diagnostic naming the requested name.

Related