I’m trying to check whether a certain arithmetic function (specifically the 2-argument version of log
) is available, so that I can conditionally use that function if possible and emulate it otherwise.
The obvious solution would be to just try calling the function and checking if it works or not, like catch(_Res is log(2, 4), _Error, false)
. Unfortunately this doesn’t always work reliably on SWI - if library(arithmetic) has been loaded, it tries to perform term/goal expansion on the right-hand side of (is)/2, which throws an error on unknown functions. Because the error is thrown during term/goal expansion rather than during execution, it isn’t caught by the catch/3 call.
As a workaround, I rewrote the check to use a meta-call, in the hope of forcing the term/goal expansion to happen inside the catch/3, so that errors from the expansion are caught: Code = (_Res is log(2, 4)), catch(Code, _Error, false)
. This seems to work (tested with the current development version of SWI built from source), but I’m not sure if this is a reliable way to catch errors from term/goal expansion or if it might break in the future…
SWI-Prolog provides current_arithmetic_function/1 for querying which arithmetic functions are available, but as far as I can tell, this predicate is entirely SWI-specific, so it’s not very useful for writing portable code. I suppose I could first try to use current_arithmetic_function/1, and only if that predicate isn’t available fall back to the catch/3-based check?