Modules & Packages
Kyna splits code across files with explicit export / import. A directory is a package: every *.kyna file in that folder shares one namespace. Underneath, the compiler still type-checks a DAG of modules, like Go's package model without Go's syntax.
Exporting
Mark top-level declarations with export. Unexported names stay private to the module (or package). export default marks the default export; export { a, b } re-exports named declarations.
# math.kyna
export fn add(a: int, b: int): int {
return a + b;
}
export default fn greet(name: str): str {
return "hi " + name;
}
fn hidden(): int {
return 9;
}
Imports must appear before other top-level declarations. Only named top-level declarations can be exported.
Importing
Namespace import (still the most common form):
import "./math.kyna" as math;
var answer: int = math.add(20, 22);
JavaScript-style named, default, and star imports also work:
import { add, sub } from "./math.kyna";
import greet from "./math.kyna";
import * as math from "./math.kyna";
- Namespace reads are live; namespace writes are forbidden.
- A missing or non-exported member is a compile error (
K4004). - Resolution tries the importer's directory first, then
--module-pathroots. - Import cycles report the full filename chain (
K4002). - Modules initialize once, in postorder.
There is no import std.fs today. Filesystem, JSON, HTTP, and logging are global builtins (readFile, jsonParse, fetch, slogInfo, …).
Directory packages
Pass a folder to ky check or ky run. Every *.kyna file in that directory (except *_test.kyna) is merged into one package scope. Sibling files share types and functions without importing each other.
app/
helpers.kyna # fn add(a: int, b: int): int { ... }
main.kyna # uses add directly
ky check ./app
ky run ./app
Ambient type-definition files (.kyna.d, .d.ky, .ky.d) contribute compile-time interfaces only and are never executed.
internal/ shielding
A package under a directory named internal may only be imported from the tree above that internal folder (Go's rule). Cross-tree imports fail with KSEM1042.
# allowed: service/app.kyna → service/internal/secret.kyna
# rejected: other/app.kyna → service/internal/secret.kyna
Export cache (.kyc)
After a dependency type-checks successfully, the compiler writes a stamp file next to the source (math.kyna.kyc). The next compile still parses that file, but skips re-checking its body when size and mtime still match.
- The entry module is always analyzed.
- A failed check deletes the stamp.
- Class shapes still come from the parsed AST.
- Set
KYNA_DISABLE_EXPORT_CACHEto disable.
.kyc files are build artifacts; do not commit them.