The algorithm for compiling modules is:

    • compile the whole module as usual, following import statements recursively
    • if there is a cycle only import the already parsed symbols (that are exported); if an unknown identifier occurs then abort

    This is best illustrated by an example:

    1. import A # A is not parsed here! Only the already known symbols
    2. # of A are imported.
    3. proc p*(x: A.T1): A.T1 =
    4. # this works because the compiler has already
    5. result = x + 1

    After the import statement a list of module names can follow or a single module name followed by an except list to prevent some symbols to be imported:

    1. import strutils except `%`, toUpperAscii
    2. # doesn't work then:
    3. echo "$1" % "abc".toUpperAscii

    It is not checked that the except list is really exported from the module. This feature allows to compile against an older version of the module that does not export these identifiers.

    The import statement is only allowed at the top level.

    Include statement

    The include statement does something fundamentally different than importing a module: it merely includes the contents of a file. The include statement is useful to split up a large module into several files:

    1. include fileA, fileB, fileC
    1. echo "Hello World!"

    A module alias can be introduced via the as keyword:

    1. import strutils as su, sequtils as qu
    2. echo su.format("$1", "lalelu")

    The original module name is then not accessible. The notations path/to/module or “path/to/module” can be used to refer to a module in subdirectories:

    1. import lib/pure/os, "lib/pure/times"

    Note that the module name is still strutils and not lib/pure/strutils and so one cannot do:

    1. import lib/pure/strutils
    2. echo lib/pure/strutils.toUpperAscii("abc")

    Likewise the following does not make sense as the name is strutils already:

    1. import lib/pure/strutils as strutils

    The syntax import dir / [moduleA, moduleB] can be used to import multiple modules from the same directory.

    Path names are syntactically either Nim identifiers or string literals. If the path name is not a valid Nim identifier it needs to be a string literal:

    There are two pseudo directories:

    1. std: The std pseudo directory is the abstract location of Nim’s standard library. For example, the syntax import std / strutils is used to unambiguously refer to the standard library’s strutils module.

    2. pkg: The pkg pseudo directory is used to unambiguously refer to a Nimble package. However, for technical details that lie outside of the scope of this document its semantics are: Use the search path to look for module name but ignore the standard library locations. In other words, it is the opposite of std.

    From import statement

    After the from statement a module name follows followed by an import to list the symbols one likes to use without explicit full qualification:

    1. echo "$1" % "abc"
    2. # always possible: full qualification:

    It’s also possible to use from module import nil if one wants to import the module but wants to enforce fully qualified access to every symbol in module.

    An export statement can be used for symbol forwarding so that client modules don’t need to import a module’s dependencies:

    1. # module B
    2. type MyObject* = object
    1. # module A
    2. import B
    3. export B.MyObject
    4. proc `$`*(x: MyObject): string = "my object"
    1. # module C
    2. import A
    3. # B.MyObject has been imported implicitly here:

    Notice that when exporting, one needs to specify only the module name: