Summary of current change suggestions
Manuel M. T. Chakravarty
chak at cse.unsw.edu.au
Wed Feb 21 00:01:48 EST 2001
malcolm-ffi at cs.york.ac.uk wrote,
> I think we're all agreed now on the desirability of tweaking the FFI
> to permit
> (a) arbitrary new foreign languages to be added;
> (b) the "foreignname" specifier to be (potentially) richer, depending
> on the particular foreign language in question;
> (c) abstraction of common header/linklib information to a single
> new sort of decl.
> For backwards compatibility, I suppose on (b) we are going to have
> to continue to allow double-string specifiers of the form
> foreign import "linklib" "cname" hname :: type
> for some time, although that form would be deprecated from now on?
Yes, that's how I see it.
> We know mostly what the richer form of the "foreignname" specifier
> will be for Java, and in any case we can leave that design to SPJ+EM.
> However, we have also heard one or two half-hearted suggestions to
> enrich the "foreignname" string for C as well. For instance, Manuel
> suggested "Gtk: gtk_new_window". Is anyone convinced that this
> is a good route for C, or should we settle instead on getting (c)
> right, leaving the "foreignname" untouched for now?
We might be able to combine the two - see below.
> As far as (a) is concerned, we have three decisions to make:
> (1) Do we use quotes around the language name or accept a simple
> varid? E.g. "java" vs java. As Marcin points out, the names
> of the languages C and C++ are not varids, so would need to
> be enclosed in quotes. On the other hand, see decision point
> (2) below.
> (2) The actual names for languages or calling conventions. Manuel
> suggests a change from naming the calling convention to naming
> the foreign language. This is somewhat attractive. However,
> I think many languages have a simple C-callable interface and
> we don't need to know anything more about the actual language.
> If this is true, I think we should continue to name the calling
> convention rather than the language. Hence, the names ccall
> and stdcall might be retained, java can be added. If anyone
> actually comes up with a C++ binding, a name like cplusplus
> (for instance) seems good enough to me. This also has the
> advantage of backwards compatibility, which incidentally would
> force decision point (1) above towards no-quotes.
I think, I retract my proposal to change ccall to c (you
convinced me). Let's just stick with the simple varids.
> Incidentally, the intention would _not_ be that all compilers
> must support all foreign languages. As at present, only
> the ccall convention is mandatory. Any other named calling
> convention should be parsed, but if the compiler doesn't support
> it, a warning (at least) should be issued. In that situation,
> it is unclear whether the compiler can actually generate sensible
> code. (At the moment, I think the FFI standard says if your
> platform doesn't support stdcall, code should default to ccall?
> Obviously that doesn't scale well to java for instance!)
I think, when the compiler supports an unsupported calling
convention it should abort. stdcall defaulting to ccall is
IMHO just a hack.
> (3) Where do we allow the language specifier? In my opinion,
> definitely in foreign import and export decls. This is at
> minimum for backwards compatibility, but looking forward to the
> day when someone writes FFI code for more than one language in
> the same module (eek!), it will be needed there. For the same
> reason, I would argue that it belongs in the new kind of decl
> required for (c).
I agree. In fact, I quite liked one of the proposals that
you made earlier, namely
foreign library C "<ncurses/curses.h>" "-lcurses"
foreign library java "blah" "blah"
foreign import C "curses_function" cf :: Int -> IO Int
foreign import java "java.blah.*/foo" jf :: Int -> IO Int
I also like Marcin's proposal, but I guess it is just too
far away from what we have and quite same work to implement.
So, how about the following. Keep everything string based.
A module can have one "foreign defaults" declaration per
calling convention, which specifies a string.
foreign defaults ccall "<gtk/gtk.h>: "
foreign defaults java "java."
Now all foreign declarations that want to inherit this
string have their "foreignname" string starting with a '*'
(or whatever symbol you prefer)
foreign import ccall
"*gtk_new_window" newWindow :: CInt -> IO (Ptr Window)
foreign import java "*blah.foo" jf :: Int -> IO Int
Otherwise, they can override the default by using a full
foreign import ccall
"<glib/glib.h>: g_timer_start" timerStart :: Ptr Timer -> IO ()
It would be nicer to do without a special symbol indicating
the use of the default, but I guess, this will always lead
to ambiguous situations.
This is, of course, a lot less flexible than what Marcin
proposed, but it would be very simple to implement and is
more or less backwards compatible.
I am not so sure anymore about the specification of link
libraries for C. It wouldn't be a problem, because we can
always extend the "foreignname", eg, something like
"<glib/glib.h>; glib: g_timer_start"
However, it usually doesn't help much, to link to GTK+, you
need to specify use
-L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
which doesn't seem attractive to include in the Haskell
source. Moreover, the flags are system dependent. They
also can't be cleanly handled with #ifdefs, as the only
guarantee that GTK+ gives is that when you execute the
command `gtk-config --libs', it will give you all the right
So, as Marcin pointed out, the only use for a library object
spec for ccall is so that interpreters know which handle to
pass to dlsym(). I am not too fond of the idea that the
interpreter has to try a dlsym() on all library objects that
it did dlopen(). Or is this maybe not too bad?
More information about the FFI