Modules and Visibility
Modules Are Files
Each .fl file is one module. There are no module declarations in source. The file path determines the module path:
| File | Module path |
|---|---|
src/main.fl | main |
src/drivers/uart.fl | drivers/uart |
src/http/client.fl | http/client |
Importing Modules
Use use to import a module:
use micro/gpio
use std/time
use drivers/uart
The last path segment is the default module name. Access exported items with dot syntax:
let led = gpio.pin(25)
time.sleep_ms(250)
uart.init()?
Aliasing with as:
use drivers/uart as debug_uart
debug_uart.write("hello")?
Use aliasing to resolve name conflicts or shorten long paths.
Visibility
Items are private by default. Use pub to export:
// src/math/bits.fl
pub fn rotl(x: u32, by: u32) -> u32 {
return (x << by) or (x >> (32 - by))
}
fn internal_helper() { ... } // not exported
The importer accesses exported items:
use math/bits
let n = bits.rotl(value, 4)
Private items are only accessible within their own module.
Official Packages
All packages ship with the toolchain. There is no external package manager. See Builtin Package Registry for the full list.
Rules
- Import paths use
/, not.or::. - Relative imports (
./foo,../foo) are not supported. - Selective imports (
use foo.{a, b}) are not supported. - Wildcard imports (
use foo/*) are not supported. - Importing a module does not inject its items into scope; you always access them through the module name.
- Unused imports are dead code. The compiler does not include unused modules in the final binary.
Deprecation
Use /// @deprecated to mark APIs that should not be used in new code:
use std/time
/// @deprecated use=std/time.sleep_ms since=1.2
pub fn delay_ms(ms: u32) {
time.sleep_ms(ms)
}
Using a deprecated item emits a lint diagnostic at the use site pointing at both the call and the deprecated declaration. The since= field records when the deprecation was introduced.