[MLton] MLTON_THREAD

Stephen Weeks MLton@mlton.org
Fri, 20 Aug 2004 08:52:24 -0700


> > I'm thinking that the common case will actually be prepVal, and that
> > with prepVal already defined, then prep is not really needed.  Putting
> > it all together, how about the following?
> >
> > 	val prepare: 'a t * 'a -> Runnable.t
> > 	val prepareFn: 'a t * (unit -> 'a) -> Runnable.t
> 
> I disagree:
...
> [fluet@tiger core-cml 13]% grep prep * | wc -l
>      37
> [fluet@tiger core-cml 14]% grep prepVal * | wc -l
>      16
> [fluet@tiger core-cml 15]% grep prepFn * | wc -l
>       3

Looking more closely at core-cml, I see 10 preps, 16 prepVals, and 3
prepFns.

The difference is whether people mostly deal with threads that have no
context (as with preemptive threads) or threads that have some
context.

> So, I prefer:
> 
>  	val prepare: unit t -> Runnable.t
>  	val prepareFn: 'a t * (unit -> 'a) -> Runnable.t
>  	val prepareVal: 'a t * 'a -> Runnable.t

Another advantage of 

> > 	val prepare: 'a t * 'a -> Runnable.t
> > 	val prepareFn: 'a t * (unit -> 'a) -> Runnable.t

is that the interface is smaller.  I think that simplicity/uniformity
is nice.  Compare

	prepare t
	prepareVal (t, x)

to

	prepare (t, ())
	prepare (t, x)

With the lightweight anonymous function syntax of SML, I'd almost go
to just having a single function

	prepare: 'a t * (unit -> 'a) -> Runnable.t

But

	prepare (t, fn _ => ())
	prepare (t, fn _ => x)

looks a little to messy to me, and we both agree that prepareFn is
pretty uncommon.


I don't think it's a big deal either way, since most people would
use some higher-level threads package.