From: Manuel Fahndrich <maf@microsoft.com>
To: "'caml-list@inria.fr'" <caml-list@inria.fr>
Subject: external C primitives and documentation
Date: Thu, 18 Feb 1999 11:03:26 -0800
I just got bitten by a misuse of the external facility to call C from CAML.
I think the documentation should alert people to following issue.
The form of type expressions in "external" declarations is
important: beware of function type abbreviations.
Consider the following scenario:
type a
type b
type c
external foo : a -> b -> c = "CFoo"
The ML compiler assumes CFoo is a two argument function C function, thus a
call
foo a b
will pass both arguments a and b to the C function CFoo and expect a value
of type c back.
Now I was stupid and I did the following:
type a
type b
type c
type b_to_c = b -> c
external foo : a -> b_to_c = "CFoo"
Of course, the ML compiler now assumes that CFoo is a one argument C
function and a call
foo a b
will call CFoo with a single argument a, expect a closure back, which will
then be applied to b.
I haven't tried to see what happens when you say"
external foo : a -> (b -> c) = "CFoo"
but I expect this would be the second case as well.
Of course, this is exactly the intended meaning of the external declaration.
But when you have function type abbreviations like 'a iterator = ('a ->
unit) -> unit, it is too tempting to use them in the external declarations.
Thus I would suggest that the OCAML documentation on the C Interface
contains a warning to this effect. The documentation doesn't describe
exactly how it determines the number of arguments to be passed to the C
function.
An alternative would be to extend the external declarations with a parameter
count:
external foo[2] : a -> (b -> c) = "CFoo"
would then unambiguously state that foo is a function which calls into C
when applied to 2 arguments, and not to one.
-Manuel
This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:19 MET