Modules

Modules are loaded from .dn files. The standard library is a set of such modules (see the Standard library section).

Importing

There are three import forms, and they interoperate freely:

import math;                          // plain: use as `math.square`
import matrix as m;                   // alias: use as `m.Vector`
from matrix import Vector, Matrix;    // selective: use `Vector` unqualified

Selective imports are comma-separated and may span several lines. Importing an unknown symbol, a private symbol, or reusing an alias that collides with another module is a compile-time error that names the offending symbol.

Module declaration

A file may open with a module name; declaration that names the unit for documentation and diagnostics. It is optional and, in this first version, does not bind the file to a directory layout — modules are located by file name on the search path.

module geometry;

export record Point {
    export x: int,
    export y: int,
}

export fn manhattan(a: Point, b: Point): int { /* ... */ }

Export visibility

If a module contains any explicit export, only exported functions, constants, records, choices, and contracts are visible through module.name; everything else stays private to the module. Record fields and methods are private across module boundaries unless the member itself is marked export.

export const ANSWER: int = 42;

fn hidden(): int { return 7; }         // private to this module

export fn public(): int { return hidden(); }

Receiver methods declared by a module become available on values of the receiver type after import — for example, import array; enables both array.first(xs) and xs.first().