IDL: Writing the module interface

The Interface Definition Language is an attempt to specify the interface of a programming module in a language-independent fashion; the middleware brokers CORBA, COM, and others support some sort of IDL, and HaskellDirect follows suit. Without getting into a long explanation of IDL, we present the interface definition for the above beta_0 and beta_1 functions:

Example 13-4. IDL for our exported regression functions

module Regression {
  [pure]double beta_0( [in, size_is(len_xs)]double* xs, [in]int len_xs, [in, size_is(len_ys)]double* ys, [in]int len_ys );
  [pure]double beta_1( [in, size_is(len_xs)]double* xs, [in]int len_xs, [in, size_is(len_ys)]double* ys, [in]int len_ys );
}

The above deserves some explanation. Line 1 simply declares the module and its name (Regression). Each line between the curly brackets declares an exported function, looking much the same as a C++ function declaration but with some specification on several items:

  1. The return value is declared to be [pure]double; this means that the return value will be a double value, but also that the function will be pure--it will have no side effects.

  2. Each of the parameters is declared to be "in"--meaning that it will not be changed during the course of function execution.

  3. Each of the array parameters is declared to be "size_is(len_xs)" (or "size_is(len_ys)")--this comes from the fact that arrays are handled differently by different languages, and means that we have to pass the length of the array along with the array itself. The size_is declaration is extremely important to the HaskellDirect code generator, because it enables the arrays of doubles to be marshaled directly into Haskell lists--vital for their manipulation!

With the Regression.hs file containing our function declarations and the Regression.idl file containing our IDL for this module, we're ready to fire up the HaskellDirect ihc command and get our C-compatible stubs by typing the rather formidable command line

ihc -s -fhs-to-c --gen-headers -fuse-ints-everywhere --output-h=Regression.h -c Regression_proxy.idl -o Regression_proxy.hs

It's an impressive command line, which makes it even more disappointing when the resultant code refuses to compile, and ghc spews screens full of type errors when it tries to parse the resultant Haskell code.