layout | title | category | tags | order | ||
---|---|---|---|---|---|---|
developer-doc |
Modules |
types |
|
7 |
With such a flexible type system in Enso, the need for making modules first-class is obviated. Instead, a module is very much its own entity, being simply a container for bindings (whether they be functions, methods, atoms, or types).
The actionables for this section are:
- Characterise modules in more depth as we need them.
[!WARNING] There is no
here
keyword anymore and the clash resultion is probably also not working.Enso modules employ the following rules in order to avoid name clashes:
- Where the module name clashes with a member contained in the module, the member is preferred. If you need the module you must import it qualified under another name.
- We provide the alias
here
as a way to access the name of the current module.
[!WARNING] Review by an imports expert is needed!
To use the contents of a module we need a way to bring them into scope. Like most languages, Enso provides an import mechanism for this. Enso has four different kinds of imports that may be combined freely, all of which take a module path as their first argument.
- Unqualified Imports: These import all symbols from the module into the
current scope (
import M
). - Qualified Imports: These import all symbols from the module into the
current scope with symbols qualified under a name different from the
module name (
import M as T
). - Restricted Imports: These import only the specific symbols from the
module into the current scope (
import M only sym1 sym2
). - Hiding Imports: These are the inverse of restricted imports, and import
all symbols other than the named ones into the current scope
(
import M hiding sym1 sym2
),
Imports may introduce ambiguous symbols, but this is not an error until one of the ambiguous symbols is used in user code.
When importing a module X
into the current module Y
, the bindings in X
become available in Y
(modified by the import type). However, these bindings
are not available in Y
externally. This means that we need a re-export
mechanism. Similarly to imports, this has four kinds, all of which take a module
path as their first argument, and all of which may introduce the module it
exports into scope (if it is not already imported).
- Unqualified Exports: These export all symbols from the module as if they
were defined in the exporting module (
export X
). - Qualified Exports: These export all symbols from the module as if they
were defined in another module accessible in the exporting module
(
export X as Y
). - Restricted Exports: These export only the specified symbols from the
module as if they were defined in the exporting module (
export X only sym
) - Hiding Exports: These export all symbols from the module except those
explicitly specified (
export X hiding sym1 sym2
).
Exports effectively act to 'paste' the contents of the exported module into the module declaring the export. This means that exports that create name clashes must be resolved at the source.
The actionables for this section are:
- Are we really, really sure we want unqualified by default?
- Think about how to handle imports properly in the type checker. What, if they have any, are the impacts of imports on inference and checking?