Manuel The FFI discussion seems to be completely stalled. Would you, as our Tsar, like to summarise the state of play, and re-invigorate it? We don't have a plan at the moment; nor do we have even a draft FFI document (the one you are going to write!). I'm concerned that we'll just dribble on and lose morale. Simon Here's my contribution to re-invigoration: As I recall the main sticking point is whether we have a global 'foreign library' declaration in addition to foreign import etc. The main (only?) motivation for such a thing is C It's a powerful motivation because C is ubiquitous. I do have one suggestion to elaborate our earlier proposal. To remind you our simple-minded proposal was * no 'foreign library' decl * the c-language-specific string on a foreign import could say foreign import "gtk:foo" foo :: <type> with 'gtk' indicating which foreign package was indicated Main complaint was: the package-name => what-to-do mapping still isn't specified. In short, our simple-minded proposal is too simple-minded to be useful. OK so the new suggestion is this: the 'gtk' indicates 'please #include gtk.h'. It's up to you to have a 'gtk.h' lying around, in which you can put all the other #includes (including whether in <> brackets or "" quotes) to your heart's content. I bet this still doesn't solve the problem entirely, but maybe it solves enough of the problem. I remain reluctant to generate elaborate designs for a single language. Simon
"Simon Peyton-Jones" <simonpj@microsoft.com> wrote,
Here's my contribution to re-invigoration:
As I recall the main sticking point is whether we have a global 'foreign library' declaration in addition to foreign import etc. The main (only?) motivation for such a thing is
C
It's a powerful motivation because C is ubiquitous. I do have one suggestion to elaborate our earlier proposal. To remind you our simple-minded proposal was
* no 'foreign library' decl * the c-language-specific string on a foreign import could say foreign import "gtk:foo" foo :: <type> with 'gtk' indicating which foreign package was indicated
Main complaint was: the package-name => what-to-do mapping still isn't specified. In short, our simple-minded proposal is too simple-minded to be useful.
OK so the new suggestion is this: the 'gtk' indicates 'please #include gtk.h'. It's up to you to have a 'gtk.h' lying around, in which you can put all the other #includes (including whether in <> brackets or "" quotes) to your heart's content.
I bet this still doesn't solve the problem entirely, but maybe it solves enough of the problem. I remain reluctant to generate elaborate designs for a single language.
I completely agree that we should have a simple solution and achieve more convenient interfaces via the existing FFI tools. I propose the following (basically my last proposal plus suggestions made by others): foreign import "gtk.h:foo" foo :: <type> corresponds to a `#include "gtk.h"' and foreign import "<gtk.h>:foo" foo :: <type> corresponds to a `#include <gtk.h>'. The former allows to have a custom `gtk.h' "lying around" as suggested above. The filename may of course be a path. As suggested by SimonM, we also allow multiple includes seperated by comma foreign import "<sys/types.h>,<sys/sockets.h>:socket" socket :: <type> (This could be solved by a custom header, too, but IMHO allowing a list of headers doesn't complicate the implementation much, but makes a common case more convenient.) foreign import/export modifiers like unsafe and dynamic can be in arbitrary order (proposed by SimonPJ). "foreign export dynamic" requires a result type of the form IO (FunPtr prim_type) (proposed by Sven). (Of course, concrete implemenatations - like the one in GHC and nhc - may support the old syntax for backward compatibility.) Rationale ~~~~~~~~~ This is easy to implement and as close as possible to the current syntax while still being better suited for multiple languages. It is not as flexible as the proposal from Marcin and Malcolm, but significantly simpler. More sophisticated interfaces can be realised on top of the basic FFI interface by tools. Proposed decision procedure ~~~~~~~~~~~~~~~~~~~~~~~~~~~ I propose that if nobody can come up with an important scenario that cannot be implemented with the above proposal, we adopt the proposal. (Here "cannot be implemented" means technically infeasable, not less convenient.) If we adopt the proposal, I will define it in detail. Cheers, Manuel
I like this nice, simple design. I'm a little uncertain about the multiple header-file aspect but have no strong feelings either way. If most libraries could be ffi'd without the need for additional C files, the multiple header file notation would be an obvious win. As it is, many libraries I've dealt with need one or more .c files containing some support code and, in that case, it's not too big a deal to add another file. Some questions though. Suppose I have two ffi decls with differing orders of files:
foreign import "<foo.h>,<bar.h>:f" f :: <type> foreign import "<bar.h>,<foo.h>:f" g :: <type> Should I report an error?
Or, suppose I have:
foreign import "<foo.h>:f" f :: <type> foreign import "<bar.h>:g" g :: <type> foreign import "<foo.h>:h" h :: <type>
can I assume that foo.h will only be included once? can I assume that foo.h is included before bar.h? (When answering, remember that an optimising compiler might combine code from multiple modules (possibly with multiple maintainers) into a single C source file due to cross-module inlining.) -- Alastair
Wed, 28 Mar 2001 12:10:46 -0700, Alastair Reid <reid@cs.utah.edu> pisze:
If most libraries could be ffi'd without the need for additional C files, the multiple header file notation would be an obvious win.
As it is, many libraries I've dealt with need one or more .c files containing some support code and, in that case, it's not too big a deal to add another file.
I think that since usually there is a C header associated with the module, it's not a problem to put original C headers there. I prefer minimal header information at each foreign declaration, so it would refer only to the custom module. hsc2hs fits into this model. The user can let it choose the right form for compilers supporting or not supporting the discussed feature, e.g. foreign import #{fun "Foo", "f"} unsafe f :: Type or better #module "Foo" foreign import #{fun "f"} unsafe f :: Type
foreign import "<foo.h>,<bar.h>:f" f :: <type> foreign import "<bar.h>,<foo.h>:f" g :: <type> Should I report an error?
No.
foreign import "<foo.h>:f" f :: <type> foreign import "<bar.h>:g" g :: <type> foreign import "<foo.h>:h" h :: <type>
can I assume that foo.h will only be included once? can I assume that foo.h is included before bar.h?
No. Since headers from multiple declarations can be put into one file, they may come in arbitrary order. You may get more headers than requested, but not less. Particularly the compiler is allowed to collect headers from all foreign declarations and attach them to the module itself, and to arbitrarily combine headers from various modules when C function calls are inlined across modules. The compiler is not forced to detect duplicates, but I would expect it to do so at least for declarations coming from a single module (so cpp doesn't need to process the header a hundred times). -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK
qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk) wrote,
Wed, 28 Mar 2001 12:10:46 -0700, Alastair Reid <reid@cs.utah.edu> pisze:
If most libraries could be ffi'd without the need for additional C files, the multiple header file notation would be an obvious win.
As it is, many libraries I've dealt with need one or more .c files containing some support code and, in that case, it's not too big a deal to add another file.
I think that since usually there is a C header associated with the module, it's not a problem to put original C headers there. I prefer minimal header information at each foreign declaration, so it would refer only to the custom module.
I have usually not needed an extra (custom) header file associated with Haskell modules, but maybe the libraries that bound where just exceptionally well behaved. "Alastair Reid" <reid@cs.utah.edu> wrote,
foreign import "<foo.h>,<bar.h>:f" f :: <type> foreign import "<bar.h>,<foo.h>:f" g :: <type> Should I report an error?
Or, suppose I have:
foreign import "<foo.h>:f" f :: <type> foreign import "<bar.h>:g" g :: <type> foreign import "<foo.h>:h" h :: <type>
can I assume that foo.h will only be included once? can I assume that foo.h is included before bar.h?
(When answering, remember that an optimising compiler might combine code from multiple modules (possibly with multiple maintainers) into a single C source file due to cross-module inlining.)
That's a very good argument in favour of SimonPJ's proposal,
Its easy to add features and nigh impossible to remove them. I suggest we have just
"gtk:foo"
(no ".h") meaning #include "gtk.h" Now we can sensibly interpret "gtk:foo" as meaning "foo from package gtk"; and in concrete terms import a suitable header file.
Ok. I think, this scheme is sufficient and Alastair has pointed out the semantic difficulties of a more complex scheme. Moreover, Marcin seems to favour it, too. Any objections? Manuel
participants (4)
-
Alastair Reid -
Manuel M. T. Chakravarty -
qrczak@knm.org.pl -
Simon Peyton-Jones