Modules

Nim supports splitting a program into pieces by a module concept. Each module needs to be in its own file and has its own namespace. Modules enable information hiding and separate compilation. A module may gain access to the symbols of another module by the import statement. Recursive module dependencies are allowed, but are slightly subtle. Only top-level symbols that are marked with an asterisk (*) are exported. A valid module name can only be a valid Nim identifier (and thus its filename is identifier.nim).

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. # Module A
  2. type
  3. T1* = int # Module A exports the type `T1`
  4. import B # the compiler starts parsing B
  5. proc main() =
  6. var i = p(3) # works because B has been parsed completely here
  7. main()
  1. # Module B
  2. import A # A is not parsed here! Only the already known symbols
  3. # of A are imported.
  4. proc p*(x: A.T1): A.T1 =
  5. # this works because the compiler has already
  6. # added T1 to A's interface symbol table
  7. result = x + 1