LEVIATHAN v962456e · 962456eee1

Declarations

Namespaces

Group declarations under a name, reopen a namespace to add to it, nest namespaces, and reach members with ::.

since 0.1.0-alpha.1linuxwindowswasm

Description

A namespace groups functions, classes, structs, enums, constants and variables under one name:

namespace Name {
    ...declarations...
}

Namespaces are declared in source, not by the layout of files on disk. The same namespace may be declared as many times as you like, in one file or several; every block adds to the same namespace. Namespaces nest, and a nested namespace is reached through its full path.

A member is reached from outside with ::: Geo::twice(), Geo::Shapes::sides(). Inside the namespace its members are visible by their bare names. To use a namespace's names without writing the path, import them with uses or use (see lang.imports).

Reopened and nested namespaces

namespace Geo {
    int count = 0;
    namespace Shapes {
        int sides() => 4;
    }
    int bump() { count += 1; return count; }
}
namespace Geo {
    int twice() => bump() + bump();
}
console.writeln(Geo::Shapes::sides());
console.writeln(Geo::twice());
Geo::count = 10;
Geo::count += 1;
console.writeln(Geo::count);
4
3
11

The second namespace Geo block adds twice to the namespace declared by the first block, and twice can call bump by its bare name because both blocks are the same namespace.

Rules

  • A namespace may be declared more than once; all blocks with the same path merge into one namespace.
  • A namespace may contain other namespaces to any depth. Its members are named with a :: path.
  • A non-const namespace variable may be written by its qualified path from anywhere: from outside the namespace, from inside it, from a free function, from an instance method, or from a lambda. Plain assignment, compound assignment (+=) and indexed assignment (table[key] = v) are all allowed, at any depth (A::B::x = v).
  • The same variable may be written by its bare name wherever the bare name is in scope: inside the namespace, or in a scope that imported it with use or uses. Inside a class body, a bare name that the class also declares as a field is the class's own field first.
  • Writing a const namespace variable is a compile error, whether the write is bare, qualified, through an import alias, compound, or indexed.
  • Only a variable can be assigned. Assigning to a namespace function name (NS::f = ..., plain, compound or indexed) is the compile error cannot assign to function 'f'.
  • Inside a class body, a bare assignment to a name that the class declares only as a method, when no namespace variable of that name is visible, is the compile error cannot assign to method 'g'.
  • Namespace-level variables are created with their default values before any initializer runs and are initialized before the program's top-level statements. See lang.const for the full order.

Examples

A namespace variable can be updated from a method of a class that is not part of the namespace:

Writing a namespace variable from a method

namespace Cfg {
    int hits = 0;
    Array<int> log = [];
    namespace Inner { int depth = 1; }
}
class Tracker {
    void hit() {
        Cfg::hits += 1;
        Cfg::log = Cfg::log.add(Cfg::hits);
    }
}
Tracker().hit();
Tracker().hit();
Cfg::Inner::depth = 4;
console.writeln(Cfg::hits);
console.writeln(Cfg::log);
console.writeln(Cfg::Inner::depth);
2
[1, 2]
4

Writing a const variable or a function is rejected at compile time:

Assigning to a const and to a function

namespace Cfg {
    const int limit = 5;
    int size() => 1;
}
Cfg::limit = 6;     // error: cannot assign to const 'limit'
Cfg::size = 3;      // error: cannot assign to function 'size'
not run — a compile error on purpose

See also

  • Imports — uses and use — Bring a namespace's names into scope in bulk with uses, or one name at a time with use ... as ....