Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

6. Modules

A program grows past one file by splitting into modules. Each .kor file is a module; import runs another one and gives you an object to reach into.

Importing a file

Say geometry.kor sits next to your program:

pi = 3.14159

fn area(r):
    return pi * r * r

Import it by relative path — ./ for "next to me", ../ to go up:

import "./geometry"

print(geometry.area(2))

import "./geometry" binds geometry (the file's name, no extension; the .kor is implied). Reach members with ., like a class instance — this prints 12.56636.

To pick a different name — or avoid a clash — add as:

import "./geometry" as geo
print(geo.area(1))

(These blocks aren't executed by the CI check the way the rest of the guide is — they need real files on disk. The behaviour is covered by the interpreter's own module tests.)

What's public

Every top-level name in a module is visible through the module object, except names starting with _:

fn shout(s):
    return _emphasise(s.upper())

fn _emphasise(s):
    return s + "!!!"

From another file, util.shout("go") returns "GO!!!", but reaching util._emphasise is an error. Inside util.kor, _-names work normally — the line is only drawn at the module boundary.

Loaded once

A module runs the first time it is imported. Import it again — from the same file or a different one — and you get the same object back, already initialised, so geometry == also_geometry is true.

Two modules that import each other are an error (E0315): Korrin will not hand you a half-loaded module. If two modules need something in common, put it in a third module they both import.

The standard library

A specifier with no ./ is a built-in module — part of Korrin, imported the same way, and it works from any program:

import "math"

print(math.sqrt(144))
print(math.floor(3.7))
print(math.max(2, 9, 5))
# => 12.0
# => 3
# => 9

math has sqrt, pow, floor, ceil, round, abs, min, max, and the constants pi and e.

io talks to the outside world — files and command-line arguments:

import "io"

io.write_file("note.txt", "hello from Korrin\n")
print(io.read_file("note.txt").trim())
print(io.args())

An io call that fails raises (E0316), so wrap it in try when the file might not be there:

import "io"
try:
    config = io.read_file("config.txt")
except e:
    config = "(defaults)"

Full list of both modules in specification §11.

Because "math" always means the built-in, a file called math.kor next to your program does not shadow it — import that one as "./math".