114 Namespaces
Predica declarations are organised using components and namespaces. A component is the filesystem and dependency unit. Namespaces organise declarations inside one component.
Where Predica is used in a computer system, a component is typically associated with a deployment unit such as a library containing implementations of the types and functions belonging to that component. In a legal system, components are typically associated with the division into parts, such as acts or articles.
Namespaces are used to organise declarations and to avoid accidental name collisions. A namespace does not create a component dependency, and a folder inside a component does not create a namespace. Namespaces must be declared explicitly in Predica source.
namespace Geometry
{
value Point
{
Real x;
Real y;
}
namespace Shapes
{
value Circle
{
Point centre;
Real radius;
}
}
}
Namespace lookup
Within a namespace, unqualified component-local names are resolved relative to the current namespace and then its ancestor namespaces, stopping at the root namespace of the current component. A more local declaration hides a declaration with the same name in an ancestor namespace.
value Thing {}
namespace Inner
{
value Thing {}
value Use
{
Thing x; // resolves to Inner.Thing
}
}
If Inner did not declare Thing, the reference would continue to the
component root namespace and find the outer Thing.
Qualified names inside a component
Qualified names that are not component aliases are interpreted relative to the current component
namespace chain. For a reference to A.B inside
acme.Model.Geometry.Units, lookup may try:
acme.Model.Geometry.Units.A.B
acme.Model.Geometry.A.B
acme.Model.A.B
Lookup does not continue to acme.A.B or to any other component merely because the
component names share a dotted prefix. Component namespace ancestry organises components; it does
not create implicit dependencies between them.