C++ provides a number of features that make it possible to define a more natural and concise interface to dynamically typed languages than plain C does. Using type-conversion (casting) and overloading, native data-types can be easily translated into appropriate Prolog types, automatic destructors can be used to deal with most of the cleanup required and C++ exception handling can be used to map Prolog exceptions and interface conversion errors to C++ exceptions, which are automatically mapped to Prolog exceptions as control is turned back to Prolog.
However, there are subtle differences between Prolog and C++ that can lead to confusion; in particular, the lifetime of terms do not fit well with the C++ notion of constructor/destructor. It might be possible to handle this with “smart pointers” , but that would lead to other complications, so the decision was made to provide a thin layer between the underlying C functions and the C++ classes/methods/functions.
More information on the SWI-Prolog native types is given in Interface Data Types.
It would be tempting to use C++ implicit conversion operators and
method overloading to automatically convert between C++ types such as
std::string
and int64_t
and Prolog foreign
language interface types such as term_t
and atom_t
.
However, types such as term_t
are unsigned integers, so
many of the automatic type conversions can inadvertently do something
other than what the programmer intended, resulting in subtle bugs that
are difficult to find. Therefore Version 2 of this interface reduces the
amount of automatic conversion and introduces some redundancy, to avoid
these subtle bugs, by using “getter” methods rather than
conversion operators, and using naming conventions for explicitly
specifying constructors.
I would like to thank Anjo Anjewierden for comments on the definition, implementation and documentation of the original C++ interface. Peter Ludemann implemented the current version (2) of the interface (see section 1.1).