Previous: Builtin operators, Up: Syntax [Contents]
Items are the top-level syntactic elements of Mercury modules. Their syntax is summarized by the following rules. (All of this information can be found in the descriptions below the rules.)
item = (‘:-’ declaration | clause) end declaration = type-system-decl | mode-system-decl | module-system-decl | pragma-decl clause = rule | dcg-rule | fact rule = head-term ‘:-’ goal dcg-rule = predicate-head-term ‘-->’ dcg-goal fact = head-term, where the principal functor is not ‘:-/1’, ‘:-/2’, or ‘-->/2’ head-term = function-head-term | predicate-head-term function-head-term = head ‘=’ expression predicate-head-term = head, where the principal functor is not ‘=/2’ head = functor-term, where the arguments are expressions
Valid items can be described in the following way.
Each item in a Mercury module is a term followed by an end token (a period). If the principal functor of the term is ‘:-/1’, it is a declaration item and the argument is the declaration. Otherwise it is a clause item and the term is the clause. Note that we often use “declaration” and “clause” informally to refer to the items themselves (i.e., including the end token).
Declarations in Mercury are used to declare things for the type system, the mode system, and the module system, as well as to give compiler directives regarding a number of features. Details of their syntax are covered in later chapters.
These declarations relate to the type system. ‘type’ declarations declare and define types (see User-defined types and Solver types). ‘pred’ and ‘func’ declarations declare the types of predicates and functions (see Predicate and function type declarations). ‘typeclass’ and ‘instance’ declarations declare typeclasses and instances (see Type classes).
‘inst’ and ‘mode’ declarations relate to the mode system (see Modes).
Declarations relating to the module system are: ‘module’, ‘interface’, ‘implementation’, ‘import_module’, ‘use_module’, ‘include_module’, ‘initialise’, ‘finalise’, ‘mutable’, and ‘end_module’. (See Modules.)
‘pragma’ declarations give compiler directives (see Pragmas), are used in the foreign language interface (see Foreign language interface), and in the purity system (see Promising purity).
A clause provides part of the definition of a function or predicate. There are three types of clauses: if the principal functor is ‘:-/2’, the clause is a rule; if the principal functor is ‘-->/2’, the clause is a DCG-rule; otherwise, the clause is a fact.
Each clause has a head term. For rules and DCG-rules, the head term is the left hand side. For facts the head term is the entire term. Rules and DCG-rules also have a body, which is the right hand side.
A rule is a clause, recognizable by the use of ‘:-/2’, that has a goal as its body (see Goals).
A DCG-rule is a clause, recognizable by the use of ‘-->/2’, that has a predicate head term and a DCG-goal as its body. It is an abbreviation for a rule with two fresh variables implicitly added to the argument list. The DCG-goal is transformed into a goal that uses these variables in an idiosyncratic way. (See DCG-goals).
DCG notation is intended for writing parsers and sequence generators in a particular style; in the past it has also been used to thread an implicit state variable, typically the I/O state, through code (something that can also be done in that style). We now recommend that DCG notation be reserved for writing parsers and sequence generators, and that state variable syntax (see State variables), which performs a similar transformation but is more flexible, be used for other purposes such as threading state variables.
A fact is a clause that has no body.
It has the same meaning as a rule
with a head term identical to the fact,
and a body of true
.
If the principal functor of the head term is ‘=/2’ then it is a function head term, otherwise it is a predicate head term.
A function head term is the head term of a clause that provides part of a function definition, and that is recognizable by the use of ‘=/2’. The term on the left hand side is the function’s head; the term on the right hand side is an expression that represents the function return value.
A predicate head term is a head on its own with no return expression, that provides part of a predicate definition.
The head of a function or predicate is a functor term whose arguments are expressions (see Expressions), optionally annotated with mode qualifiers (see Different clauses for different modes). The principal functor determines which function or predicate is being defined.
For example, the following three items are clauses. The first is a function fact that defines a function named ‘loop/1’, a not particularly useful function. The second is a predicate fact and the third is a predicate rule, which between them define a predicate named ‘append/3’.
loop(X) = 1 + loop(X). append([], Bs, Bs). append([X | As], Bs, [X | Cs]) :- append(As, Bs, Cs).
The following example contains a number of declaration and clause items,
and forms a syntactically valid module.
(The semantics of the clauses will be covered in the next chapter.
Note that the length/1
function in the standard library
is implemented more efficiently.)
:- module slow_length. :- interface. :- import_module list. :- func length(list(T)) = int. :- implementation. :- import_module int. % for '+' length([]) = 0. length([_ | Xs]) = 1 + length(Xs). :- end_module slow_length.
Previous: Builtin operators, Up: Syntax [Contents]