Next: , Previous: Declaring impurity, Up: Impurity   [Contents]

15.5 Marking a goal as impure

If predicate p/N is declared to be impure (semipure) then all calls to p/N must be annotated with impure (semipure):

impure p(X1, X2, …, XN)

If function f/N is declared to be impure (semipure) then all applications of f/N must be obtained by unification with a variable and the unification goal as a whole be annotated with impure

impure X = f(X1, X2, …, XN)

Any call or unification goal containing a non-local variable with inst any that appears in a negated context (i.e., in a negation or in the condition of an if-then-else goal) must be given an impure annotation because it may violate referential transparency.

Compound goals should not have purity annotations.

The compiler will report an error if a required purity annotation is omitted from a call or unification goal or if a semipure annotation is used where an impure annotation is required. The compiler will report a warning if a semipure goal is annotated with impure or a pure goal is annotated with semipure.

The requirement that impure or semipure calls be marked with impure or semipure allows someone reading the code to tell which goals are not pure, making code which relies on side effects somewhat less mysterious. Furthermore, it means that if a call is not preceded by impure or semipure, then the reader can rely on the call having a proper declarative semantics, without hidden side-effects.