The Avail Programming Language

Private Imports Section

The Uses keyword begins the private imports section. The contents of this section are zero or more import specifications separated by commas , (U+002C). An import specification constitutes a request to import the exported names of a given module, called the import target. These names are available for private use only; they are not re-exported to downstream modules. An import specification satisfies the ImportSpecification syntax diagram,

ImportSpecification

where the terminal module is a string literal that specifies the local name of the import target. The import target is, by definition, an upstream module.

An import specification contains an optional required versions list. A required versions list stipulates what active versions of the import target are acceptable for linkage. As such, it is a declaration of compatibility with a particular list of versions. A required versions list satisfies the nonterminal VersionList, and corresponds to the following syntax diagram,

VersionList

where version is a string literal that denotes an acceptable version of the import target. If the import target advertises no versions in common with the required versions list, then the compiler or executor aborts linkage of the dependent module.

If a required versions list is not specified, then no compatibility check is performed. Any version of the import target is therefore considered acceptable, at least in the sense that linking to the import target will not be preemptively aborted. It is still possible that the API of the import target may prove incompatible with the API required by the dependent module.

An import specification contains an optional custom import rules list. A custom import rules list cherry-picks exported names from the import target in accordance with a small number of predefined rules. It satisfies the CustomImportRulesList nonterminal, and corresponds to the following syntax diagram,

CustomImportRulesList

where each of the terminals name, rename, and excludedName are string literals. The sundry paths through the syntax diagram represent custom import rules, which come in four varieties:

Importing a name as is.
This rule is invoked when name occurs alone. In this case, name specifies an atom exported by the imported target. This atom should be imported into the dependent module, and should be available under its original name.[1] name must not be explicitly excluded from import.
Importing a name as a new name.
This rule is invoked when name → rename occurs. name denotes an atom exported by the import target. This atom will not be imported into the dependent module. rename introduces a new atom into the dependent module. If name refers to an existing method, then rename will be made to refer to this method. If name does not refer to a method, then an empty method is created and both name and rename will be made to refer to it. name will not be imported into the dependent module even when importing by wildcard, but it must not be explicitly excluded from import. It is still possible to import name by explicitly importing it as is.
Excluding a name from import.
This rule is invoked when -excludedName occurs. excludedName denotes an atom that is exported by the import target. This atom will not be imported into the dependent module. Furthermore, name must not be explicitly imported, either as is or under a new name. This rule is only available when importing by wildcard.
Importing by wildcard.
This rule is invoked when horizontal ellipsis (U+2026) occurs. Every atom that is exported by the import target is imported as is into the dependent module, with the following exceptions: When not importing by wildcard, only those names exported by the import target that are explicitly imported as is or under new names will be imported; any name not mentioned will not be imported.

A custom import rules list is optional. If it is not specified, then every name exported by the import target will be imported into the dependent module as is; this is the same behavior as specifying a custom import rules list which only imports by wildcard. In practice, omitting the custom import rules list is the most common use case.

And now for some examples:

Module "Hello World" Uses "Avail" Entries "Greet" Body

Hello World imports every name exported by Avail.

Module "Core" Versions "dev" Uses "Avail" = ( "_+_" → "_+_(Avail)", "_-_" → "_-_(Avail)", "_×_" → "_×_(Avail)", "_÷_" → "_÷_(Avail)", "_mod_" → "_mod_(Avail)", "_^_" → "_^_(Avail)", … ), "Feature Renames (Inequalities)" Names /* Lots of names elided here. */ Body

Core, a submodule of Dimensional Analysis, imports two modules for private use: Avail and Feature Renames (Inequalities). From Avail, it imports "_+_", "_-_", "_×_", "_÷_", "_mod_", and "_^_", but renames each so that it has the suffix (Avail). Everything else exported by Avail is imported as is. It imports every name that is exported by Feature Renames (Inequalities).

Module "Concurrency" Versions "dev" Uses "Assertions", "Atoms", "Bootstrap", "Casts", "Collections", "Control Structures" = ( -"Cast|cast_into_else_", -"Cast|cast_into_", -"Cast|cast_into«_‡,»«else_»", … ), "Definers", "Enumeration Support", "Exceptions", "Functions", "Literals", "Logic", "Math", "Objects", "Synchronization", "Tuples", "Types", "Variables" Names /* Lots of names elided here. */ Body

Concurrency, an indirect submodule of Avail, imports many modules for private use. From most of these, it imports all exported names. But from Control Structures, it imports everything except for "Cast|cast_into_else_", "Cast|cast_into_", and "Cast|cast_into«_‡,»«else_»".


[1] Though it is sometimes useful to import an atom for its own sake, it is generally the case that the dependent module wishes to gain access to a method named by the atom.

‹ Active Versions Section | Return to Modules | Extended Imports Section ›