Modification to foreign import/export

Marcin 'Qrczak' Kowalczyk qrczak at
Mon Feb 12 13:32:31 EST 2001

Mon, 12 Feb 2001 17:27:36 +0000, malcolm-ffi at <malcolm-ffi at> pisze:

> > We can have some declaration specifying the context of *following*
> > foreign declarations. Another such declaration can change the
> > context later in the module.
> Please no!

OK, my current favourite is to specify them globally but allow to
override locally.

> > foreign language "c",
> I think the quotes around the language name are redundant - why not
> just
>   foreign language C
> ?

To keep the syntax consistent: a list of
    keyword "string"
pairs separated by commas, including the language invocation (even
though it's special: it distinguishes the whole construct from other
foreign declarations and determines the language name).

And to allow the spelling of "c++" :-)

> > foreign language "c",
> >     include "<ncurses/curses.h>",
> >     library "ncurses"
> I quite like the idea of keyword/string pairs.  I'm not sure how you
> would propose to use the layout rule here.

No layout is used here. Everything is one logical declaration, which
can be split into indented lines as usual. Just as for other foreign

> To make them slightly easier to parse, why not make them like
> named-field bindings perhaps?

My record proposal goes in the opposite direction by removing this
use of braces from the record syntax :-)  Anyway, I don't see the
reason for introducing extra punctuation. My original syntax is
trivial to parse:

    <foreign-language> ::= foreign language <string> <parameters>
    <parameters>       ::= <empty>
                         | , <keyword> <strings> <parameters>
    <strings>          ::= <empty>
                         | <string> <strings>

Other foreign declarations can use the same <parameters> syntax at
the end:

-- A file with a bunch of Java functions and one C function:
foreign import func :: Ptr CChar -> IO CInt, language "c", library "foo"

-- Another file where the language is C and files are in the library "foo":
foreign import func2 :: IO (), library "foo1"

IMHO attributes like unsafe should be specified that way. They could
even give a warning instead of an error if they are not recognized,
so nhc98's noproto or future additions like blocking behavior discussed
on the workshop can be added without breaking the compatibility.
I had to play hsc2hs tricks to have noproto for nhc98 but not for ghc.
A programmer could make unsafe his default in a module and write safe
explicitly when needed.

> I suppose in the case where the C header was local, the string
> would need to use the Haskell double-quoting mechanism?

Yes, lexically it's a string literal. But we can adopt ghc's -#include
command line option's convention that the absence of quotes means
double quotes.

> For booleans, use booleans
>         flag=True
> and for multiple strings, use tuples?
>         searchpaths=("dir1","dir2")

This unnecessarily complicates the syntax. With my version the abstract
syntax contains just
    [(Keyword, [Value])]
where type Keyword = String; type Value = String
and interpretation of the strings is up to the language + keyword
combination. It is parsed complately before recognizing individual

Here we would need to decide if True is the same as "True", there
might be the temptation to include integer literals later etc.

Since these keywords are used nowhere else and no identifiers are
expected here, they can be freely chosen. Each value of a multiway
switch of a fixed set of values can have its own keyword without
arguments (e.g. for calling conventions). Arbitrary weirdness invented
by other languages' implementers can be accommodated here without
influencing the rest of our beloved language :-)

 __("<  Marcin Kowalczyk * qrczak at
  ^^                      SYGNATURA ZASTÊPCZA

More information about the FFI mailing list