This is a topic to discuss the wiki
This is generally not true. Most more recent hooks are defined in the module prolog
, but basically any module may define hooks and several libraries do.
I don’t know about numbers. Bottom line is that assert/1 and retract/1 raise an exception when used on a predicate that exists and static. On a non-existing predicate assert/1 creates the predicate as dynamic. Use dynamic/1 if you want to allow dynamic modification later.
Not sure to what this refers. erase/1 and retract/1 behave the same wrt memory management. Neither physically reclaim the clause as it may be involved in other threads or choice points of the calling thread. They mark the clause and reclaiming the memory is left to the (clause) garbage collector. The reason that temporary installed hooks use
setup_call_cleanup(
asserta(HookTerm, Ref),
ProtectedCode,
erase(Ref))
Is because this makes it trivial remove exactly the added clause. If we use retract/1, it may retract another clause that happens to unify with the one you just added. It may also leave a choice point. Using erase/1 guarantee we have the right clause without any search and without unwanted choice points.
Personal notes (Click triangle to expand)
An overview of hook predicates
Many hook predicates have initialization code in init.pl, e.g. dynamic/1, multifile/1
A list of know hooks is in prolog_xref.pl
Definition of known hooks. Hooks that can be called in any module are unqualified. Other hooks are qualified with the module where they are called.
List as of 09/13/2021
Examples of hooks from GitHub
portray/1 (1)
message_property/2 - Examples exist in code. I don’t know how message_property/2 works.
message_prefix_hook/2 - [1]
Note: Defined in module prolog
not module user
.
ibrary_directory/1 -
Work in progress.
Stopped at this point because I know feel that I understand the mistakes I made as noted by Jan W. and how to correct the Wiki.