Modules
A program can be split into files. import loads another file, named
relative to the importing file and without the .cz extension:
// main.cz
import "shapes"
print(area(square(3)))// shapes.cz
pub struct Square do
int side
end
pub func square(int side) Square do
return Square(side)
end
pub func area(Square s) int do
return s.side * s.side
endA name may include directories, as in import "lib/text" or
import "../common", but it must be relative: absolute paths and drive
letters are rejected. Imports are top-level only. Each file is loaded once,
however many files import it, so imports may repeat or form cycles.
Declarations can be used in any order. Only the main file, the one given to
cuarzo, may contain top-level statements; imported files hold declarations
and imports.
Public and private names
A declaration marked pub can be used by the files that import its file;
any other declaration is private to its file. A file sees its own
functions, structs, enums, interfaces, and constants, and the public ones of
the files it imports. Using a private name of another file is an error that
says so, and using a name of a file that is not imported is an error that
names the file. Private names never clash, so two files may each have a
private helper; two public names that one file sees together cannot be the
same. Methods belong to their type, wherever it is used.
An import does not pass the imported file's names on: a file that imports
a, which imports b, sees a's public names but not b's. pub import
passes them on, so a module can gather others under one name:
// geometry/index.cz
pub import "shapes" // geometry/shapes.cz
pub import "angles"
pub func describe(Square s) str do
return f"a square of side {s.side}"
endA folder with an index.cz is a module too: when there is no geometry.cz,
import "geometry" loads geometry/index.cz.
import "x" as name gives the imported file a name instead. Its declarations
are then reached only through that name, so they never clash with the
importer's:
import "std/term" as term
import "shapes" as shapes
// std/term has a `table` too, but here it is `term.table`.
func table() str do
return "my table"
end
shapes.Square s = shapes.square(3)
print(shapes.area(s), table())
print(term.paint("done", "green"))name.x reaches the public names of the file and those it passes on with
pub import. It works for functions, constants, structs, and enums, in expressions,
in types such as shapes.Square[] or Option[shapes.Square], and in match
patterns such as when shapes.Kind.ROUND. Two modules imported with as may
declare the same names. The name given cannot be used for a variable or
parameter in that file, and two imports in one file cannot share a name.
A name that starts with std/ imports a module of the
standard library, such as import "std/term". The
compiler carries these modules, so they work from any directory. A file
that imports a module and wants its names imports it itself, as with any
other module.