Modules
Part of: Reef Language Reference Last reviewed on version: 0.8.0
Module Structure
Modules are file-based: each .reef file is a module.
File path → Module path:
io/console.reef→ moduleio.consolemath/basic.reef→ modulemath.basic
Importing Modules
Simple Import
import io.console
Exports from io.console become available.
Local Project Modules
Import modules from your project's src/ directory:
// src/main.reef
import utils // Finds src/utils.reef
import models.user // Finds src/models/user.reef
Import with Alias
import test.framework as tf
Use with qualified names:
let runner = new tf.TestRunner()
Qualified Access
All imported symbols must be accessed with module prefix.
Function Calls
import math.basic as math
import core.str
proc main()
let x = math.abs(-5) // Call function from math module
let s = str.length("hello") // Call function from str module
end main
Type Names in Signatures (NEW in v1.2)
Use qualified types in function parameters and return types:
import graphics.core as gfx
import sys.platform.runtime as runtime
// Qualified types in function signature
fn make_point(x: float, y: float): gfx.Point
return gfx.point(x, y)
end make_point
// Qualified types as parameters. gfx.Color's r/g/b fields are uint8; there
// is no direct uint8 -> float `as` cast, so widen through int first via
// runtime.reef_int_to_float (there's no int -> float `as` cast either).
fn color_brightness(c: gfx.Color): float
let sum = (c.r as int) + (c.g as int) + (c.b as int)
return runtime.reef_int_to_float(sum) / 3.0
end color_brightness
// Multiple qualified parameters
fn create_rect(p1: gfx.Point, p2: gfx.Point): gfx.Rect
return gfx.rect_from_points(p1, p2)
end create_rect
Qualified Generic Types
import collections.list as list
import core.option as option
fn get_first(items: list.List[int]): option.Option[int]
return list.get(items, 0) // Some(elem) if present, None if index out of range
end get_first
Reusing a type name across modules
A type's identity is its defining module plus its name, so two modules
may each declare a Widget and a program may import both. Qualify at the
use site and each liba.Widget / libb.Widget keeps its own fields, its
own layout and its own GC descriptor:
// --- liba.reef ---
module liba
export
type Widget
end export
type Widget = struct
name: string
size: int
end Widget
end module
// --- libb.reef --- a DIFFERENT Widget, same unqualified name
module libb
export
type Widget
end export
type Widget = struct
size: int
name: string
end Widget
end module
import liba
import libb
fn a_size(w: liba.Widget): int
return w.size
end a_size
fn b_size(w: libb.Widget): int
return w.size
end b_size
The two are distinct types: passing a libb.Widget where a
liba.Widget is declared is a type error, not a silent reinterpretation.
This holds for every kind — struct, enum, Active Object and type alias —
and in both import orders.
An unqualified reference to a name that two imported modules both declare is not a way to pick between them; write the qualifier.
Two object classes with the same name in two modules are distinct
types, same as structs: identity is (defining module, name). Passing
one where the other is declared is a type error. (This was a loud
refusal until 0.9 Phase 8e; it is no longer an exception.)
Two consequences worth knowing before you meet them:
type_name()returns the SOURCE name, so two coexisting types with the same name both report the same string. It is a human-readable label, not an identity — useisto test identity, not atype_name()comparison.- Two declarations may not derive the same generated symbol. Symbol
components are joined with
_, and Reef identifiers may themselves contain_, so this is possible even between different modules (moduleA_bclasscand moduleAclassb_c). The compiler refuses it and names both declarations; rename one.
Export Sections
Define public API with export section:
export
fn public_function(): int
type PublicType
end export
fn public_function(): int
return helper() // Can call private
end public_function
fn helper(): int // Private (not in export)
return 42
end helper
Example Module
File: math/basic.reef
export
fn square(x: int): int
fn cube(x: int): int
end export
fn square(x: int): int
return x * x
end square
fn cube(x: int): int
return x * x * x
end cube
Usage:
import math.basic
proc main()
let s = basic.square(5) // 25 - qualified with the last path segment
let c = basic.cube(3) // 27
end main
Next: 080_TESTING.md Previous: 070_SPAWN.md