Variables, functions, types, etc. are usually given names when declared or defined. These names are always defined within a specific lexical context's namespace.

Cone supports several kinds of namespaces:

Namespaces facilitate a module architecture in several ways. Prudent use of namespaces reduces the accidental risk of name collisions, where two different items (created possibly by different authors) are given the same name. Namespaces also support encapsulation, helping to ensure that implementation details are not visible outside of the namespace.

The rules governing names and namespaces vary depending on the type of namespace.

Name uniqueness

Module, block, and function parameters restrict names so that only one item in that namespace may use a specific name. A compiler error results whenever a name is reused within these namespaces.

However, types do allow the definition of multiple methods that share the same name. Such polymorphism makes it possible to gracefully support the same fundamental semantic capability across many different types of parameters.

Forward references

For the most part, module and type namespaces support forward references. This means that code within a module or type may refer to a name that will be defined later in that code. However, permissions and allocators do not support forward references. These must be defined before they can be used.

Blocks do not support forward references. A local variable must be declared before it can be used.

Name visibility

All names defined within a namespace are visible (may be referenced) within that namespace. The rules for when a name may be referenced by code external to the namespace vary depending on the kind of namespace, as the following sections describe.

Local Name Visibility

A function's (or method's) local names consist of its parameters, as well as all local variables and named (nested) functions or closures that are declared within any of its blocks.

Once a local name has been declared, it may be referenced at any point afterwards within the block's scope it is declared within, as well as within any block that lies within that lexical scope. The only exception to this would be if any inner block defines a local variable of the same name, which then takes precedence within that inner scope.

A function cannot reference any local named declared by another function. This is true even for functions or closures declared within another function. Even a closure's bound variables are visible only to that closure.

Methods and Fields: Public vs. Private

All of a type's methods and fields may be referenced by any of its methods' code. However, only a type's public methods or fields may be referenced by code external to the type. All such references are made using the dot ('.') operator.

Method and field names that begin with an underscore are considered private. Otherwise, the name is public, making it referenceable by code outside the type's namespace.

Module Names: Public vs. Private

Any named item declared as part of a module may be referenced by any code within that module (including inside any of its functions or type's methods). However, only the module's public names may be referenced by code outside that module. As with types, private names begin with an underscore.

The only way to reference a name belonging to another module (even a module nested inside another module) is through the use of a qualified path name.