@manpage Namespaces ### Namespaces All identifiers declared in a monkey2 program file end up inside a 'namespace'. Namespaces are hierarchical, so in addition to identifiers declared by monkey2 code, namespaces can also contain other namespaces. @#### Declaring namespaces You control which namespace the identifiers declared in a monkey2 file go with the namespace directive: `Namespace` _namespace-path_ This directive must appear at the top of the program file, before any actual declarations are made. A namespace path is a 'dot' separated sequence of identifiers, eg: `monkey.types` `std.collections` The 'dot' separator indicates the namespace hierarchy, eg: `monkey.types` is a 'child' or 'inner' namespace of `monkey`. If no namespace is specified in a program file, the identifiers go into a default namespace. This is not recommended though, as the default namespace has no name - so anything inside the default namespace cannot be 'seen' by anything outside. @#### Accessing namespaces Code can access an identifier in a namespace by prefixing the identifier with the namespace path, eg: `Local list:=New std.collections.List` Here, `std.collections` refers to a namespace, while `List` is an identifier inside the `std.collections` namespace. Code inside a particular namespace does not have to use a namespace prefix to find identifiers in the same namespace or in any parent namespace, although it can still do so, eg: ``` Namespace testing Function Test() End Function Main() Test() 'works fine... testing.Test() 'also works... End ``` @#### The Using directive To make it easier to deal with long or complex namespace paths, the using directive provides a way to add namespace 'search paths' for locating identifiers. The using directive looks like this: `Using` _namespace-path_ A program can have multiple using directives. Using directives must appear at the top of the program file before any program declarations. Each using directive adds a namespace to a set of 'search paths' that is used to resolve any unknown identifiers in the program code, eg: ``` #Import "" Using std.collections Function Main() Local list:=New List End ``` Without the using directive, this program would fail to compile because the `List` identifier cannot be found. However, the using direct tells the compiler look for `List` in the `std.collections` namespace, where it is successfully located. If you have multiple using directives and an identifier is found in more than one namespace, you will still get a compile error. In this case, you will need to 'fully qualify' the identifier by prefixing it with the correct namespace path. Some modules declare many namespaces, and it can often be difficult to remember where everything is. To deal with this, Monkey2 provides a convenient 'double dot' form of Using that will use both a namespace AND all namespaces contained in that namespace. For example: ``` Using std.. ``` The double dots must appear at the end of the using. This will use the std namespace, and the std.collections, std.filesystem etc namespaces too. This works recursively, so any namespaces inside std.collections and std.filesystem are also used. This can of course lead to more 'duplicate identifier' clashes but is none-the-less very convenient.