Modules

What is a module?

In Keen, every file is a module. There is no need for an explicit module declaration.
Without an import, code in one file won't have access to code from a different file.

The standard import

Every file automatically imports from keen/std .
This re-exports from fundamental modules such as keen/bool that we've been using all along.

Standard library imports

Most of the standard library is not in the keen/std and must be explicitly imported.
Imports from the standard library start with keen/.

Imports go in an indented block after the import keyword, each on their own line.

import keen/col/mut-stack main void() a nat mut-stack = 1, 2, 3 log pop a

Selected imports

To import just a few declarations from a module, write those names after a colon.

import keen/col/mut-stack: list-new, mut-stack, pop main void() a nat mut-stack = 1, 2, 3 log pop a

Relative imports

Imports can use relative paths. These look like the relative path to the imported file, just with .keen omitted.

import ./greetings ../some-other-dir/places main void() log "{hello}, {world}!"hello string() "hello"world string() "world"

Re-exports

One module can re-export declarations from another.
This may be useful for defining a main entry point for a library.

import ./re-exporter main void() log fooexport ./foofoo string() "foo"

The export block has the same syntax as an import block. It must come after any import block.

File imports

You can import a file as a string or nat8[].

import ./hello.txt as hello string main void() log hello

No cycles

Modules must be acyclic. If module A imports module B, B can't import A.
To work around this, you could use specs. (See Specs.)

import ./pong main void() log ping 10 ping nat[](x nat) - x -- unless x == 0 then pong x - 1ping spec ping nat[](x nat) pong nat[](x nat) ping - x -- unless x == 0 then ping x - 1