Modules and Visibility
Modules organize source code. open and seal control the visibility of declarations.
Declare a Module
module must be the first nonempty, non-comment declaration in a file:
module app.internal;
A module is not visible outside its package by default. Declare a public module with:
open module app.api;
One module can span multiple files, and a file path does not determine its module name.
Import a Module
import declarations appear after the module declaration and before other declarations:
module app;
import std.io;
import app.user;
import app.service as service;
An unaliased import introduces the target module's public names into the current file as short names. An aliased import is accessed through a qualified name:
let current = service.load();
Imports are independent in each file. An import in another file of the same module does not automatically apply to the current file.
Three Levels of Visibility
External access to a type member passes through three levels:
- Module:
sealby default; writeopen moduleto make it public. - Module member: top-level
type,spec,enum, functions, and bindings aresealby default; writeopento make them public. - Type member: fields, methods, and constructors are
openby default; writesealto hide them.
open module app.api.user;
open type User {
var name: string;
seal var token: string;
func display(): string {
return self.name;
}
}
The signature of a public API cannot expose a type with narrower visibility.
Public fit Declarations
fit is not a named declaration. Only an open fit in a public module can be exported outside its package; any other fit applies only within its declaring module.
open module app.extensions;
open fit User {
func greeting(): string {
return "Hello, " + self.name;
}
}
A consumer must import app.extensions before using the extension.
Avoid Name Conflicts
Names from multiple imports become ambiguous only when the same bare name is actually used. Prefer import aliases or full module paths to resolve a conflict:
import app.first as first;
import app.second as second;
let a = first.User {};
let b = second.User {};