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 pathModule path:

  • io/console.reef → module io.console
  • math/basic.reef → module math.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 — use is to test identity, not a type_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 (module A_b class c and module A class b_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