Re: _import in a functor
Phil Clayton <[email protected]> Wed, 03 Feb 2016 13:32:02 +0000
| Newsgroups | gmane.comp.lang.ml.mlton.user |
|---|---|
| Message-ID | <[email protected]> |
On 02/02/2016 17:42, Matthew Fluet wrote: > On Tue, Feb 2, 2016 at 8:49 AM, Phil Clayton <[email protected]> wrote: >> (I thought I had already asked about this issue but I can't find or remember >> any answer. Sorry if it's a duplicate.) >> >> It appears that _import can't be used inside a functor when the types of the >> imported function depend on the functor's arguments. See attached example. >> Building with >> >> mlton -default-ann 'allowFFI true' import_in_functor.sml >> >> gives >> >> Error: import_in_functor.sml 3.13. >> Invalid type for _import. >> int32 * t -> unit >> compilation aborted: elaborate reported errors >> >> Is that intentional behaviour and something I should work around? > > It is intentional, in as much as we want to ensure that any functor > that type checks at its declaration site will necessarily type check > at every application site (that is, when we re-type-check the functor > body with the actual argument at its use site). > > In your example, if you had > > structure S2 = F (type t = int -> int) > > then that would not work, since "int -> int" is not a valid FFI type > and the re-type-checking would result in the "Invalid type for > _import" error message. That seems a reasonable decision. I think this could be usefully mentioned in http://mlton.org/ForeignFunctionInterfaceSyntax Perhaps at the end of the first section, something like: "Inside a functor, before the functor's arguments are known, the type must elaborate to a correct form." > Also, there are few cases where the same C function would work with > multiple different SML types, so I wouldn't expect that there are very > many situations where you could exploit an ability to include an > _import in a functor. The one exception is when the C function is > taking a void* argument, for which multiple SML types have that same > runtime C representation. See, > https://github.com/MLton/mlton/issues/53 for a similar proposal. In > that scenario, you might use something like: > > functor F (type t val toPtr : t -> MLton.Pointer.t) = struct val f = > _import "c_fun" : int * MLton.Pointer.t -> unit; end > > Now the application site need not know the details of or provide the > right _import; instead, it simply witnesses how to convert to the > generic FFI type. I agree that there are limited opportunities to use _import in this way. In my case it was different SML types for pointers, as you mention above. By the way, in https://github.com/MLton/mlton/issues/53 doesn't the proposal to have toPtr for vectors and arrays suffer from the problem that a garbage collection could relocate v between toPtr v and the foreign call? (I think this came up in discussion about ways to pass a null char pointer, to support the C representation of an optional string.) > Another potential problem with _import-s in functors is that they > would be expanded to multiple _import-s overall, one for each functor > application. Each of those _import-s, with the same C function name, > would result in a distinct C prototype (in the C codegen; no > prototypes needed in the native codegens), which is often an error for > the C compiler. I found that I needed to move the _import out of the functor for another reason. (I sometimes _import a diagnostic version of the C function that is specific to the type, although the non-diagnostic version is always the same.) When I first encountered this a few years ago, I seem to recall that I found that I also had to move the _import outside the functor, which is probably why I didn't mention it then. So I haven't actually found the current behaviour to be limiting. Phil ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140