Stone Modules: Imports, Exports, and Re-Exports

Stone's module system is designed to be:

  • static — all module paths are resolved at compile time
  • explicit — nothing is imported or exported unless declared
  • clean — no namespace pollution or implicit bindings
  • path-based — module hierarchy is expressed using /
  • minimal — only essential forms for defining and exposing module APIs

A Stone module is always a single .stn file. Folders may contain many modules, but each file is an isolated compilation unit.

1. Exports

The export keyword marks top-level bindings as part of the module's public API.

export fn calcVelocity(d, t) = d / t
export fn calcAcceleration(dv, dt) = dv / dt

export constant = 42

Bindings not explicitly exported remain private.

Export Rules

  • Only top-level bindings may be exported.
  • Exported names must be unique within the module.
  • Exported bindings must not be rebound.
  • The module's public API is exactly the set of names preceded by export.

2. Import Paths

Module paths mirror directory structure using /. Module references never use .stn extensions.

Stone supports two path forms:

Identifier Paths (ModulePath)

Standard paths using identifiers separated by /:

physics/mechanics/SpeedCalcUtility
math/statistics/variance

Quoted Paths (ModuleLocator)

String literals that allow spaces and special characters in folder/file names:

import "core logic/math/stats"
import "my modules/utilities"

Quoted paths must be string literals—no interpolation or concatenation allowed.

Import Path Rules

  • Paths beginning with ./ or ../ are relative.
  • All others are absolute.
  • When importing a module without an alias, the final path segment becomes the namespace name.
  • Quoted paths allow folder and file names with spaces.

Examples:

import math             // absolute
import physics/rigid    // absolute

import ./helpers        // relative
import ../shared/utils  // relative

// Quoted paths (allows spaces)
import "core logic/math/stats"
import "my modules/utilities"

Directory + Inferred Filename

When using a quoted path with a single selective import, Stone infers the filename from the import name:

// This resolves to "core logic/math/stats.stn"
import stats from "core logic/math"

// Equivalent to:
import stats from "core logic/math/stats"

This rule only applies when:

  • The path is a quoted string literal
  • There is exactly one import specifier

Multiple specifiers require an exact path:

// Must point to an actual file, no inference
import a, b from "some/dir"

3. Import Forms

Stone provides two import forms:

  • Selective import — import specific exported names
  • Namespace import — import the entire module as a namespace binding

These forms preserve clarity without polluting the local scope.

3.1 Selective Imports

Brings specific exported names into the current scope.

Syntax

import name1, name2 from path/to/module

// With quoted paths (allows spaces)
import mean from "core logic/math/stats"
import stats from "core logic/math"           // infers stats.stn

Aliased

import name1 as local1, name2 as local2 from path/to/module
import mean as avg from "core logic/math/stats"

Example

import calcVelocity as vel,
       calcAcceleration as accel
from physics/mechanics/SpeedCalcUtility

v = vel(100, 9.58)
a = accel(10, 2)

Rules

  • Names must exist in target module's exports.
  • Aliasing is optional.
  • Selective imports introduce names into local scope.
  • Single-specifier imports from quoted paths use directory inference.

3.2 Namespace Imports

Imports the entire module as a namespace.

Syntax

import path/to/module as Alias

// With quoted paths
import "core logic/math/stats" as mathLib

Automatic alias

If no alias is provided, the last path segment becomes the namespace.

import physics/mechanics/SpeedCalcUtility
SpeedCalcUtility.calcVelocity(5, 2)

// With quoted paths (auto-binds as 'stats')
import "core logic/math/stats"
stats.mean([1, 2, 3])

Rules

  • Only the namespace binding is introduced.
  • Exported names appear as fields.
  • Namespace objects cannot be rebound.
  • For quoted paths without alias, the last path segment becomes the namespace name.

4. Combined Imports

Selective and namespace imports may coexist:

import physics/mechanics/SpeedCalcUtility as Speed
import calcVelocity as vel from physics/mechanics/SpeedCalcUtility

This is allowed but rarely needed.

5. Standard Library Modules

Stone provides a standard library with modules for common operations. No std/ prefix required.

Note: Standard library modules must be explicitly imported. They are separate from the built-in functions (like print, len, sqrt, sin) which are auto-imported and always available.

// These require imports:
import hypot, clamp from math
import zeros, dot from linalg
import mean, std from stats

Quick Examples

// Math utilities
import PI, hypot, clamp from math
dist = hypot(3, 4)          // 5

// Array operations
import linspace, reshape from array
t = linspace(0, 1, 100)

// Linear algebra
import dot, solve, eigvals from linalg
x = solve(A, b)

// Statistics
import mean, std, corr from stats
avg = mean(data)

// Signal processing
import fft from dynamics/fft
import hamming, filter from signal

// Control systems
import tf, step, bode from dynamics
G = tf([1], [1, 1])

6. Re-Exports (Exporting From Another Module)

Stone extends export to allow re-exporting bindings from another module. This enables clear, composable public APIs without requiring additional keywords.

Two re-exporting forms exist:

  • Selective re-export — export specific names from another module
  • Namespace re-export — export an entire module as a namespace

Re-exports do not introduce names into local scope. They only contribute to the module's exported API.

6.1 Selective Re-Export

export add, sub from ./math

Aliased:

export avg from ./math as calcAverage

Multiple names:

export add, sub, avg from ./math
export add as plus, sub as minus from ./math

Rules:

  • Each forwarded name must exist in the target module's exports.
  • The exported name (or alias) must not conflict with another export.
  • Re-exported names do not appear in local scope unless separately imported.

6.2 Namespace Re-Export

Exports an entire module as a namespace.

export ./math as math

Without alias:

export ./physics/mechanics/SpeedCalcUtility

Exports a namespace named SpeedCalcUtility.

Rules:

  • The exported namespace name must not conflict with another export.
  • The namespace re-export does not introduce a local binding unless explicitly imported.

7. Barrel Modules (main.stn)

A folder may define a barrel module—typically named main.stn—to act as the folder's public API entrypoint. The barrel composes internal modules using re-exports.

Example folder structure:

utils/
  main.stn
  math.stn
  string.stn
  doc.md

Example main.stn:

# Namespace re-exports
export ./math as math
export ./string as string

# Selective helpers
export add, sub from ./math
export avg from ./math as calcAverage

export trim from ./string
export pad from ./string as padLeft

Consumer use:

import ./utils as utils

x = utils.add(1, 2)
y = utils.calcAverage([1, 2, 3])
z = utils.math.sub(10, 3)
s = utils.string.trim("  hi  ")

Barrels:

  • define controlled, stable package APIs
  • prevent namespace leakage
  • keep internal modules clean and focused

8. Unsupported Forms

To preserve clarity and prevent ambiguous resolution, Stone does not support:

  • wildcard imports (import *)
  • wildcard re-exports (export * from ...)
  • default exports
  • dynamic module paths
  • dot-separated module paths (a.b.c)
  • extracting import syntax ({a, b})

All module relations remain static and explicit.

9. Summary

FeatureSyntax
Export local bindingexport fn f(...), export x = value
Selective importimport a, b as B from path/module
Namespace importimport path/module as Alias
Auto namespace nameimport path/module
Quoted path importimport "path with spaces"
Directory inferenceimport stats from "dir"dir/stats.stn
Selective re-exportexport a, b as B from path/module
Namespace re-exportexport path/module as Alias

Stone's module system is:

  • simple
  • explicit
  • immutable
  • static — all paths resolved at compile time
  • consistent across large and small codebases