From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id JAA24803 for caml-redistribution; Fri, 19 Feb 1999 09:27:31 +0100 (MET) Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id UAA09014 for ; Thu, 18 Feb 1999 20:03:31 +0100 (MET) Received: from mail3.microsoft.com (mail3.microsoft.com [131.107.3.123]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id UAA11367 for ; Thu, 18 Feb 1999 20:03:29 +0100 (MET) Received: by mail3.microsoft.com with Internet Mail Service (5.5.2524.0) id ; Thu, 18 Feb 1999 11:03:27 -0800 Message-ID: <25983782061AD111B0800000F86310FE1026CB1B@RED-MSG-42> From: Manuel Fahndrich To: "'caml-list@inria.fr'" Subject: external C primitives and documentation Date: Thu, 18 Feb 1999 11:03:26 -0800 X-Mailer: Internet Mail Service (5.5.2524.0) Sender: weis 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