Fri, 23 Feb 2001 18:38:20 +0000, malcolm-ffi@cs.york.ac.uk <malcolm-ffi@cs.york.ac.uk> pisze:
foreign_decl ::= 'foreign' what [conid] [attributes] [foreign_name] varid '::' prim_type | 'foreign' 'library' conid attributes
I like the idea. Putting attributes before foreign_name is incompatible with current unsafe.
I also prefer to change
attribute ::= varid | varid string_literal to attribute ::= varid | varid=string_literal
Intuitively juxtaposition binds more strongly than '=', so foreign import keyword = value keyword = value varid :: type looks like divided into three parts separated by '=': foreign import keyword value keyword value varid :: type Some time ago I proposed to separate 'keyword = value' pairs by commas, but it was incompatible with the placement of 'unsafe'.
You can have as many library decls as you like - think of them simply as named collections of features.
In this case there can be no [conid] in the grammar, only user-defined attributes. Consistency in unifying them with atomic attributes requires the ability to include multiple user-defined attribute sets in one foreign declaration, to define attribute sets in terms of others, and to export them (explicitly). This may be overly general. This may also be really convenient. When a foreign library requires configure magic to determine headers and libraries and other system-dependent attributes, it may be placed in a single preprocessed module, and all other modules will just use the named set of attributes defined in one place. Syntax proposal: foreign library Gtk = header "<gtk/gtk.h>" header "<gtk/glib.h>" dll "libGTK.dll" stdcall unsafe foreign import "gtk_text_widget" Gtk textWidget :: String -> GtkWidget The foreign_name can be seen as a value for the keyword 'import'. Using conids instead of varids for library names ensures that old code will not break when further attributes are defined. Usually the module name is a good choice. I don't propose to be able to bind parameters on the lhs of '=', although the syntax would easily allow that. If at some time we decide to have 'foreign type' declarations which tell how to translate Haskell types to C types, they should be attached to 'library' contexts instead of being put in a global pool, which solves the problem of conflicting translations coming from different modules and how they are exported: data RangeTag type Range = ForeignPtr RangeTag foreign type "GtkRange *" Gtk Range It does not mean to _use_ Gtk attributes here, but to _add_ this definition to Gtk's type translation dictionary.
By the way, this implies that certain single-word features must be invertible - 'unsafe' can be overridden by 'safe', 'nonblocking' can be overridden by 'blocking', or whatever.
Yes. And it should be more precisely said what does it mean to "override", e.g. are both Gtk safe and safe Gtk legal, meaning to override whatever safety switch is in Gtk? If the order does not matter but they are overridable, then there are ambiguities when e.g. we include multiple library ids which define conflicting safety switches. It becomes more complex than really needed. One way to solve this is to drop the idea that library ids have the same rights as atomic attributes. At most one library per foreign declarations, no libraries defined as extensions of others, and the library name can be required to be written at the first position because extra syntax freedom doesn't buy anything in this case. Another way is to say that the order matters and later attributes override earlier ones, no matter how they came from flattened library specifications. This is very nice and consistent, except that stupid declarations like 'unsafe safe' are legal. -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK