LEVIATHAN v962456e · 962456eee1

Declarations

Imports — uses and use

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

since 0.1.0-alpha.1linuxwindowswasm

Description

Namespace members are normally reached with a qualified path such as Shop::price. Two statements import names so that the path can be dropped:

uses NS;                      // import ALL of NS's names into the enclosing scope
uses A::B;                    // a nested path works the same way

use NS::name;                 // import ONE name: a value, function, class or namespace
use NS::name as alias;        // import it under another name
use A::B;                     // import a nested namespace itself; B::f() then works

uses imports every name of a namespace at once. use imports a single name, of any kind, and the optional as renames it, which avoids collisions with names you already have.

Imports are resolved entirely at compile time. An alias is another name for the same declaration, not a copy, so assigning to an imported variable through its alias assigns the original variable.

Importing one name, a whole namespace, and a nested namespace

namespace Shop {
    int tax = 8;
    int price(int base) => base + base * tax / 100;
    class Cart {
        int items = 3;
    }
    namespace Pay {
        string method() => "card";
    }
}
uses Shop;
use Shop::price as shopPrice;
use Shop::Pay;
console.writeln(shopPrice(100));
console.writeln(Pay::method());
console.writeln(tax);
console.writeln(Cart().items);
108
card
8
3

Rules

  • An import is a declaration in the scope where it is written, and that scope is whatever block, function body or file contains it. An import written at the top of a file is visible in that file only, not in the rest of the program.
  • Imports are hoisted: an import is visible throughout its whole scope, including statements that come before it.
  • A declaration in a scope hides an imported name of the same spelling that arrives from a wider scope or from the same scope. In particular, a nearer use hides a farther use, and a function declared in a scope hides an import of the same name in that scope.
  • Within one scope, use beats uses: a name imported by use wins over the same name brought in by uses.
  • An alias names the same declaration, so writing through an alias writes the original variable. Writing through the alias of a const variable is the same compile error as writing the const directly.
  • use can import any kind of declaration: a variable, a function, a class, an interface or a nested namespace.
  • use of a class or interface type can also activate a dependency-injection binding that the type's namespace exports; see lang.bind-activation. uses never activates a binding.

Examples

A use in a nearer scope wins over a uses in the same scope, and an import in a function body is visible only inside that function:

Specific beats bulk, and scoping

namespace Shop {
    int price(int base) => base + 1;
}
namespace Other {
    int price(int base) => base * 2;
}
uses Shop;
void bulk() {
    uses Other;
    use Shop::price;
    console.writeln(price(100));
}
void nearer() {
    use Other::price;
    console.writeln(price(100));
}
bulk();
nearer();
console.writeln(price(100));
101
200
101

In bulk, uses Other and use Shop::price both supply price, and the specific use wins. In nearer, the function's own use hides the file-level uses Shop. Outside both functions only uses Shop is in scope.

An alias is the same variable under another name:

Writing through an alias

namespace Cfg {
    int hits = 0;
}
use Cfg::hits as h;
h = 50;
h += 1;
console.writeln(Cfg::hits);
51

An import is visible in its own file only:

File scope of an import

// file a.lev
namespace NS { int v() => 7; }
uses NS;
int fromA() => v();      // fine: the import is in this file

// file b.lev
console.writeln(fromA());
console.writeln(v());    // error: unknown function 'v'; b.lev has no import
not run — needs a project of two source files

Notes

An import is a compile-time rename, so it costs nothing at run time.

See also

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