Imports and Exports¶
Imports publish selected module bindings directly into the current source environment. Exports are explicit so implementation helpers remain private.
Import a Module¶
> import: profiles
= `get_profile("Ada")`
The imported module must explicitly export get_profile. Imports do not bind a
profiles namespace and do not expose unexported names. The backtick expression
preserves the native Profile; an angle call would render it to str.
Explicit Exports¶
In profiles.kedi:
~Profile(name: str, id: int)
@get_profile(name: str) -> Profile:
= `Profile(name=name, id=1)`
@normalize_internal(name: str) -> str:
= `name.strip()`
[profile_id: int] = `1`
> export:
Profile
get_profile
profile_id
normalize_internal remains usable inside the module but is unavailable to
importers. An export name must resolve to a top-level declaration or value in
that module.
Selective Imports¶
An importer can request only part of the exported surface:
> import: services/profiles:
Profile
get_profile
Every selected name must be exported by the target and must appear once in the list. A missing, private, or duplicate name is an error. Selective import is appropriate for documenting dependencies and avoiding collisions in large programs.
Star Exports¶
> export: * exports every public top-level name:
@public_name() -> str:
= visible
@_internal_name() -> str:
= hidden
> export: *
Names beginning with _ remain private. Star export is convenient for small
facade modules, but explicit export lists make API reviews and compatibility
changes clearer.
Re-Exports¶
Because imported names enter the module environment, an importing module can export them again:
> import: services/profiles:
Profile
@load_default() -> Profile:
= `Profile(name="default", id=0)`
> export:
Profile
load_default
Use re-exports to create a stable facade. Avoid chains of accidental star re-exports, which make ownership and compatibility difficult to see.
Source-Order Binding¶
Imports and declarations bind names where they appear. When several statements provide the same name, the last binding wins:
[label] = before
> import: labels
[label] = after
= <label>
The result is "after". This behavior supports deliberate overrides but can
hide collisions. Prefer selective imports or distinct names when both values
matter.
An initialized module's exports are republished at every import position, so a later repeated import can overwrite a binding changed between imports without re-running module initialization.
Private and Non-Exported Names¶
No export directive means the module publishes nothing. A leading underscore only matters to star export; an explicit export list should still be used for the intended public API.
Module Python-prelude helpers are implementation details unless surfaced through a Kedi value, procedure, type, or profile and explicitly exported.
Errors¶
Kedi rejects invalid paths, missing module files, unknown selective names, duplicate names in one selective list, unknown exports, and malformed export directives. Import errors include the resolution candidates so local, built-in, and registry problems can be distinguished.