Modified proposal for default decls

Marcin 'Qrczak' Kowalczyk qrczak at
Sat Feb 24 08:27:59 EST 2001

Fri, 23 Feb 2001 18:38:20 +0000, malcolm-ffi at <malcolm-ffi at> 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"

    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
    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 at
  ^^                      SYGNATURA ZASTÊPCZA

More information about the FFI mailing list