Nobody answered, so perhaps everybody agrees :-) Sat, 03 Feb 2001 00:14:56 +1100, Manuel M. T. Chakravarty <chak@cse.unsw.edu.au> pisze:
Re (2): In Java, we obviously want to use qualified names (like "java.lang.foo"), but in the case of dynamic libraries and C calls it is less clear what the syntax should look like. "gtk: gtk_new_window" to specify that the dynamic library "gtk" (on Unix that would happen by loading "libgtk.so") has to be loaded to call the function "gtk_new_window"?
On Linux it is not specified which functions are taken from which library - everything is linked into a flat global namespace. Similarly for #included files (but this is during compilation, not linking, and thus can be different for each module). Is it true for Windows and other platforms too? Or do some platforms require to tell from which libraries individual functions are taken? If not, we could use this fact and specify the C library in a separate foreign declaration rather than together with each function. This has the advantage that when the library name is #ifdefed, the conditional needs not to be repeated for each function. Similarly for #included header names. A disadvantage is that linking using dlopen/dlsym or equivalent (in interpreted environments) is problematic, because then you must know the library of each function. It still can be done; we assume that a single module will not import two identically named functions from different libraries, so if more than one library is specified, an interpreter can try each of them for each function. For C++ the external name would contain the namespace, but not the library nor header.
Is it reasonable to require that only foreign declarations of a *single* foreign language are allowed per Haskell module?
We can give up the irrelevance of the order of declarations (which does not apply for regular imports anyway - they must be at the top of the module, before all local definitions). We can have some declaration specifying the context of *following* foreign declarations. Another such declaration can change the context later in the module. In this case we have both the generality and convenience. The language, calling convention, header files, and libraries would be moved there. My discussion above is pointless: we specify the library name once, but logically it applies to each individual function. Here is a concrete proposal: foreign language "c", #if HAVE_NCURSES_CURSES_H include "<ncurses/curses.h>", #elif HAVE_CURSES_H include "<curses.h>", #else #error Where is curses.h? #endif library "ncurses" The set of meaningful pseudokeywords ('include' and 'library' above) depends on the 'language' which is mandatory and must be specified first. Multiple headers/libraries/etc. can be specified as separate include/library/etc. clauses. I hope all interesting parameters in the future will fit in the syntax of keyword/string pairs, with the string being optional (some keywords are just boolean switches), or perhaps with multiple strings separated by spaces (multiple headers/libraries could be specified that way). The calling convention is specified thus: foreign language "c", include "<whatever.h>", stdcall and removed from individual functions. All information normally found in the C header must be duplicated by other means, because the header is used only optionally to check the call with the prototype, and physical linking with the function can be done without cooperation with the C compiler. Header and library paths are specified by compiler's commandline options as usual. -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK