a fun language for serious programming


module declares the name of a module. While optional it is recommended to use it, at least for documentation purpose. The basename of the source file must match the name declared with module. The extension of the source file must be nit.

A module is made of, in order:

  • the module declaration;
  • module importations;
  • class definitions (and refinements) ;
  • top-level function definitions (and redefinitions) ;
  • main instructions .

Module Importation

import declares dependencies between modules. By default (that is without any import declaration), a module publicly imports the module standard. Dependencies must not produce cycles. By importing a module, the importer module can see and use classes and properties defined in the imported module.

  • import indicates a public importation. Importers of a given module will also import its publicly imported modules. An analogy is using #include in a header file (.h) in C/C++.

  • private import indicates a private importation. Importers of a given module will not automatically import its privately imported modules. An analogy is using #include in a body file (.c) in C/C++.

  • intrude import indicates an intrusive importation. intrude import bypasses the private visibility and gives to the importer module a full access on the imported module. Such an import may only be considered when modules are strongly bounded and developed together. The closest, but insufficient, analogy is something like including a body file in a body file in C/C++.


By default, all classes, methods, constructors and virtual types are public which means freely usable by any importer module. Once something is public it belongs to the API of the module and should not be changed.

private indicates classes and methods that do not belong to the API. They are still freely usable inside the module but are invisible in other modules (except those that use intrude import).

protected indicates restricted methods and constructors. Such methods belong to the API of the module but they can only be used with the self receiver. Basically, protected methods are limited to the current class and its subclasses. Note that inside the module (and in intrude importers), there is still no restriction.

Visibility of attributes is more specific and is detailed in its own section.

module m1
class Foo
    fun pub do ...
    protected fun pro
    do ...
    private fun pri
    do ...
private class Bar
    fun pri2 do ...
var x: Foo = ...
var y: Bar = ...
# All OK, it is
# inside the module
module m2
import m1
class Baz
    super Foo
    fun derp
        self.pro # OK
var x: Foo = ...
x.pub # OK
x.pro # Compile error:
      # pro is protected
x.pri # Compile error:
      # unknown method pri

var y: Bar
# Compile error:
# unknown class Bar

Visibility Coherence

In order to guarantee the coherence in the visibility, the following rules apply:

  • Classes and properties privately imported are considered private: they are not exported and do not belong to the API of the importer.

  • Properties defined in a private class are private.

  • A static type is private if it contains a private class or a private virtual type.

  • Signatures of public and protected properties cannot contain a private static type.

  • Bounds of public generic class and public virtual types cannot contain a private static type.