Mon, 12 Feb 2001 09:50:07 -0700, Alastair Reid <reid@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@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK