Modification to foreign import/export

Marcin 'Qrczak' Kowalczyk qrczak at knm.org.pl
Mon Feb 12 12:49:32 EST 2001


Mon, 12 Feb 2001 09:50:07 -0700, Alastair Reid <reid at cs.utah.edu> pisze:

> Note that this can be done without separating the library name from
> the ffi decl:
> 
> #ifdef UNIX
> # define LIBNAME "foo.so"
> #else
> # define LIBNAME "foo.dll"
> #endif
> 
> foreign import ... LIBNAME ...
> foreign import ... LIBNAME ...
> foreign import ... LIBNAME ...

Only if you use cpp. With hsc2hs you have #ifdef but #define like
this is harder (although possible).

> Just to be clear that I understand this argument, you're saying that:
> 
>   It is ok to severely break order independence in the ffi because it is
>   already mildly broken in normal module import?

Yes.

> This is just another source of confusion for the baffled programmer.
> (And more clutter for a language that already needs to go on a diet.)

An alternative is either a global set of options for each Haskell
module or repeating things with each foreign declaration. Both are
not quite satisfactory: the former imposes an arbitrary restriction,
the latter is inconvenient.

We could also allow to override things specified globally in individual
definitions. This should combine the best of both solutions. In this
case we just must design a nice, consistent and extensible syntax.

> > Here is a concrete proposal:
> > [proposal deleted]
> 
> Looks like a massive extension to the ffi definition.
> What does all this complexity buy us?

The ability to specify #include files in a portable way, instead of
relying on compiler-specific methods (-#include commandline option
for ghc, not needed for nhc98).

If a Haskell implementation needs to know from which library to take
which function, e.g. an interpreter using dlopen/dlsym, then again
this must be specified somehow. We could invent a way to encode it in
the foreign function name, but it has disadvantages: the name might
not be constant (e.g. ncurses or curses determined at configure time)
and it would have to be repeated for each function.

When I import many stdcall functions, I must currently write stdcall
with each declaration. Similarly when I link to another language
(this is not a problem now when the only language is C, but it will
be a problem when more languages are supported).

> Wouldn't it be better to fix on a C/Pascal-like interface on the
> Haskell side and implement a series of similar ffi's for Java, C++,
> etc. which also target a C/Pascal-like interface?  Now if I want
> to call Java code, I use ffi/Java to construct C-like exports for
> the Java library and I use ffi/Haskell to generate C-like imports
> for the Haskell library.

Why I should be require to wrap everything in C if the compiler can
be designed to do that for me?

Imagine a Haskell implementation compiled to JVM. It would be stupid
to let Java talk with Jaba through C, but otherwise it would be
unportable.

> On the plus side, this style of narrow-waisted architecture is much,
> much easier to maintain, concentrates debugging/development effort
> on just one interface, provides utility to people on both sides of
> the interface (because a C++ programmer could use the exports from
> the Java library too), is simpler, is more flexible, ...

Surely maintaining just a C compiler is easier than maintaining both
C and Haskell compilers. So what, abandon Haskell because using C
for everything is simpler for compiler writers?

> ps Could I propose that any proposed new keywords be prefixed by __
> or ffi_ or something like that.  Adding keywords like "library"
> (i.e., ordinary useful words that programmers might already be
> using as variable names) breaks a lot of code.

Of course they are not keywords in any context except foreign language
declaration. That's why I wrote "pseudokeywords".

-- 
 __("<  Marcin Kowalczyk * qrczak at knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZASTÊPCZA
QRCZAK





More information about the FFI mailing list