[MLton-devel] Re: finalization in MLton

Stephen Weeks MLton@mlton.org
Mon, 19 May 2003 11:45:23 -0700


> Really, touch needs to be a compiler primitive. 

Yes.  I hope to put it in today.

> > Yes, if we are talking about and arbitrary intelligent SML compiler
> > with weak pointers.  But with the current MLton what do I need to
> > do to protect my finalized values?
> 
> Use refs ;-)
> 
> Keeping more in line with your implementation, you need a touch that just
> might (but really won't) be called with different exceptions.  I'd propose
> the following:
...
> Again, an arbitrarily smart compiler could figure this out.  In
> particular, the closure for touch (holding r') is always paired up with a
> getVal and value -- and value = WRAP(?, r'); so, the r' in the closure of
> touch is really redundant.  If the compiler came up with a better
> representation for the closures of touch and getVal and the representation
> of value, then they could all share the same unit ref, and the comparision
> r = r' would become r = r which is manifestly true.  But, don't expect to
> see any such optimization any time soon. ;-)

Actually, I think MLton will figure this one out sometimes due to
globalization of refs.  So I wouldn't trust this approach either.  The
only approach I would trust is to use the new touch primitive.

Stepping back a level, since we now have a Finalizable module in
MLton, I think things be much more robust if Ken uses that instead of
trying to roll his own.  As we can see, the implementation relies on a
lot of low-level understanding of the compiler (weak pointers, gc,
optimization, ...), which will almost certainly be different from
compiler to compiler.  So, I don't see any advantage to sharing the
code between Moscow ML and MLton and I do see the disadvantage of
mistakes and confusion.  Also, it would be nice to encapsulate all
that low-level understanding and trickiness in one place (the
implementation of MLton.Finalizable) so that we can change it without
breaking other code.  Thus, Ken, I think it would be best if you built
your Finalized module on top of MLton.Finalizable, something like the
following.

signature MLTON_FINALIZABLE =
   sig
      type 'a t

      val addFinalizer: 'a t * ('a -> unit) -> unit
      val finalizeBefore: 'a t * 'b t -> unit
      val new: 'a -> 'a t
      val withValue: 'a t * ('a -> 'b) -> 'b
   end

signature Finalized =
   sig
      type 'a value
      type 'a destructor = 'a -> unit
	 
      val value     : 'a * 'a destructor -> 'a value
      val withValue : ('a -> 'b) -> 'a value -> 'b
	 
      val doGC : unit -> unit
   end

functor F (S: MLTON_FINALIZABLE): Finalized =
   struct
      type 'a value = 'a S.t
      type 'a destructor = 'a -> unit

      fun value (x, d) =
	 let
	    val v = S.new x
	    val _ = S.addFinalizer (v, d)
	 in
	    v
	 end

      fun withValue f v = S.withValue (v, f)

      fun doGC () = ()
   end



-------------------------------------------------------
This SF.net email is sponsored by: If flattening out C++ or Java
code to make your application fit in a relational database is painful, 
don't do it! Check out ObjectStore. Now part of Progress Software.
http://www.objectstore.net/sourceforge
_______________________________________________
MLton-devel mailing list
MLton-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlton-devel