The behaviour of the predicate setup_call_cleanup/3 is described in . Our implementation is based on a dissection of this behaviour into the system predicates sys_atomic_call/1 and sys_on_cleanup/1. The implementation needs the newly introduced cutter mechanism.
During the implementation here and then we did not closely follow the ISO proposal. At the moment the following behavioural discrepancies are known:
Some of the discrepancies have simple workarounds. If pre-validation is needed one could invoke setup_call_cleanup/3 as follows:
(var(C) -> sys_throw_error(instantiation_error);
\+ callable(C) -> sys_throw_error(
true)), G, C).
If no exception accumulation is needed one could invoke the setup_call_cleanup/3 as follows:
throw_cause(cause(_,E)) :- !, throw_cause(E).
throw_cause(E) :- throw(E).
?- catch(setup_call_cleanup(S, G, C), E, throw_cause(E))).
If no exception on failure is needed one could invoke the
setup_call_cleanup/3 as follows:
?- setup_call_cleanup(S,G, (C;true)).
WG17 N215, ISO 3
WG17 N215, ISO 25
WG17 N215, ISO 26
WG17 N215, ISO 27
WG17 N215, ISO 9
WG17 N215, XLOG 12