3. Namespaces
There are two namespaces in Gazprea:
Type namespace: user-defined and builtin types (structs and typealiases).
Variable/Function/procedure namespace: variables, functions, and procedures.
Items in separate namespaces may share an identifier. Items within the
same namespace cannot share an identifier; the compiler must emit a
SymbolError (see Errors).
Both namespaces are lexically scoped. The no-sharing rule applies within a single scope. A name introduced in an inner scope shadows any outer name of the same namespace for the extent of that scope and does not leak back out. In particular, a type defined inside a function or procedure is not added to the global type namespace.
A struct’s field names can only collide with other field names in the same
struct. Each struct
introduces its own declaration scope for its fields, so a
field name lives in that struct’s scope, not in either global namespace, and may
freely coincide with a type name, a variable/function/procedure name, or a field
name of another struct. On violation of unique field names in a struct
the compiler must emit a
SymbolError (see Errors).
// Does not conflict with the other statements
struct x (integer a, integer b);
// These three statements all conflict with each other
// Any two of them in the same program produces a SymbolError
integer x = 3;
function x() returns integer;
procedure x() returns integer;
The pro tip below relies on struct construction syntax, which is introduced
later in Structs.
// Pro tip: write code that looks like this, employers love it
typealias integer a;
typealias integer main; // Procedure and type do not conflict
struct b (a b, a a, main main); // Struct field identifiers do not conflict with anything
procedure main() returns integer {
a a = 1; // type and variable do not conflict
b b = b(b: a, a: 2, main: 3);
if (true) { // New scope
a a = b.b; // New `a` shadows the old `a`
}
return 0;
}