[MLton-devel] Re: [MLton-user] new release of MLton

Stephen Weeks MLton@mlton.org
Tue, 15 Jul 2003 03:24:20 -0700


> I'm pushing for ease of use and transparency both for myself in
> terms of the FFI and for the end user.  The original Moscow ML
> binding allows the SML approach to the OpenGL libraries to be
> intuitively the same as the C language bindings which are well known
> and well documented.  This gives two advantages ...

Sounds good.  And I agree with the advantages you mention.  As a side
note -- I would drop the "glut" and "GLUT_" prefix from all of the
identifiers in the Glut module, since you have already done the
namespace management by putting the identifiers in that module.

> Still it would be convenient.  Having said that I suppose there is a
> compatibility issue with SML/NJ which presumably doesn't allow C source code
> in CM files.

Yeah.  The MLton CM stuff is a really simple hack just to get some
compatibility.  I don't really want to spend any mroe effort on it,
since we are working on a replacement for CM that we hope will be
ready for our next release (3-6 months out).  I'll keep in mind these
concerns for that replacement.  I definitely think it would be
reasonable to put .o files, .a files, or linker switches (-llib) in
the files.  As to putting C files, there's the question of what C
compiler is called, or is MLton called, and with what switches.  I
think it may be cleaner to keep the calls to gcc outside the
description of the SML code.  But I'm not sure and will think about
it.

> $ make -f Makefile.mlton
> mlton test.cm
> test.sml:31.3-31.18 Error: unify: can't unify
>    t1: unit
>    t2: unit -> unit
> compilation aborted: type check reported errors
> make: *** [test] Error 1

This error is because display is of type "(unit -> unit) -> unit", not
"unit -> unit".  Hence, the call "display (fn "() => ...)" is type
correct, but the call "glutDisplayFunc display" is not.

> Basically I want to pass my SML callback "display" into C land with
> "glutDisplayFunc" but it is apparently not allowed to use a function
> type as an argument to an FFI function.

I have looked some more at the code and think things are being made
more difficult than they need to be, possibly because of confusion
about the differences in the way MLton and Moscow ML handle calls from
SML to C.  If I understand the display example, you want the
following:

  Every time SML call "Glut.glutDisplayFunc display" happens, call the
  C glutDisplayFunc with an argument that is a C callback that will
  call the SML display function.

Here is some MLton/SML code to do this.

------------------------------------------------------------
(* glut.sml *)
structure Glut:
   sig
      val displayFunc: (unit -> unit) -> unit
   end  =
   struct
      local
	 val e = _export "glutDisplayFuncArgument": unit -> unit;
	 val f = _ffi "callGlutDisplayFunc": unit -> unit;
      in
	 fun displayFunc (display: unit -> unit) = (e display; f ())
      end
   end

fun display () = ()
   
val _ = Glut.displayFunc display
------------------------------------------------------------

If you call mlton -export-header true on this program, you will get
the following prototype (after some typedefs):

	void glutDisplayFuncArgument ();

Assumeyou call mlton -export-header true >export.h.  Then here is the
C code that fits with the SML code.

------------------------------------------------------------
/* glut.c */
#include <GL/gl.h>
#include "export.h"

void callGlutDisplayFunc () {
	glutDisplayFunc (glutDisplayFuncArgument);
}
------------------------------------------------------------

There is no need to create an additional C function as a wrapper for
glutDisplayFuncArgument.  Since MLton knows the type of
glutDisplayFuncArgument, it generates the appropriate header.  This is
different than how Moscow ML handles callbacks, where the C programmer
is required to "lookup" the SML function and wrap up the arguments.

I don't know enough about glut to know if the call to glutDisplayFunc
can be moved to run only once at program initialization time, since it
has a constant argument.  I would guess that it can be.  The point is
that the assignment to change the function to call is happening in the
MLton implementation of the ffi, when the _export is applied to an SML
function ("e display" in the above code).

If all of the uses of callbacks are of this form, I don't see any need
for hash tables of SML functions or any of the trickery that Ken uses
for mGTK.  (In fact, maybe he doesn't even need it.  I haven't closely
looked at his code.)

Putting it all together, the following sequence of calls with generate
an executable 

	mlton -export-header true glut.sml >export.h
	gcc -c glut.c
	mlton glut.sml glut.o -lglut

The executable segfaults, but I would guess a lot more glut stuff
needs to be done.

> Does anyone use PolySML to typecheck mlton FFI code?

I never have.  You might ask MLton-user@mlton.org.



-------------------------------------------------------
This SF.Net email sponsored by: Parasoft
Error proof Web apps, automate testing & more.
Download & eval WebKing and get a free book.
www.parasoft.com/bulletproofapps1
_______________________________________________
MLton-devel mailing list
MLton-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlton-devel