# Wiki Discussion: Using message\_hook/3

**URL:** <https://swi-prolog.discourse.group/t/wiki-discussion-using-message-hook-3/4430>\
**Category:** Wiki Discussion\
**Created:** [September 12, 2021, 10:14am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-using-message-hook-3/4430 "2021-09-12T10:14:56Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [September 13, 2021, 8:49am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-using-message-hook-3/4430/2 "2021-09-13T08:49:49Z")

</div>

> [@Using message\_hook/3](https://swi-prolog.discourse.group/t/using-message-hook-3/4429/1):
>
> With [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) hooks are created as predicates in [user module](https://www.swi-prolog.org/pldoc/man?section=resmodules)

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.

> [@Using message\_hook/3](https://swi-prolog.discourse.group/t/using-message-hook-3/4429/1):
>
> AFAIK the times [dynamic/1](https://www.swi-prolog.org/pldoc/doc_for?object=dynamic/1) is needed with [assert/1](https://www.swi-prolog.org/pldoc/doc_for?object=assert/1),2 and [retract/1](https://www.swi-prolog.org/pldoc/doc_for?object=retract/1) outnumber the times when it is not needed.

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.

> [@Using message\_hook/3](https://swi-prolog.discourse.group/t/using-message-hook-3/4429/1):
>
> Notes:
> 
> One would think that if the hook is asserted then [assert/1](https://www.swi-prolog.org/pldoc/doc_for?object=assert/1) would be used to assert [message\_hook/3](https://www.swi-prolog.org/pldoc/doc_for?object=message_hook/3), typically [assert/2](https://www.swi-prolog.org/pldoc/doc_for?object=assert/2) is used to capture the reference to the asserted clause. So what is a refence you ask and why should I care? [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) is written in C and low level Prolog constructs such as a clause are actually C structures ([struct clause](https://github.com/SWI-Prolog/swipl-devel/blob/984bb191bb1c989d4fc930f558ae0906bfbbc339/src/pl-incl.h#L1343-L1361)). I don’t know the reason why [retract/1](https://www.swi-prolog.org/pldoc/doc_for?object=retract/1) does not erase the underlying C structure for a clause but apparently it does not and so the use of [erase/1](https://www.swi-prolog.org/pldoc/doc_for?object=erase/1) is needed. Since [erase/1](https://www.swi-prolog.org/pldoc/doc_for?object=erase/1) needs a reference and the best time to grab a reference is during creation, the reference is returned as part of [assert/2](https://www.swi-prolog.org/pldoc/doc_for?object=assert/2). Thus the typical use of [assert/2](https://www.swi-prolog.org/pldoc/doc_for?object=assert/2) instead of [assert/1](https://www.swi-prolog.org/pldoc/doc_for?object=assert/1). (Remember this is a wiki so just edit this if you know more.)

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

```prolog
    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.

---

_[View the full topic](https://swi-prolog.discourse.group/t/wiki-discussion-using-message-hook-3/4430)._
