imports
α1imports
ferrule uses a rust-like module system. files are modules, directories with mod.fe are submodules.
project structure
| file | purpose |
|---|---|
Package.fe | package manifest (like cargo.toml) |
ferrule.lock | lockfile for dependencies |
src/main.fe | binary entrypoint |
src/lib.fe | library root (optional) |
src/parser/mod.fe | submodule definition |
src/parser/lexer.fe | file in submodule |
tests/*.fe | test files |
directories with mod.fe become submodules. the module path matches the file path: src/parser/lexer.fe is parser.lexer.
visibility
function helper() { } // default: module-private
pub function process() { } // public to package
pub export function api() { } // public to everyone (lib.fe only)local imports
// from local modules
import parser { Parser, ParseError }; // from src/parser/mod.fe
import utils { helper }; // from src/utils.fe
// re-export
pub import lexer { Token }; // re-export from lexer.febasic import
Import by name (resolved via Package.fe manifest and ferrule.lock):
import time { Clock };
import mylib.http { get, post };Capability-Gated Imports
An import can declare that loading requires build-time capability permission:
import time { Clock } using capability time;
import mylib.http { get, post } using capability net;This is build-time capability gating — the build tool must have permission X to load the import.
At runtime, capabilities are still passed explicitly as values (no ambient authority).
Content-Addressed Imports
For critical dependencies, import by explicit content address:
import store://sha256:e1f4a3b2... { io as stdio } using capability fs;Direct hash imports:
- pin to exact versions
- bypass name resolution
- provide maximum reproducibility
Import Resolution
Name-based imports are resolved:
- Check
Package.femanifest for declared dependencies - Look up content address in
ferrule.lock - Fetch from cache or registry
- Verify content hash
Aliasing
Rename imports with as:
import net.http { Client as HttpClient };
import store://sha256:... { io as stdio };Selective Imports
Import specific items:
import net.http { get, post, Client };Or import the module namespace:
import net.http;
// use as: http.get(...), http.Client, etc.Derivation Mutation
Imports can override derivation parameters, producing a different content address:
import stdlib { io } with { features: { simd: false } };The with { ... } clause:
- modifies the imported package's build configuration
- creates a variant with a different content address
- the lockfile records both original and mutated addresses
Example
package my.app;
// standard imports
import time { Clock } using capability time;
import net.http { Client, Response } using capability net;
// pinned critical dependency
import store://sha256:abc123... { crypto } using capability ffi;
// modified derivation
import stdlib { io } with { features: { debug: true } };