> ##

> ## 5.12 Namespaces

> One really nice feature of RECORDs and UNIONs is that the field names are local to a given RECORD or UNION declaration. That is, you can reuse field names in different RECORDs or UNIONs. This is an important feature of HLA because it helps avoid name space pollution. Name space pollution occurs when you use up all the "good" names within the current scope and you have to start creating non-descriptive names for some object because you've already used the most appropriate name for something else. Because you can reuse names in different RECORD/UNION definitions (and you can even reuse those names outside of the RECORD/UNION definitions) you don't have to dream up new names for the objects that have less meaning. We use the term namespace to describe how HLA associates names with a particular object. The field names of a RECORD have a namespace that is limited to objects of that record type. HLA provides a generalization of this namespace mechanism that lets you create arbitrary namespaces. These namespace objects let you shield the names of constants, types, variables, and other objects so their names do not interfere with other declarations in your program.

> An HLA NAMESPACE section encapsulates a set of generic declarations in much the same way that a RECORD encapsulates a set of variable declarations. A NAMESPACE declaration takes the following form:

>     namespace name;

>     	<< declarations >>

>     end name;

> The name identifier provides the name for the NAMESPACE. The identifier after the END clause must exactly match the identifier after NAMESPACE. You may have several NAMESPACE declarations within a program as long as the identifiers for the name spaces are all unique. Note that a NAMESPACE declaration section is a section unto itself. It does not have to appear in a TYPE or VAR section. A NAMESPACE may appear anywhere one of the HLA declaration sections is legal. A program may contain any number of NAMESPACE declarations; in fact, the name space identifiers don't even have to be unique as you will soon see.

> The declarations that appear between the NAMESPACE and END clauses are all the standard HLA declaration sections except that you cannot nest name space declarations. You may, however, put CONST, VAL, TYPE, STATIC, READONLY, STORAGE, and VAR sections within a namespace1. The following code provides an example of a typical NAMESPACE declaration in an HLA program:

>     namespace myNames;

>     	type

>     		integer: int32;

>     	static

>     		i:integer;

>     		j:uns32;

>     	const

>     		pi:real64 := 3.14159;

>     end myNames;

> To access the fields of a name space you use the same dot notation that records and unions use. For example, to access the fields of myNames outside of the name space you'd use the following identifiers:

>     myNames.integer - A type declaration equivalent to int32.

>     myNames.i - An integer variable (int32).

>     myNames.j - An uns32 variable.

>     myNames.pi - A real64 constant.

> This example also demonstrates an important point about NAMESPACE declarations: within a name space you may reference other identifiers in that same NAMESPACE declaration without using the dot notation. For example, the i field above uses type integer from the myNames name space without the "mynames." prefix.

> What is not obvious from the example above is that NAMESPACE declarations create a clean symbol table whenever you open up a declaration. The only external symbols that HLA recognizes in a NAMESPACE declaration are the predefined type identifiers (e.g., int32, uns32, and char). HLA does not recognize any symbols you've declared outside the NAMESPACE while it is processing your namespace declaration. This creates a problem if you want to use symbols outside the NAMESPACE when declaring other symbols inside the NAMESPACE. For example, suppose the type integer had been defined outside myNames as follows:

>     type

>     	integer: int32;

>     namespace myNames;

>     	static

>     		i:integer;

>     		j:uns32;

>     	const

>     		pi:real64 := 3.14159;

>     end myNames;

> If you were to attempt to compile this code, HLA would complain that the symbol integer is undefined. Clearly integer is defined in this program, but HLA hides all external symbols when creating a name space so that you can reuse (and redefine) those symbols within the name space. Of course, this doesn't help much if you actually want to use a name that you've defined outside myNames within that name space. HLA provides a solution to this problem: the @global: operator. If, within a name space declaration section, you prefix a name with "@global:" then HLA will use the global definition of that name rather than the local definition (if a local definition even exists). To correct the problem in the previous example, you'd use the following code:

>     type

>     	integer: int32;

>     namespace myNames;

>     	static

>     		i:@global:integer;

>     		j:uns32;

>     	const

>     		pi:real64 := 3.14159;

>     end myNames;

> With the @global: prefix, the i variable will be type int32 even if a different declaration of integer appears within the myNames name space.

> You cannot nest NAMESPACE declarations2. However, you can have multiple NAMESPACE declarations in the same program that use the same name space identifier, e.g.,

>     namespace ns;

>     	<< declaration group #1 >>

>     end ns;

>     	.

>     	.

>     	.

>     namespace ns;

>     	<< declaration group #2 >>

>     end ns;

> When HLA encounters a second NAMESPACE declaration for a given identifier, it simply appends the declarations in the second group to the end of the symbol list it created for the first group. Therefore, after processing the two NAMESPACE declarations, the ns name space would contain the set of all symbols you've declared in both the name space blocks.

> Perhaps the most common use of name spaces is in library modules. If you create a set of library routines to use in various projects or distribute to others, you have to be careful about the names you choose for your functions and other objects. If you use common names like get and put, the users of your module will complain when your names collide with theirs. An easily solution is to put all your code in a NAMESPACE block. Then the only name you have to worry about is the name of the NAMESPACE itself. This is the only name that will collide with other users' code. That can happen, but it's much less likely to happen than if you don't use a name space and your library module introduces dozens, if not hundreds, of new names into the global name space3. The HLA Standard Library provides many good examples of name spaces in use. The HLA Standard Library defines several name spaces like stdout, stdin, str, cs, and chars. You refer to functions in these name spaces using names like stdout.put, stdin.get, cs.intersection, str.eq, and chars.toUpper. The use of name spaces in the HLA Standard Library prevents conflicts with similar names in your own programs.

> ## 5.13 Putting It All Together

> One of the more amazing facts about programmer psychology is the fact that a high level language programmer would refuse to use a high level language that doesn't support records or structures; then that same programmer won't bother to learn how to use them in assembly language (all the time, grumbling about their absence). You use records in assembly language for the same reason you use them in high level languages. Given that most programmers consider records and structure essential in high level languages, it is surprising they aren't as concerned about using them in assembly language.

> This short chapter demonstrates that it doesn't take much effort to master the concept of records in an assembly language program. Taken together with UNIONs and NAMESPACEs, RECORDs can help you write HLA programs that are far more readable and easier to understand. Therefore, you should use these language features as appropriate when writing assembly code.

> 1Procedure and macro declarations, the subjects of later chapters, are also legal within a name space declaration section.

> 2There really doesn't seem to be a need to do this; hence its omission from HLA.

> 3The global name space is the global section of your program.