[MLton] Callback to function pointer?
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
_import "symbol": cbTy; cbTy
_store "symbol": cbTy -> unit; cbTy -> unit
_import * : ptrTy -> cbTy; ptrTy -> cbTy
_store * : ptrTy -> cbTy -> unit; ptrTy -> cbTy -> unit
_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.
_symbol "symbol": cbTy; (unit -> cbTy) * (cbTy -> unit)
_symbol *: ptrTy, cbTy; (ptrTy -> cbTy) * (ptrTy * cbTy -> unit)
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.