11.1 Compiling Procedures as Dynamic or Static
If it is intended that
a procedure be altered through the use of assert/1 and retract/1,
the system should be informed that the procedure will be dynamic,
since these predicates are
designed to work on dynamic procedures.
If assert/1 is applied on a non-existing procedure, an error
is raised, however the default error handler for this error
only declares the procedure as dynamic and then makes the assertion.
A procedure is by default static unless it has been specifically declared as
dynamic.
Clauses of static procedures must always be consecutive,
they may not
be separated in one or more source files or by the user from the top level.
If the static procedure clauses are not consecutive, each of the
consecutive parts is taken as a separate procedure which redefines
the previous occurrence of that procedure, and so only the last one will
remain.
However, whenever the compiler encounters nonconsecutive clauses of a static
procedure in one file, it raises an exception whose default handler
prints a warning but it continues to compile the rest of the file.
If a procedure is to be dynamic the ECLiPSe system should be
given a specific dynamic declaration
A dynamic declaration takes the form
:- dynamic SpecList.
The predicate is_dynamic/1 may be used to check if a procedure
is dynamic:
is_dynamic(Name/Arity).
When the goal
compile(Somefile)
is executed
and Somefile contains clauses for procedures that have
already been defined
in the Prolog database, those procedures are treated in one of two ways:
If such a procedure is dynamic, its clauses compiled from Somefile
are added to the database (just as would happen if they were asserted),
and the existing clauses are not affected.
For example, if the following
clauses have already been compiled:
:- dynamic city/1.
city(london).
city(paris).
and the file Somefile contains the
following Prolog code:
city(munich).
city(tokyo).
then compiling Somefile will cause adding
the clauses for city/1 to those
already compiled, as city/1 has been declared dynamic.
Thus the query city(X) will give:
[eclipse 5]: city(X).
X = london More? (;)
X = paris More? (;)
X = munich More? (;)
X = tokyo
yes.
If, however, the compiled procedure is static,
the new clauses in Somefile replace the old procedure.
Thus, if
the following clauses have been compiled:
city(london).
city(paris).
and the file Somefile contains the following Prolog code:
city(munich).
city(tokyo).
when Somefile is compiled, then the procedure city/1 is redefined.
Thus the query city(X) will give:
[eclipse 5]: city(X).
X = munich More? (;)
X = tokyo
yes.
When the dynamic/1 declaration is used on a procedure that is
already dynamic, which may happen for instance by recompiling a file
with this declaration inside, the system raises the error 64,
'procedure already dynamic'.
The default handler for this error, however, will only erase
all existing clauses for the specified procedure, so that
when such a file is recompiled several times during its debugging,
the system behaves as expected, the existing clauses
are always replaced.
The handler for this error can of course be changed if required.
If it is set to true/0, for instance,
the dynamic/1 declaration is be just silently
accepted without erasing any clauses and without printing an error message.