Namespaces

## 10 Namespaces

As in C++, namespaces are used to avoid name clashes in code. For example:

      namespace Foo {
        int x = 0;
        int f() { return x; }
      }

declares an integer named `Foo::x` and a function named `Foo::f`. Note that within the namespace, you don't need to use the qualified name. For instance, `Foo::f` refers to `Foo::x` as simply `x`. We could also simply write ```namespace Foo;`'' (note the trailing semi-colon) and leave out the enclosing braces. Every declaration (variables, functions, types, typedefs) following this namespace declaration would be placed in the Foo namespace.
As noted before, you can refer to elements of a namespace using the ```::`'' notation. Alternatively, you can open up a namespace with a ```using`'' declaration. For example, we could follow the above code with:

      namespace Bar {
        using Foo {
          int g() { return f(); }
        }
        int h() { return Foo::f(); }
      }

Here, we opened the `Foo` namespace within the definition of `Bar::g`. One can also write ```using Foo;`'' to open a namespace for the remaining definitions in the current block.
Namespaces can nest as in C++.
Currently, namespaces are only supported at the top-level and you can't declare a qualified variable directly. Rather, you have to write a namespace declaration to encapsulate it. For example, you cannot write ```int Foo::x = 3;`.''
The following subtle issues and implementation bugs may leave you scratching your head:

- The current implementation translates qualified Cyclone variables to C identifiers very naively: each `::` is translated to `_` (underscore). This translation is wrong because it can introduce clashes that are not clashes in Cyclone, such as in the following:

        namespace Foo { int x = 7; }
        int Foo_x = 9;

  So avoid prefixing your identifiers with namespaces in your program. We intend to fix this bug in a future release.
- Because `#include` is defined as textual substitution, the following are usually very bad ideas: Having ```namespace Foo;`'' or ```using Foo;`'' at the top level of a header file. After all, you will be changing the identifiers produced or the identifiers available in every file that includes the header file. Having `#include` directives within the scope of namespace declarations. After all, you are changing the names of the identifiers in the header file by (further) qualifying them. Unfortunately, the current system uses the C pre-processor before looking at the code, so it cannot warn you of these probable errors.
  In short, you are advised to not use the ``semicolon syntax'' in header files and you are advised to put all `#include` directives at the top of files, before any namespace or using declarations.
- The translation of identifiers declared `extern "C"` is different. Given

        namespace Foo { extern "C" int x; }

  the Cyclone code refers to the global variable as `Foo::x`, but the translation to C will convert all uses to just `x`. The following code will therefore get compiled incorrectly (`f` will return 4):

        namespace Foo { extern "C" int x; }
        int f() {
          int x = 2;
          return x + Foo::x;
        }