Go to the first, previous, next, last section, table of contents.


Functional notation

Author(s): Daniel Cabeza.

Version: 1.11#222 (2004/5/24, 13:8:7 CEST)

Version of last change: 1.9#291 (2004/2/13, 20:46:8 CET)

This library package allows the use of functional notation in a Ciao module/program.

It should be made clear that this package just provides a kind of syntactic sugar for defining and using predicates as if they were functions, and thus any function definition is in fact defining a predicate, and any predicate can be used as a function. The predicate associated to a function has the same name and one more argument, added to the right, to hold the result of the function.

Any term preceded by the operator ~ is a function application, as in write(~arg(1,T)), which is equivalent to the sequence arg(1,T,A), write(A). Functors can be declared as evaluable by using the declaration function/1, and thus avoiding the need to use the operator ~, as in

:- function(arg/2).

Note that this declaration, as is customary in Ciao Prolog, is local to the source code where it is included. In addition, the package defines several functors as evaluable by default, those being:

A functional clause is written using the binary operator :=, as in

opposite(red) := green.

Functional clauses can also have a body, which is executed before the result value is computed. It can serve as a guard for the clause or to provide the equivalent of a where-clause in a functional language:

fact(0) := 1.
fact(N) := N * ~fact(--N) :- N > 0.

Note that often a guard can be better defined using a conditional expression:

fact(N) := N = 0 ? 1
         | N > 0 ? N * ~fact(--N).

In clause heads (either defined as predicates or functions) functors can be prevented from being evaluated by using the (^)/1 prefix operator, as in

pair(A,B) := ^(A-B).

Note that this just prevents the evaluation of the principal functor of the enclosed term, not the possible occurrences of other evaluable functors inside. The operator is by now ignored outside clause heads, due to the recurrent nature of the goal translations used.

When using function applications inside the goal arguments of meta-predicates, there is an ambiguity as they could be evaluated either in the scope of the outer execution or the in the scope of the inner execution. The chosen behavior is by default to evaluate function applications in the scope of the outer execution, and if they should be evaluated in the inner scope, the goal containing the function application needs to be escaped with the (^^)/1 prefix operator, as in findall(X, (d(Y), ^^(X = Y+1)), L) (which could also be written as findall(X, ^^ (d(Y), X = Y+1), L)).

Usage and interface (functions)

Known bugs and planned improvements (functions)


Go to the first, previous, next, last section, table of contents.