[MLton] Callback to function pointer?

Stephen Weeks MLton@mlton.org
Fri, 15 Jul 2005 12:26:37 -0700

I looked back over all the proposals, and tried to unify them as much
as possible so we could compare the remaining differences.  Here's
what they have in common.

 _address "symbol": ptrTy;	    ptrTy
 _import "symbol": cfTy;	    cfTy
 _export "symbol": cfTy;	    cfTy -> unit

For importing a function pointer, we have seen two proposals.

 _import *: ptrTy -> cfTy;	    ptrTy -> cfTy
 _iccall : ptrTy -> cfTy; 	    ptrTy -> cfTy

This is purely cosmetic, and it doesn't seem worth the extra keyword
or breaking backwards compatibility.  So I think it makes sense to
stick with _import * (which, by the way Matthew must have slipped the
currying by me in my sleep :-).

The big question seems to be how to express getting and setting C
base types.

Wesley proposed:

 _import "symbol": cbTy;	    cbTy
 _store "symbol": cbTy -> unit;	    cbTy -> unit
 _import * : ptrTy -> cbTy;	    ptrTy -> cbTy
 _store * : ptrTy -> cbTy -> unit;  ptrTy -> cbTy -> unit

Matthew proposed:

 _fetch "symbol": cbTy; 	    unit -> cbTy
 _store "symbol": cbTy; 	    cbTy -> unit
 _fetch * : ptrTy -> cbTy; 	    ptrTy -> cbTy
 _store * : ptrTy * cbTy; 	    ptrTy * cbTy -> unit

The differences are:

 o Wesley's is backward compatible
 o the keyword _import vs _fetch
 o whether or not fetching a symbol is explicit with "unit ->"
 o whether or not _store * is curried.
 o whether or not the explicit annotation always matches the type.

Stephen proposed:

 _symbol "symbol": cbTy;            (unit -> cbTy) * (cbTy -> unit)
 _symbol *: ptrTy, cbTy;            (ptrTy -> cbTy) * (ptrTy * cbTy -> unit)

This proposal

 o is not backward compatible
 o does not use currying
 o does use "unit ->" for fetching
 o introduces a new keyword
 o would be nice in situations where one wants both the getter and the
   setter -- I'm not sure how common that is

In the absence of strong reasons to go otherwise, backward
compatibility is nice.  However, in this case, it's easy enough to
deprecate the old syntax while phasing in the new one.  Since we
already don't match the type annotation with _export, I don't think
it's a huge deal to continue that trend.  Further, I think there is a
benefit to the concision of not having to write out the whole type
(especially in my proposal, where it would be silly to).

In summary, the proposals are all quite similar.  I lean slightly
toward mine (shocking!), as it is uncurried, makes the fetch explicit,
and is the most concise, especially in cases where both the getter and
setter are needed.  BTW, as a reminder, my proposal easily expands via
an annotation if we want to define the C base type SML side.

 _symbol "symbol" define : cbTy;    (unit -> cbTy) * (cbTy -> unit)

One thing I don't like about any of the proposals is having to write
the pointer type, since it is almost always MLton.Pointer.t.  Wesley's
suggestion of using type inference would be nice here.  This is an
interesting idea, and, I can't see any reason why it wouldn't work.
The code to implement this hooks in during type inference.  With a
little bit of delaying, it could likely be made to work.  Hmmm ...
probably to much to think about at this time.