112 Introduction to components

A Predica component is the unit used to group a set of type definitions for compilation, schema evolution, and deployment. The component's filesystem location identifies it.

Consider the following directory structure:


root/
    acme/
        Geometry/
            _component_.predica
            point.predica
            circle.predica
            internal/
                vectors.predica
    

The folder named root is called an include root. These are folders that may contain any number of components. The folder named Geometry contains the component manifest _component_.predica. That marks Geometry/ as a component root folder. The component name is the name of that folder, Geometry. The qualified component name is the path from the include root to the component root with path separators replaced by dots: acme.Geometry.

Include roots

A compiler is given an ordered list of filesystem paths denoting include roots. An include root is a folder from which components can be discovered, for tools that recursively scan subfolders for _component_.predica files, or looked up for a given qualified component name. A compiler might support declaring include roots on the command line, for example using a -I switch. A qualified component name is allowed to appear under more than one include root. Lookup by qualified component name searches include roots in order and uses the first matching component root. Qualified component names are case sensitive in Predica. Distinct components cannot have the same qualified component name under case-insensitive comparison. If R is the list of include roots, no root in R may be a descendant of another root in R.

Component roots

A valid component root satisfies the following rules.

  • The component root folder name must be a valid identifier and must match the component name.
  • The component root folder must contain a component manifest named _component_.predica.
  • Components cannot nest: no descendant folder may contain another component manifest.

Folder names below an include root that correspond to namespace names or component names must also be valid identifiers, as defined by the lexical grammar.

Files inside a component

A Predica file is a file with the .predica extension. The Predica files belonging to a component are found by searching the component root's folder tree. The component manifest identifies that folder as a component root; other Predica files in the tree provide the component's declarations and optional program/query items.

The folder structure inside a component has no semantic meaning. Subfolders may be used for convenience, but they do not create namespaces. Any namespaces used inside a component must be declared explicitly in Predica source.

Optional component declarations

A component declaration is optional at the start of any Predica file, including the component manifest. When present, it is the first non-whitespace, non-comment token in the file.

The following form gives the component name:


component Geometry;
    

Alternatively, this form gives the qualified component name:


component acme.Geometry;
    

The compiler ensures these match the component name or qualified component name determined by the file system.

Ordinary source-file order

This is an example of a Predica source file:


component acme.Geometry;
@dynamic = true;
using acme.Units { Metre };

value Point
{
    Float64 x;
    Float64 y;
}

show(Point { x = 0, y = 0 });
    

The top-level items in a Predica source file appear in this order:

  1. An optional component declaration.
  2. An optional @dynamic directive.
  3. Zero or more file-scoped using declarations.
  4. All schema/library declarations.
  5. Optional top-level program statements.

Top-level program statements may appear in ordinary component source files after all declarations. Schema and check modes load and type-check those items as source, but they do not execute them.

Namespace declarations contain schema/library declarations only. They do not contain using declarations or program statements. Once a file has reached its program statement section, no further declarations are allowed.

Encoding and file system details

The recommended encoding for Predica files is UTF-8 without a byte order mark and without a shebang. This is the only encoding currently supported by the reference implementation.

The handling of symlinked files and folders, hidden folders, and generated folders is currently unspecified by the reference compiler.