Skip to content

Modules ​

Modules help organize code into separate files.

Importing Modules ​

Use import to bring definitions from other modules:

kettle
import utils

fn main() -> Unit using file_io
  result = utils.helper(5)
  print(to_string(result))
end fn

For modules in subdirectories, use path-based imports:

kettle
import stdlib/quantum

fn main() -> Unit using quantum_simulator
  q: Qubit = 0
  q <- hadamard
  print(measure(q))
end fn

The module name used for qualified calls is the last path component (e.g., stdlib/quantum is accessed as quantum).

Module Structure ​

A Kettle file is a module. The file name (without .ket) is the module name:

project/
  main.ket        -- main module
  utils.ket       -- utils module
  stdlib/
    math.ket      -- stdlib/math module

Defining a Module ​

Every .ket file defines a module. All top-level definitions are exported:

kettle
-- utils.ket

fn helper(x: Int) -> Int
  x + 1
end fn

type Config = record
  name: String
  value: Int
end record

Using it:

kettle
-- main.ket
import utils

fn main() -> Unit using file_io
  result = utils.helper(5)
  cfg = utils.Config { name: "test", value: 42 }
  print(to_string(result))
end fn

Nested Imports ​

Modules can import other modules. When module A imports module B which imports module C, all three are loaded and each module can call functions in its own imports:

kettle
-- inner.ket
fn value() -> Int
  42
end fn
kettle
-- outer.ket
import inner

fn relay() -> Int
  inner.value()
end fn
kettle
-- main.ket
import outer

fn main() -> Unit using file_io
  print(to_string(outer.relay()))
end fn

Each module can only access the modules it directly imports — main.ket above cannot call inner.value() because it only imports outer.

Built-in Functions ​

Core functions like print, map, filter, fold, and length are always available without imports. These are built into the language.

Circular Imports ​

Kettle does not allow circular imports. If module A imports module B, then B cannot import A (directly or indirectly). The compiler detects cycles and reports an error.

Structure your code to avoid cycles:

-- Bad: circular
a.ket imports b.ket
b.ket imports a.ket

-- Good: shared dependency
a.ket imports common.ket
b.ket imports common.ket

Next Steps ​