[MLton-user] FFI and finalizable values

Stephen Weeks sweeks@sweeks.com
Mon, 15 Dec 2003 12:30:58 -0800


> Hello, I'd like to be able to write, for example:
> val c_function = _import "c_function" : Pointer.t Finalizable.t ->
> unit;
> The benefit would be less typing. For example,
> withValue (x, c_function)
> could be written
> c_function x
> Actually, that's not so bad, but it's worse if a function has many
> parameters, for example:
> withValue (x, fn x => withValue (y, fn y => c_function (x, y)))
> What do you think of this? I think this is unnecessary extra sugar, but
> it would definately make programming easier and faster.

I think that it's easy enough to do in the language by writing a
wrapper around c_function at the time it is defined, so that you only
have to use the awkward syntax once per _import.

  val c_function = _import "c_function" : Pointer.t -> unit;
  val c_function: Pointer.t Finalizable.t -> unit =
     fn x => withValue (x, c_function)

You can also add helper functions for the more complex cases

  val withValue2: 'a Finalizable.t * 'b Finalizable.t * ('a * 'b -> 'c) -> 'c =
     fn (x, y, f) => withValue (x, fn x => withValue (y, fn y => f (x, y)))

Or, we might add these to MLton.Finalizable.  In any case, with these,
it is easy enough to define a wrapper for your other case.

  val c_function = _import "c_function" : Pointer.t * Pointer.t -> unit;
  val c_function: Pointer.t Finalizable.t * Pointer.t Finalizable.t -> unit =
     fn (x, y) => withValue2 (x, y, c_function)

Hopefully that works well enough, especially since it's all done once
per _import.