rokdocs
v0.1

5. Variables / modules / visibility / packages overview

This part covers rok's name space. Its goal is to define where variables are visible, how modules are grouped, how visibility levels work, and where the boundaries between packages lie.

Contents

The four levels of the name space

The name space has four levels:

package
  └── module
        └── item
              └── local variable

Containment runs top to bottom. A package has many modules, a module has many items (functions, types, traits, const, static), and an item (in particular a function body) has many local variables.

The boundary rules for each level are defined in the following documents.

Packages: the largest unit

The package defined in source units is the outermost level of the name space. Each package is identified by a content-based hash.

All items in the same package belong to the same code-authority domain. This is why the orphan rule of impl applies per package.

Modules: grouping units within a package

A package has many modules. Each module is either a single file (foo.rok) or a body file plus a folder of the same name (foo.rok + foo/). This is the same model as Rust 2018+. The detailed rules are defined in modules.

my_pkg/
└── src/
    ├── lib.rok                  <- root module body
    ├── geom.rok                 <- geom module    (single-file: geom.rok)
    ├── parsing.rok              <- parsing module body
    └── parsing/                 <- parsing's submodules
        ├── lexer.rok                parsing::lexer
        └── parser.rok               parsing::parser

Items: named definitions within a module

Each module has items: functions, types, traits, impl blocks, const, static, and other module declarations.

Every definition of a function declaration, struct, enum, trait and impl is an item within a module.

Local variables: variables within functions / blocks

Within functions, blocks and other expressions, local variables are declared with the let keyword (keywords).

fn area(r: f64) -> f64 {
    let pi = 3.14159f64;          // local variable
    pi * r * r
}

The visibility scope of a local variable is determined per block of a block expression. The detailed rules are defined in variable declarations.

Visibility: exposing items

Each item has a visibility. The visibility level (visibility) determines how far the item is visible.

private (default)    within the same module only
pub(sub)             within submodules only
pub(pkg)             within the same package only
pub                  also from external packages

Name resolution rules

Determining which item a name in the code refers to is called name resolution.

It considers the following. First, items locally visible in the current module are candidates. Second, external items imported with use (use) are also candidates. Third, the automatically imported rok::** (standard library tiers) is consulted as well. Finally, a visibility check is performed, and only visible items remain as candidates.

Name resolution happens at compile time. Method dispatch on dynamic slots happens at runtime, but resolving the name itself is always completed at compile time.

Edit this page on GitHub