Modified proposal for default decls

Simon Peyton-Jones 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
qualified
   method name, plus the method type.  Other languages doubtless
   lie between

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
implementation
   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
way,
   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.


Notice that
	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
story

	foreign import ccall "gtk:foo" foo :: Int -> IO Int

* "ccall" is one of a small number of language specifiers, "java" and
".net"
   "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
a "new"
   constructor etc.

*  The "gtk:" part is a concession to (b).  It specifies a C package
from which 
   this procedure comes. There is then some compiler-specific mechanism
   for mapping the name of a C package to the location of its header
files and
   .o file.

* If the Haskell compiler wants to typecheck the import, it is free to
consult
  the header file, meta data or whatever, based on the foreign package
name
  and the name of the thing being called.


No "foreign library",  no "foreign default"...  You get to repeat
everything at
every foreign import.  Notice that cross-module exports of inlinings are
now
straightforward: the foreign call carries its package name with it.


You may think this is too minimalist, but there are big advantage to
simple,
minimal designs, even if they can't cope with every single case.  Do we
really
need the elaboration of Malcolm's proposal?

Simon




More information about the FFI mailing list