Modules and packages
One file is one module
Directories form the path. Declarations are private to their module unless marked pub:
use std.io; // module namespace: io.read_fd(..)
use std.io.{read_fd, write_fd}; // items directly
use std.io.{read_fd as read}; // an item under another name
use std.io as sio; // a module under another name
use std.str.*; // all public itemsstd resolves to the standard library; other roots resolve relative to the entry file's directory and to the package root. Cycles are an error. A program is a module tree with exactly one fn main in its root module.
One name, one meaning. What happens when two bindings want the same name is fixed by the form of the import, never by order:
| The two bindings | What happens |
|---|---|
use a.{f} and use b.{f} | error at the second import |
use a.{f} and fn f here | error at the import |
use a.* and fn f here | the declaration wins |
use a.* and use b.{f} | the item import wins |
use a.* and use b.*, both f | error where f is used, and only there |
A type is a name of its module: two modules may each declare a pub struct S; an importer that needs both imports each under an alias, inside the braces.
Reexports: pub use
pub use imports a name and makes it a public name of the module that writes it, so a package can present one front door whatever files its code lives in:
// shapes.talor - the package's root module
pub use shapes.geometry.{Point, origin}; // items
pub use shapes.geometry.{Point as P}; // an item under another name
pub use shapes.geometry.*; // every public item of the module// main.talor
use shapes.{Point, origin};The reexported name is the same declaration, not a copy: shapes.Point and shapes.geometry.Point are one type. Only public items can be reexported, and only items: pub use a.b; naming a module is refused.
A package on disk
A package is a directory with a talor.mod file at its root. The manifest is lines:
name myapp
version 0.1.0
program myapp src/main.talor
require greet file:// ../greet
require util path libs/util| Directive | Meaning |
|---|---|
name | one identifier |
version | <major>.<minor>.<patch> |
program | an executable and the module it starts at |
library | the module an importer of this package reaches |
require | a dependency's name, the source it comes from, and what that source takes |
registry | one URL: the default registry for this package |
warn | a warning category and the level it is reported at |
The sources are path (a directory in the package), file:// (a path anywhere, copied into the cache), git and registry - those last two need the network, and packages says where that stands - and workspace, which takes nothing: the package depends on the name, and the build it is part of says where the name comes from, through the root package's own require of it. A require written twice is refused.
A package declares every package it uses: a use whose first name is neither one of the package's own modules nor std needs a require of that name.
A use a.b.c names the file a/b/c.talor, searched in order: beside the file that wrote the use, under the root of the require whose name is a, then under each -L root. First file that exists wins.
The commands
talor build [<dir>] [--check] [--release] [--target <triple>] [--target-os <name>]
talor run <file.talor> [-L <dir>] [--release] [-- args...]
talor test <file.talor> -o <out.ll>buildreads the manifest and links everyprograminto<dir>/build/; the link is skipped when the IR did not change. With notalor.lockit resolves therequirelines and writes one, and with a lock it reads it and never changes it.--checkcompiles and does not link.runis one program, compiled and run in one step: the command answers what the program answered,--ends the command's arguments and begins the program's, and nothing survives the run.- The closed set of targets is
linux/macos/windowsonx86_64/aarch64.--target-osis how a declaration under#[os("macos")]is compiled on a Linux machine.