5. Modules and imports¶
Once your program is more than one file, you’ll split it into modules and import what you need.
A tiny multi-file project¶
Create a folder:
my_project/
├── main.incn
└── strings.incn
strings.incn:
pub def shout(s: str) -> str:
return s.strip().upper()
main.incn:
from strings import shout
def main() -> None:
println(shout(" hello "))
Run from my_project/:
incan run main.incn
Visibility: exporting with pub¶
By default, definitions are module-private (only usable inside the same .incn file).
Prefix a declaration with pub to export it so other modules can import it.
Coming from Python?
In Python, most top-level definitions are effectively importable.
In Incan, you typically make the intended “public API” of a module explicit with pub.
For more detail on pub (including how it affects model/class fields), see: Models & Classes.
Exporting an alternate name¶
Use a symbol alias when a module should expose another name for the same callable or type:
# strings.incn
pub def shout(s: str) -> str:
return s.strip().upper()
pub yell = shout
# main.incn
from strings import yell
def main() -> None:
println(yell(" hello "))
yell is an alias of shout, not a copied function body. The target must already be a supported declaration, and a public alias must target a public symbol. For the full contract, see Symbol aliases.
Import styles¶
Incan supports two styles you can mix:
# Python-style
from strings import shout
# Rust-style
import strings::shout
Navigating folders (.., super, crate)¶
The reference documents how parent/root paths work:
- Parent:
..(Python-style) orsuper::(Rust-style) - Project root:
crate
See: Imports and modules (reference).
Module-owned state with static¶
Sometimes a module does not just export functions and types.
Sometimes it owns long-lived runtime state.
That is what static is for:
This example shares live runtime state across module boundaries with pub static:
pub static hits: int = 0
pub def record_hit() -> None:
hits += 1
from counters import hits, record_hit
def main() -> None:
record_hit()
record_hit()
println(hits)
This prints 2.
Important:
staticis runtime state, not a compile-time constant- imported
pub staticnames refer to the same live storage staticalways needs an explicit type and initializer
Use const for baked compile-time data (constants).
Try it¶
- Add another function in
strings.incn(for examplewhisper). - Mark it
puband import it intomain.incn. - Call both functions.
One possible solution
# strings.incn
pub def shout(s: str) -> str:
return s.strip().upper()
pub def whisper(s: str) -> str:
return s.strip().lower()
# main.incn
from strings import shout, whisper
def main() -> None:
println(shout(" hello ")) # outputs: HELLO
println(whisper(" HELLO ")) # outputs: hello
What to learn next¶
- Explanation: Imports and modules
- Explanation: Module static storage
- How-to: Imports and modules (how-to)
- How-to: Module state
- Reference: Imports and modules (reference)
- Reference: Static storage
Next¶
Back: 4. Control flow
Next chapter: 6. Errors (Result/Option and ?)