\section{External Functions}
\label{sec-external-functions}

\index{function!external}\index{external function}
Currently, \CYS has no general interface to external functions.
Therefore, if a new external function should be added
to the system, this function must be declared as \code{external}
in the Curry source code
and then an implementation for this external function
must be inserted in the corresponding back end.
An external function is defined as follows in the Curry source code:
\begin{enumerate}
\item
Add a type declaration for the external function somewhere
in the body of the appropriate file (usually, the prelude
or some system module).
\item
For external functions it is not allowed to define any
rule since their semantics is determined by an external implementation.
Instead of the defining rules, you have to write
\begin{curry}
f external
\end{curry}
somewhere in the file containing the type declaration for 
the external function \code{f}.
\end{enumerate}
For instance, the addition on integers can be declared as
an external function as follows:
\begin{curry}
(+) :: Int -> Int -> Int
(+) external
\end{curry}
The further modifications to be done for an inclusion of
an external function has to be done in the back end.
A new external function is added to the back end of \CYS
by informing the compiler about the existence of an external function
and adding an implementation of this function in the run-time
system. Therefore, the following items must be added
in the \CYS compiler system:
\begin{enumerate}
\item
If the Curry module \code{Mod} contains external functions,
there must be a file named \code{Mod.pakcs} containing the
specification of these external functions. The contents of this file
is in XML format and has the following general structure:\footnote{%
\url{http://www.informatik.uni-kiel.de/~pakcs/primitives.dtd} contains a DTD
describing the exact structure of these files.}
\begin{curry}
<primitives>
  $\textit{specification of external function~}f_1$
  $\ldots$
  $\textit{specification of external function~}f_n$
</primitives>
\end{curry}
The specification of an external function $f$
with arity $n$ has the form
\begin{curry}
<primitive name="$f$" arity="$n$">
  <library>lib</library>
  <entry>pred</entry>
</primitive>
\end{curry}
where \code{lib} is the Prolog library (stored in the directory of the
Curry module or in the global directory
\code{\cyshome/src/lib_src}) containing the code implementing this
function and \code{pred} is a predicate name in this library
implementing this function. Note that the function $f$ must be
declared in module \code{Mod}: either as an external function
or defined in Curry by equations. In the latter case,
the Curry definition is not translated but calls to this function
are redirected to the Prolog code specified above.

Furthermore, the list of specifications can also contain entries of the form
\begin{curry}
<ignore name="$f$" arity="$n$" />
\end{curry}
for functions $f$ with arity $n$ that are declared in module \code{Mod}
but should be ignored for code generation, e.g., since they are
never called w.r.t.\ to the current implementation of external functions.
For instance, this is useful when functions that can
be defined in Curry should be (usually more efficiently) are implemented
as external functions.

Note that the arguments are passed in their current (possibly unevaluated) form.
Thus, if the external function requires the arguments to be evaluated
in a particular form, this must be done before calling the external function.
For instance, the external function for adding two integers
requires that both arguments must be evaluated to non-variable head normal form
(which is identical to the ground constructor normal form). Therefore,
the function \ccode{+} is specified in the prelude by
\begin{curry}
(+)   :: Int -> Int -> Int
x + y = (prim_Int_plus $\$$# y) $\$$# x

prim_Int_plus :: Int -> Int -> Int
prim_Int_plus external
\end{curry}
where \code{prim_Int_plus} is the actual external function implementing
the addition on integers. Consequently, the specification file
\code{Prelude.pakcs} has an entry of the form
\begin{curry}
<primitive name="prim_Int_plus" arity="2">
  <library>prim_standard</library>
  <entry>prim_Int_plus</entry>
</primitive>
\end{curry}
where the Prolog library \code{prim_standard.pl} contains the Prolog code
implementing this function.

\item
For most external functions, a \emph{standard interface} is
generated by the compiler so that an $n$-ary function can be
implemented by an $(n+1)$-ary predicate where the last argument must
be instantiated to the result of evaluating the function.  The
standard interface can be used if all arguments are ensured to be
fully evaluated (e.g., see definition of \code{(+)} above) and no
suspension control is necessary, i.e., it is ensured that the
external function call does not suspend for all arguments.
Otherwise, the raw interface (see below) must be used.  For
instance, the Prolog code implementing \code{prim_Int_plus}
contained in the Prolog library \code{prim_standard.pl} is as
follows (note that the arguments of \code{(+)} are passed in reverse
order to \code{prim_Int_plus} in order to ensure a left-to-right
evaluation of the original arguments by the calls to \code{(\$\#)}):
\begin{curry}
prim_Int_plus(Y,X,R) :- R is X+Y.
\end{curry}

\item
The \emph{standard interface for I/O actions}, i.e., external functions
with result type \code{IO~a}, assumes that the I/O action
is implemented as a predicate (with a possible side effect)
that instantiates the last argument to the returned value of type \ccode{a}.
For instance, the primitive predicate \code{prim_getChar}
implementing prelude I/O action \code{getChar}
can be implemented by the Prolog code
\begin{curry}
prim_getChar(C) :- get_code(N), char_int(C,N).
\end{curry}
where \code{char_int} is a predicate relating the internal
Curry representation of a character with its ASCII value.

\item
If some arguments passed to the external functions are not fully evaluated
or the external function might suspend, the implementation must follow
the structure of the \CYS run-time system by using
the \emph{raw interface}. In this case, the name of the external entry
must be suffixed by \ccode{[raw]} in the \code{pakcs} file.
For instance, if we want to use the raw interface for the external function
\code{prim_Int_plus},
the specification file \code{Prelude.pakcs} must have an entry of the form
\begin{curry}
<primitive name="prim_Int_plus" arity="2">
  <library>prim_standard</library>
  <entry>prim_Int_plus[raw]</entry>
</primitive>
\end{curry}
In the raw interface, the actual implementation of an $n$-ary external function consists
of the definition of an $(n+3)$-ary predicate $pred$.
The first $n$ arguments are the corresponding actual arguments.
The $(n+1)$-th argument is a free variable which must be
instantiated to the result of the function call after
successful execution. The last two arguments
control the suspension behavior of the function
(see \cite{AntoyHanus00FROCOS} for more details):
The code for the predicate $pred$
should only be executed when the $(n+2)$-th argument
is not free, i.e., this predicate has always the
SICStus-Prolog block declaration
\begin{curry}
?- block $pred$(?,$\ldots$,?,-,?).
\end{curry}
In addition, typical external functions should suspend
until the actual arguments are instantiated. This can be ensured
by a call to \code{ensureNotFree} or \code{(\$\#)}
before calling the external function. Finally, the
last argument (which is a free variable at call time)
must be unified with the $(n+2)$-th argument
after the function call is successfully evaluated
(and does not suspend). Additionally, the actual (evaluated) arguments
must be dereferenced before they are accessed.
Thus, an implementation
of the external function for adding integers is as follows in the raw interface:
\begin{curry}
?- block prim_Int_plus(?,?,?,-,?).
prim_Int_plus(RY,RX,Result,E0,E) :-
     deref(RX,X), deref(RY,Y), Result is X+Y, E0=E.
\end{curry}
Here, \code{deref} is a predefined predicate for dereferencing the
actual argument into a constant (and \code{derefAll} for dereferencing
complex structures).
\end{enumerate}
%
The Prolog code implementing the external functions must be accessible to the run-time
system of \CYS by putting it into the directory containing the corresponding
Curry module or into the system directory
\code{\cyshome/src/lib_src}.
Then it will be automatically loaded into the run-time environment
of each compiled Curry program.

Note that arbitrary functions implemented in C or Java can be connected to
\CYS by using the corresponding interfaces of the underlying Prolog system.


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "manual"
%%% End: 
