[MLton] Documentation on _export

Matthew Fluet fluet@cs.cornell.edu
Fri, 23 Sep 2005 09:01:36 -0400 (EDT)


> In the process of writing documentation on the mzscheme<->mlton FFI,
> I came across:
>
>  Export
>
>  _export "C function name" attr... : cFuncTy -> unit;
>
>  Denotes a function that must be applied to a SML function f and
>  arranges for the exported C function to call the SML function.
>
> at <http://mlton.org/ForeignFunctionInterfaceSyntax>.
>
> This suggests that the export happens when the denoted function
> is called, in other words that the export happends at runtime.
> That can't be right? What would an improved wording look like?

I think the wording is correct.  _export "foo"  ensures that there is a 
symbol "foo" which may be called as a C function.  However, calling the 
exported function before applying the "cFuncTy -> unit" denoted function 
to an SML function will result in an exception at runtime claiming that 
the exported function hasn't yet been initialized.

To put it another way:  If your source program starts like:

   ...
   val () = (_export "foo": (unit -> unit) -> unit) f
   ...

then it is transformed to something like:

   val fooStub : (unit -> unit) option ref = NONE
   ...
   val () = fooStub := SOME f
   ...

Hence, it is illegal to call "foo" before the stub is initialized with an 
actual function.

Note, you cannot transform it to something like:

   val fooStub : (unit -> unit) = f
   ...
   val () = ()
   ...

since f is not in scope at the beginning of the program.

Now, in most well-structured programs, this distinction isn't likely to 
cause problems.  All of the _export's appear as top-level effects which 
happen at the very beginning of the program before you call a Main.main 
like function.  So, by the time the "real" program starts, all the exports 
are initialized.