---
{
"@context": "https://nxdlang.org/schema",
"doc_id": "TE010",
"title": "",
"description": "",
"layer": "Examples",
"category": "Tiny Examples",
"keywords": [],
"doc_version": "1.0",
"status": "active"
}
---
# TE0010 — Multi‑Module (Tiny Layer)
# Problem Statement
Demonstrate NXD’s multi‑module system:
- Two modules: `math.ops` and `app.main`
- `EXPORT` controls visibility
- `IMPORT` brings symbols into scope
- `INIT` blocks run in dependency order
- Namespaces follow dot‑notation
- No cyclic INIT dependencies
This example shows a clean two‑module project where `app.main` imports and uses `math.ops`.
---
# Canonical NXD (≤30 lines)
```nxd
MODULE math.ops
EXPORT FUNC ADD
EXPORT FUNC MUL
INIT:
PRINTLN("math.ops init")
FUNC ADD(X: int, Y: int): int:
RETURN X ADD Y
FUNC MUL(X: int, Y: int): int:
RETURN X MUL Y
MODULE app.main
IMPORT math.ops
INIT:
PRINTLN("app.main init")
FUNC MAIN():
LET A SET ADD(3, 4)
LET B SET MUL(A, 10)
PRINTLN(B)
RETURN none
```
---
# Semantic Notes
- `EXPORT FUNC ADD` and `EXPORT FUNC MUL` make these functions public.
- `IMPORT math.ops` brings exported symbols into `app.main`.
- `INIT` blocks run in topological order:
1. `math.ops`
2. `app.main`
- Dot‑notation module names map cleanly to file paths.
- No cyclic INIT dependencies exist.
- Left‑to‑right evaluation ensures `MUL(A, 10)` evaluates `A` first.
- Backend lowering must preserve module boundaries and visibility.
---
# Backend Outputs
### Nim
```nim
# math/ops.nim
static:
echo "math.ops init"
proc add(x, y: int): int = x + y
proc mul(x, y: int): int = x * y
# app/main.nim
import math/ops
static:
echo "app.main init"
proc main() =
let a = add(3, 4)
let b = mul(a, 10)
echo b
```
---
### Elixir
```elixir
# math/ops.ex
defmodule Math.Ops do
@on_load :init
def init(), do: IO.puts("math.ops init")
def add(x, y), do: x + y
def mul(x, y), do: x * y
end
# app/main.ex
defmodule App.Main do
@on_load :init
def init(), do: IO.puts("app.main init")
def main() do
a = Math.Ops.add(3, 4)
b = Math.Ops.mul(a, 10)
IO.puts(b)
end
end
```
---
### D
```d
// math/ops.d
module math.ops;
static this() {
writeln("math.ops init");
}
int add(int x, int y) { return x + y; }
int mul(int x, int y) { return x * y; }
// app/main.d
module app.main;
import math.ops;
static this() {
writeln("app.main init");
}
void main() {
int a = add(3, 4);
int b = mul(a, 10);
writeln(b);
}
```
---
# Audit Rules
- Module names must match file paths.
- Exports must be explicit; unexported symbols remain private.
- INIT blocks must execute in dependency order.
- Imports must not create cyclic INIT dependencies.
- Backend lowering must preserve namespace structure.
- No implicit conversions allowed in arithmetic.
---
These examples form the **canonical foundation** of NXD:
- CRUD
- Concurrency
- Channels
- Ownership
- Security
- Error Handling
- Generics
- Runtime
- Compiler Plugin
- Multi‑Module
Documentation