extended foreign decls

malcolm-ffi at cs.york.ac.uk malcolm-ffi at cs.york.ac.uk
Wed Dec 6 11:35:51 EST 2000

Fergus writes, triggered by my suggestion of "foreign value":

> Mercury supports this using `foreign_decls' and `foreign_code' pragmas.

I refrained from proposing this in an earlier mail, but I've been
thinking about it for a long time.  I *really* *really* want to be
able to insert small snippets of foreign code into the source of
a Haskell module.

GreenCard allows you to do this, via the %- or %C directives.  It is
one of the features I miss most about the new FFI.  I know that it
is always possible to write a small .c file and compile and link it
in separately, but with the new FFI that now seems to necessitate
writing an additional .h file as well.  And all for a handful of lines
of foreign code that could easily be kept in the Haskell source, with
the ease-of-comprehension benefits entailed by keeping everything
together that belongs together.

For instance, in the new FFI I often want to do something like

    foreign code { #include <dirent.h> }
    foreign import opendir :: Ptr String -> IO (Ptr DIR)

Ok, you might argue that ghc already lets you do #include's.  But it
isn't part of the agreed FFI, and other compilers don't have that
feature.  And often I want to do just a tiny bit more than a simple

    foreign code { #include <string.h> }
    foreign import readdirent :: Ptr DIR -> IO (Ptr String)
    foreign code C {
      char *readdirent (DIR*d) {
        struct dirent *e;
        e = readdir(d);
        return e->d_name;

I propose that
    foreign code <language-id> { <code> }
should simply cause the verbatim copying of the <code> part into a
file to be compiled by the appropriate foreign compiler.  That's all.
Nothing fancy.

The facility I propose is very similar to what Fergus described in
Mercury, but I came up with it independently.  As people have pointed
out, we need to avoid being totally C-centric, which is why there
needs to be a language identifier attached.  We can argue over exact
syntax if you like, but I think the facility is desperately needed.

> 	:- pragma foreign_decls(c, "
> 		#define _POSIX_SOURCE 1
> 		extern int my_global;
> 	").

Fergus, could you enlighten me some more about the difference between
the foreign_decls and foreign_code pragmas?  I'm afraid I can't
immediately see why you have both.

> the Mercury compiler extracts the foreign_decl and
> foreign_code stuff, wrapping code in the second form of foreign_code
> up inside appropriate function definitions, and puts them all in a
> separate file that it then invokes the foreign language compiler on.

And I would expect a Haskell compiler to do something similar.  For C,
Java, and the like, this would be fairly easy for the compiler writer
to provide.  But in the general case, I'd guess that there should be
some sort of configurable "plugin" interface, by which an ordinary
user could tell the the Haskell compiler about
    foreign language name:	Wibble
    compiler name:		wblc
    default options:		-fno-flubble-mangling
    extra linking options:	-lwibblelib
and such like, so that they could use the FFI for whatever language
they pleased.

> > Don't forget about specifying which C compiler to use and
> > with which options, e.g. which include paths.
> Those are not part of the language.  Those are specified by options
> which you pass to the Mercury compiler, or more likely put in your
> makefile.  E.g. to compile the C example you could use
> 	mmc --cc gcc --cflags "-I/foo/bar" example.m

Just as ghc currently provides the OPTIONS pragma
    {-# OPTIONS -fallow-overlapping-instances #-}
to control Haskell compiler flags within the source, I can imagine a
    {-# FOREIGN OPTIONS Wibble -fallow-flubble-mangling #-}
or similar for foreign compiler calls.  Such pragmas may not be
required, but they should be possible.

> I certainly consider the mechanism that Mercury
> uses to be elegant enough to be the official Mercury FFI,
> and I hope our standards are not so much lower than yours ;-)

I agree.  In fact, I was mighty impressed to see that you'd already
implemented my proposal in Mercury before I even proposed it.  :-)

Comments are eagerly solicited.


More information about the FFI mailing list