Summary of current change suggestions

Alastair Reid reid at
Wed Feb 21 17:51:35 EST 2001

The first time I read this syntax, I misinterpreted it.
I think my misinterpretation might be interesting so I'll give it below in case
anyone else likes it.

> 	foreign library C    "<ncurses/curses.h>" "-lcurses"
> 	foreign library java "blah" "blah"
> 	foreign import C    "curses_function" cf :: Int -> IO Int
> 	foreign import java "java.blah.*/foo" jf :: Int -> IO Int

What I first thought this was doing was:

1) The foreign library decls _declare_ two new kinds of external function which
the programmer as arbitrarily (and confusingly) chosen to call "C" and "java".

2) The foreign import declarations refer to these new kinds of external
   Those declared as "C" will use <ncurses/curses.h>, etc.
   Those declared as "java" will use "blah", etc.

Of course, this interpretation doesn't quite work because if "C" is just an
arbitrary varid with no particular meaning, then we need to say somewhere else
that "C" is to use the C calling convention.  (We also need to change "C" to
"c" if it is going to be a varid.)

> A module can have one "foreign defaults" declaration per
> calling convention, which specifies a string.
>   foreign defaults ccall "<gtk/gtk.h>: "
>   foreign defaults java  "java."


ps Just as a general remark on language design...

User defined defaults are really tempting to add (my component programming
language had them briefly and I am under constant pressure to add them back in)
but they are kinda messy because:

1) You have to resolve (or forbid) use of multiple defaults.

2) You need a way to override the default.
   Do you override the whole default (includes, libraries, etc.) at once or
   only the bits you don't specify.

   The latter seems to be slightly better than the former because defaults are
   sorta invisible - the programmer forgets that they're there and so they
   that overriding the default will zap all the default not just the part
   say) that they're thinking about at that moment.

3) A small change to code in one place can have unexpected results (and it is
   hard to detect the consequences using typechecking or from a failed link or

4) Cutting and pasting some code from one context to another context results in
   very different behaviour because the defaults don't carry over.

[I think every form of default behaviour in the Haskell spec has caused
problems like this way out of proportion to the apparent difficulty of
specifying the meaning of defaults and the difficulty of implementing it.]

More information about the FFI mailing list