directive
uses/2
Description
uses(Object, [Name/Arity, ...])
uses(Object, [Name/Arity as Alias/Arity, ...])
uses(Object, [Predicate as Alias, ...])
uses(Object, [Name//Arity, ...])
uses(Object, [Name//Arity as Alias//Arity, ...])
uses(Object, [op(Precedence, Associativity, Operator), ...])
Declares that all calls made from predicates (or non-terminals) defined
in the category or object containing the directive to the specified
predicates (or non-terminals) are to be interpreted as messages to the
specified object. Thus, this directive may be used to simplify writing
of predicate definitions by allowing the programmer to omit the
Object::
prefix when using the predicates listed in the directive
(as long as the calls do not occur as arguments for non-standard Prolog
meta-predicates not declared on the adapter files). It is also possible
to include operator declarations in the second argument.
This directive is also taken into account when compiling calls to the database and reflection built-in methods by looking into these methods predicate arguments if bound at compile time.
It is possible to specify a predicate alias using the notation
Name/Arity as Alias/Arity
or, in alternative, the notation
Name/Arity::Alias/Arity
. Aliases may be used for avoiding
conflicts between predicates specified in use_module/2
and uses/2
directives, for giving more meaningful names considering the calling
context of the predicates, and for changing the order of the predicate
arguments when calling the predicate. For predicates, is also possible
to define alias shorthands using the notation Predicate as Alias
or,
in alternative, the notation Predicate::Alias
, where Predicate
and Alias
are callable terms where some or all arguments may be
instantiated.
To enable the use of static binding, and thus optimal message sending performance, the objects should be loaded before compiling the entities that call their predicates.
The object identifier argument can also be a parameter variable when using the directive in a parametric object or a parametric category defined in a source file (the common case). In this case, dynamic binding will be used for all listed predicates (and non-terminals). The parameter variable must be instantiated at runtime when the messages are sent.
Template and modes
uses(+object_identifier, +predicate_indicator_list)
uses(+object_identifier, +predicate_indicator_alias_list)
uses(+object_identifier, +predicate_template_alias_list)
uses(+object_identifier, +non_terminal_indicator_list)
uses(+object_identifier, +non_terminal_indicator_alias_list)
uses(+object_identifier, +operator_list)
Examples
:- uses(list, [append/3, member/2]).
:- uses(store, [data/2]).
:- uses(user, [table/4]).
foo :-
...,
% the same as findall(X, list::member(X, L), A)
findall(X, member(X, L), A),
% the same as list::append(A, B, C)
append(A, B, C),
% the same as store::assertz(data(X, C))
assertz(data(X, C)),
% call the table/4 predicate in "user"
table(X, Y, Z, T),
...
Another example, using the extended notation that allows us to define predicate aliases:
:- uses(btrees, [new/1 as new_btree/1]).
:- uses(queues, [new/1 as new_queue/1]).
btree_to_queue :-
...,
% the same as btrees::new(Tree)
new_btree(Tree),
% the same as queues::new(Queue)
new_queue(Queue),
...
An example of defining a predicate alias that is also a shorthand:
:- uses(logtalk, [
print_message(debug, my_app, Message) as dbg(Message)
]).
Predicate aliases can also be used to change argument order:
:- uses(meta, [
fold_left(Closure,Accumulator,List,Result) as foldl(Closure,List,Accumulator,Result)
]).
An example of using a parameter variable in place of the object identifier to allow using the same test set for checking multiple implementations of the same protocol:
:- object(tests(_HeapObject_),
extends(lgtunit)).
:- uses(_HeapObject_, [
as_heap/2, as_list/2, valid/1, new/1,
insert/4, insert_all/3, delete/4, merge/3,
empty/1, size/2, top/3, top_next/5
]).
See also