Modified proposal for default decls
simonpj at microsoft.com
Mon Feb 26 10:07:55 EST 2001
| I am reasonably convinced by the need for an extensible
| attribute-style specification such as Marcin has been proposing.
I've been talking about the FFI stuff with Simon and Julian.
We aren't (yet, anyway) convinced by the need for anything
nearly as elaborate as what is now proposed.
Most notably, Malcolm's latest proposal introduces a new form
of abstraction (named thing), a bundle of attributes like Gtk or Bzip.
Another environment for the compiler to manage! Soon people will
want to export these things and import them elsewhere! This
way lies madness.
What is particularly tanatlising is that to a first approximation none
of this is necessary. For example, the native code generator is quite
happy without any of the new stuff now proposed.
I think we can usefully distinguish three kinds of thing:
a) What is necessary to uniquely identify the thing you want to call.
In C this is just a single identifier; in Java, it's a fully
method name, plus the method type. Other languages doubtless
b) What is necessary to allow the compiler to typecheck the
foreign import/export. In part, we seek #includes so that
in the via-C route the C compiler will compare the call with the
prototype, and complain if they don't match. But this is an
thing. In principle, the Haskell compiler could consult type info and
compare. The important thing is that there's enough info to get from
the thing-being-called to the type-of-the-thing-being-called.
c) What is necessary for particular compilers, compiling in a particular
to generate the right code. In particular, GHC compiling via C. GHC
can't generate prototypes, because they might be #included. GHC can't
omit prototypes unless prototypes are guaranteed to be #included.
Hence the motivation to specify #include stuff.
a) is essential
b) is desirable, but not implemented at all
c) is essential, but extremely language and compiler specific
Therefore we propose that
a) be part of the FFI standard
b) be achievable, if desired, via (a)
c) be not part of the FFI standard
In particular, we propose to stick to a mild variant of the current FFI
foreign import ccall "gtk:foo" foo :: Int -> IO Int
* "ccall" is one of a small number of language specifiers, "java" and
"stdcall" being other possibilities. C is strange in having more
than one calling
convention; we treat "stdcall" as a second "language".
* The "gtk:foo" is a string in language-specific format
that uniquely specifies the thing being called. It'll be quite
different for Java,
when it'll contain the type signature of the method and whether it's
* The "gtk:" part is a concession to (b). It specifies a C package
this procedure comes. There is then some compiler-specific mechanism
for mapping the name of a C package to the location of its header
* If the Haskell compiler wants to typecheck the import, it is free to
the header file, meta data or whatever, based on the foreign package
and the name of the thing being called.
No "foreign library", no "foreign default"... You get to repeat
every foreign import. Notice that cross-module exports of inlinings are
straightforward: the foreign call carries its package name with it.
You may think this is too minimalist, but there are big advantage to
minimal designs, even if they can't cope with every single case. Do we
need the elaboration of Malcolm's proposal?
More information about the FFI