Previous Up Next

10  MLton extensions

10.1  #line directives

To aid in the debugging of code produced by program genenerators such as Noweb, MLton supports comments with #line directives of the form (*#line line.col "file"*). Here, line and col are sequences of decimal digits and file is the source file. A #line directive causes the front end to believe that the character following the right parenthesis is at the line and column of the specified file. A #line directive only affects the reporting of error messages and does not affect program semantics (except for functions like MLton.Exn.history which report source file positions). Syntactically invalid #line directives are ignored. To prevent incompatibilites with SML, the file name may not contain the character sequence *).

10.2  The MLton structure

The remainder of this section describes the modules MLton makes available that are not part of the Standard ML Basis Library. As a warning, please keep in mind that the MLton structure and its substructures do change from release to release of MLton.
structure MLton:
   sig
      val eq: 'a * 'a -> bool
      val isMLton: bool
      val share: 'a -> unit
      val shareAll: unit -> unit
      val size: 'a -> int

      structure Array: MLTON_ARRAY
      structure BinIO: MLTON_BIN_IO
      structure Cont: MLTON_CONT
      structure Exn: MLTON_EXN
      structure Finalizable: MLTON_FINALIZABLE
      structure GC: MLTON_GC
      structure IntInf: MLTON_INT_INF
      structure Itimer: MLTON_ITIMER
      structure Platform: MLTON_PLATFORM
      structure Pointer: MLTON_POINTER
      structure ProcEnv: MLTON_PROC_ENV
      structure Process: MLTON_PROCESS
      structure Profile: MLTON_PROFILE
      structure Random: MLTON_RANDOM
      structure Rlimit: MLTON_RLIMIT
      structure Rusage: MLTON_RUSAGE
      structure Signal: MLTON_SIGNAL
      structure Socket: MLTON_SOCKET
      structure Syslog: MLTON_SYSLOG
      structure TextIO: MLTON_TEXT_IO
      structure Thread: MLTON_THREAD
      structure Vector: MLTON_VECTOR
      structure Weak: MLTON_WEAK
      structure Word: MLTON_WORD where type word = Word.word
      structure Word8: MLTON_WORD where type word = Word8.word
      structure World: MLTON_WORLD
   end

10.2.1  MLton

eq (x, y)
       
returns true if x and y are equal as pointers. For simple types like char, int, and word, this is the same as equals. For arrays, datatypes, strings, tuples, and vectors, this is a simple pointer equality. The semantics is a bit murky.

isMLton
       
is always true in a MLton implementation, and is always false in a stub implementation.

share x
       
maximizes sharing in the heap for the object graph reachable from x.

shareAll ()
       
maximizes sharing in the heap by sharing space for equivalent immutable objects. A call to shareAll performs a major garbage collection, and takes time proportional to the size of the heap.

size x
       
return the amount of heap space (in bytes) taken by the value of x, including all objects reachable from x by following pointers. It takes time proportional to the size of x. For an example, see examples/size.sml.

10.2.2  MLton.Array

signature MLTON_ARRAY =
   sig
      val unfoldi: int * 'b * (int * 'b -> 'a * 'b) -> 'a array
   end
unfoldi (n, b, f)
       
construct an array a of a length n, whose elements ai are determined by the equations b0 = b and (ai, bi+1) = f (i, bi).

10.2.3  MLton.BinIO

signature MLTON_BIN_IO =
   MLTON_IO
   where type instream = BinIO.instream
   where type outstream = BinIO.outstream
See Section 10.2.9.

10.2.4  MLton.Cont

signature MLTON_CONT =
   sig
      type 'a t

      val callcc: ('a t -> 'a) -> 'a
      val prepend: 'a t * ('b -> 'a) -> 'b t
      val throw: 'a t * 'a -> 'b
      val throw': 'a t * (unit -> 'a) -> 'b
   end
type 'a t
       
the type of continuations that expect a value of type 'a.

callcc f
       
apply f to the current continuation. Because this copies the entire stack, callcc takes time proportional to the current stack size.

prepend (k, f)
       
compose a function f with a continuation k to create a continuation that first does f and then does k. This is a constant time operation.

throw (k, v)
       
throw value v to continuation k. Because this copies the entire stack of k, throw takes time proportional to the size of this stack.

throw' (k, th)
       
a generalization of throw that evaluates th () in the context of k. Thus, for example, if th () raises an exception or grabs another continuation, it will see k, not the current continuation.

10.2.5  MLton.Exn

signature MLTON_EXN =
   sig
      val addExnMessager: (exn -> string option) -> unit
      val history: exn -> string list
      val topLevelHandler: exn -> 'a
   end
addExnMessager f
       
adds f as a pretty-printer to be used by General.exnMessage for converting exceptions to strings. Messagers are tried in order from most recently added to least recently added.

history e
       
returns the file positions that have raised the exception e, in reverse chronological order. A handle expression that implicitly reraises counts as a raise. history will return [] unless the program is compiled with -exn-history true.

topLevelHandler e
       
behave as if the top level handler received the exception e, that is, print out the unhandled exception message for e and exit.

10.2.6  MLton.Finalizable

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 touch: 'a t -> unit
      val withValue: 'a t * ('a -> 'b) -> 'b
   end
A finalizable value is a value to which finalizers can be attached. A finalizer is a function that runs after a garbage collection determines that the value to which it is attached is unreachable. Reachability is the same as with weak pointers (see Section 10.2.25). The finalizer is treated like a signal handler, in that it runs asynchronously in a separate thread, with signals blocked, and will not run within a critical section (see Section 10.2.23).

For an example, see the examples/finalizable directory.
addFinalizer (v, f)
       
adds f as a finalizer to v. This means that sometime after the last call to withValue on v completes and v becomes unreachable, f will be called with the value of v.

finalizeBefore (v1, v2)
       
ensures that v1 will be finalized before v2. A cycle of values v = v1, ..., vn = v with finalizeBefore (vi, vi+1) will result in none of the vi being finalized.

new x
       
creates a new finalizable value, v, with value x. The finalizers of v will run sometime after the last call to withValue on v when the garbage collector determines that v is unreachable.

touch v
       
ensures that v's finalizers will not run before the call to touch.

withValue (v, f)
       
returns the result of applying f to the value of v and ensures that v's finalizers will not run before f completes. The call to f is a nontail call.

10.2.7  MLton.GC

signature MLTON_GC =
   sig
      val collect: unit -> unit
      val pack: unit -> unit
      val setMessages: bool -> unit
      val setSummary: bool -> unit
      val unpack: unit -> unit
   end
collect ()
       
causes a garbage collection to occur.

pack ()
       
shrinks the heap as much as possible so that other processes can use available RAM.

setMessages b
       
controls whether diagnostic messages are printed at the beginning and end of each garbage collection. It is the same as the gc-messages runtime system option.

setSummary b
       
controls whether a summary of garbage collection statistics is printed upon termination of the program. It is the same as the gc-summary runtime system option.

unpack ()
       
resizes a packed heap to the size desired by the runtime.

10.2.8  MLton.IntInf

signature MLTON_INT_INF =
   sig
      type t

      val areSmall: t * t -> bool
      val gcd: t * t -> t
      val isSmall: t -> bool
      datatype rep =
         Big of word vector
       | Small of int
      val rep: t -> rep
   end
MLton represents an arbitrary precision integer either as an unboxed 32 bit word with the bottom bit set to 1 and the top 31 bits representing a small integer in [-230, 230), or as a pointer to a vector of words where the first word indicates the sign and the rest are the limbs of GNUmp big integer.
type t
       
the same as type IntInf.int.

areSmall (a, b)
       
returns true iff both a and b are small.

gcd (a, b)
       
use the GNUmp's fast gcd implementation.

isSmall a
       
returns true iff a is small.

datatype rep
       
the underlying representation of an IntInf.

rep i
       
return the underlying representation of i.

10.2.9  MLTON_IO

signature MLTON_IO =
   sig
      type instream
      type outstream

      val inFd: instream -> Posix.IO.file_desc
      val mkstemp: string -> string * outstream
      val mkstemps: {prefix: string, suffix: string} -> string * outstream
      val newIn: Posix.IO.file_desc * string -> instream
      val newOut: Posix.IO.file_desc * string -> outstream
      val outFd: outstream -> Posix.IO.file_desc
   end
inFd ins
       
return the file descriptor corresponding to ins.

mkstemp s
       
like the C mkstemp function, generate and open a tempory file with prefix s.

mkstemps {prefix, suffix}
       
mkstemps is like mkstemp, except it has both a prefix and suffix.

newIn (fd, name)
       
create a new instream from file descriptor fd, with name used in any Io exceptions later raised.

newOut (fd, name)
       
create a new outstream from file descriptor fd, with name used in any Io exceptions later raised.

outFd out
       
return the file descriptor corresponding to out.

10.2.10  MLton.Itimer

signature MLTON_ITIMER =
   sig
      datatype t =
         Prof
       | Real
       | Virtual

      val set: t * {interval: Time.time, value: Time.time} -> unit
      val signal: t -> Posix.Signal.signal
   end
set (t, {interval, value})
       
set the interval timer (using setitimer) specified by t to the given interval and value.

signal t
       
return the signal corresponding to t.

10.2.11  MLton.Platform

signature MLTON_PLATFORM =
   sig
      structure Arch:
         sig
            datatype t = PowerPC | Sparc | X86

            val fromString: string -> t option
            val host: t
            val toString: t -> string
         end
         
      structure OS:
         sig
            datatype t = Cygwin | Darwin | FreeBSD | Linux | MinGW
                       | NetBSD | OpenBSD | Solaris

            val fromString: string -> t option
            val host: t
            val toString: t -> string
         end
   end
datatype Arch.t
       
the architectures to which MLton can compile.

Arch.fromString a
       
convert from string to architecture. Case insensitive.

Arch.host
       
the architecture for which the program is compiled.

Arch.toString
       
string for architecture.

datatype OS.t
       
the operating systems to which MLton can compile.

OS.fromString
       
convert from string to operating system. Case insensitive.

OS.host
       
the operating system for which the program is compiled.

OS.toString
       
string for operating system.

10.2.12  MLton.Pointer

signature MLTON_POINTER =
   sig
      eqtype t

      val add: t * word -> t
      val compare: t * t -> order
      val diff: t * t -> word
      val getInt8: t * int -> Int8.int
      val getInt16: t * int -> Int16.int
      val getInt32: t * int -> Int32.int
      val getInt64: t * int -> Int64.int
      val getPointer: t * int -> t
      val getReal32: t * int -> Real32.real
      val getReal64: t * int -> Real64.real
      val getWord8: t * int -> Word8.word
      val getWord16: t * int -> Word16.word
      val getWord32: t * int -> Word32.word
      val getWord64: t * int -> Word64.word
      val null: t
      val setInt8: t * int * Int8.int -> unit
      val setInt16: t * int * Int16.int -> unit
      val setInt32: t * int * Int32.int -> unit
      val setInt64: t * int * Int64.int -> unit
      val setPointer: t * int * t -> unit
      val setReal32: t * int * Real32.real -> unit
      val setReal64: t * int * Real64.real -> unit
      val setWord8: t * int * Word8.word -> unit
      val setWord16: t * int * Word16.word -> unit
      val setWord32: t * int * Word32.word -> unit
      val setWord64: t * int * Word64.word -> unit
      val sub: t * word -> t
   end
eqtype t
       
The type of pointers, i.e. machine addresses.

add (p, w)
       
returns the pointer w bytes after than p. Does not check for overflow.

compare (p1, p2)
       
compare the pointer p1 to the pointer p2 (as addresses).

diff (p1, p2)
       
returns the number of bytes w such that add (p2, w) = p1. Does not check for overflow.

getX (p, i)
       
returns the object stored at index i of the array of X objects pointed to by p. For example, getWord32 (p, 7) returns the 32-bit word stored 28 bytes beyond p.

null
       
the null pointer, i.e. 0.

setX (p, i, v)
       
assigns v to the object stored at index i of the array of X objects pointed to by p. For example, setWord32 (p, 7, w) stores the 32-bit word w at the address 28 bytes beyond p.

sub (p, w)
       
returns the pointer w bytes before p. Does not check for overflow.

10.2.13  MLton.ProcEnv

signature MLTON_PROC_ENV =
   sig
      val setenv: {name: string, value: string} -> unit
   end
setenv {name, value}
       
Like the C setenv function. Does not require name or value to be null terminated.

10.2.14  MLton.Process

signature MLTON_PROCESS =
   sig
      type pid = Posix.Process.pid

      val spawn: {path: string, args: string list} -> pid
      val spawne: {path: string, args: string list, env: string list} -> pid
      val spawnp: {file: string, args: string list} -> pid
   end
The spawn functions provide an alternative to the fork/exec idiom that is typically used to create a new process. On most platforms, the spawn functions are simple wrappers around fork/exec. However, on Cygwin, the spawn functions are primitive and are both faster and more reliable than fork/exec. All spawn functions return the process id of the spawned process. They differ in how the executable is found and the environment that it uses.
spawn {path, args}
       
Start a new process running the executable specified by path with the arguments args. Like Posix.Process.exec.
spawne {path, args, env}
       
Start a new process running the executable specified by path with the arguments args and environment env. Like Posix.Process.exece.
spawnp {file, args}
       
Search the PATH environment variable for an executable named file, and start a new process running that executable with the arguments args. Like Posix.Process.execp.

10.2.15  MLton.Profile

signature MLTON_PROFILE =
   sig
      structure Data:
         sig
            type t

            val equals: t * t -> bool
            val free: t -> unit
            val malloc: unit -> t
            val write: t * string -> unit
         end

      val isOn: bool
      val withData: Data.t * (unit -> 'a) -> 'a
   end
MLton.Profile provides profiling control from within the program. For more on profiling, see Section 7. In order to most efficiently execute non-profiled programs, when compiling -profile no (the default), type Data.t is equivalent to unit ref.
isOn
       
a compile-time constant that is true when compiling -profile time or -profile alloc.

type Data.t
       
the type of a unit of profiling data.

Data.equals (x, y)
       
returns true if the x and y are the same unit of profiling data.

Data.free x
       
frees the memory associated with the unit of profiling data x. It is an error to free the current unit of profiling data or to free a previously freed unit of profiling data. When compiling -profile no, Data.free x is a no-op.

Data.malloc ()
       
returns a new unit of profiling data. Each unit of profiling data is allocated from the process heap (not the MLton heap) and consumes memory proportional to the number of source functions. When compiling -profile no, Data.malloc () is equivalent to allocating a new unit ref.

write (x, f)
       
writes the accumulated ticks in the unit of profiling data x to file f. It is an error to write a previously freed unit of profiling data. When compiling -profile no, write (x, f) is a no-op. A program compiled with -profile time or -profile alloc will always write the current unit of profiling data at program exit to a file named mlmon.out.

withData (d, f)
       
runs f with d as the unit of profiling data, and returns the result of f after restoring the current unit of profiling data. When compiling -profile no, withData (d, f) is equivalent to f ().

10.2.16  MLton.Random

signature MLTON_RANDOM =
   sig
      val alphaNumChar: unit -> char
      val alphaNumString: int -> string
      val rand: unit -> word
      val seed: unit -> word option
      val srand: word -> unit
      val useed: unit -> word option
   end
alphaNumChar ()
       
returns a random alphanumeric character.

alphaNumString n
       
return a string of length n of random alphanumeric characters.

rand ()
       
return the next pseudrandom number.

seed ()
       
return a random word from /dev/random. Useful as an arg to srand. If /dev/random can not be read from, seed () returns NONE. A call to seed may block until enough random bits are available.

srand w
       
set the seed used by rand to w.

useed ()
       
return a random word from /dev/urandom. Useful as an arg to srand. If /dev/urandom can not be read from, useed () returns NONE. A call to useed will never block -- it will instead return lower quality random bits.

10.2.17  MLton.Rlimit

signature MLTON_RLIMIT =
   sig
      type rlim = word
               
      val infinity: rlim

      type t
               
      val coreFileSize: t        (* CORE    max core file size *)
      val cpuTime: t             (* CPU     CPU time in seconds *)
      val dataSize: t            (* DATA    max data size *)
      val fileSize: t            (* FSIZE   Maximum filesize *)
      val lockedInMemorySize: t  (* MEMLOCK max locked address space *)
      val numFiles: t            (* NOFILE  max number of open files *)  
      val numProcesses: t        (* NPROC   max number of processes *)
      val residentSetSize: t     (* RSS     max resident set size *)
      val stackSize: t           (* STACK   max stack size *)
      val virtualMemorySize: t   (* AS      virtual memory limit *)
      
      val get: t -> {hard: rlim, soft: rlim}
      val set: t * {hard: rlim, soft: rlim} -> unit
   end
MLton.Rlimit provides a wrapper around the C getrlimit and setrlimit functions.
type rlim
       
the type of resource limits.

infinity
       
indicates that a resource is unlimited.

type t
       
the types of resources that can be inspected and modified.

get r
       
returns the current hard and soft limits for resource r. May raise OS.SysErr.

set (r, {hard, soft})
       
sets the hard and soft limits for resource r. May raise OS.SysErr.

10.2.18  MLton.Rusage

signature MLTON_RUSAGE =
   sig
      type t = {utime: Time.time, (* user time *)
                stime: Time.time} (* system time *)
         
      val rusage: unit -> {children: t,
                           gc: t,
                           self: t}
   end
type t
       
corresponds to a subset of the C struct rusage.

rusage ()
       
corresponds to the C getrusage function. It returns the resource usage of the exited children, the garbage collector, and the process itself. The process time (self) includes the gc time.

10.2.19  MLton.Signal

signature MLTON_SIGNAL =
   sig
      type t
      type signal = t

      structure Handler:
         sig
            type t

            val default: t
            val handler: (Thread.Runnable.t -> Thread.Runnable.t) -> t
            val ignore: t
            val isDefault: t -> bool
            val isIgnore: t -> bool
            val simple: (unit -> unit) -> t
         end

      structure Mask:
         sig
            type t
               
            val all: t
            val allBut: signal list -> t
            val block: t -> unit
            val getBlocked: unit -> t
            val isMember: t * signal -> bool
            val none: t
            val setBlocked: t -> unit
            val some: signal list -> t
            val unblock: t -> unit
         end

      val getHandler: t -> Handler.t
      val handled: unit -> Mask.t
      val prof: t
      val restart: bool ref
      val setHandler: t * Handler.t -> unit
      val suspend: Mask.t -> unit
      val vtalrm: t
   end
Signals handlers are functions from (runnable) threads to (runnable) threads. When a signal handler is invoked, it receives as an argument the thread that was interrupted by the signal. The signal handler returns the thread that it would like to resume execution (this is often the thread that it was passed). It is an error for a signal handler to raise an unhandled exception.

A signal handler is never invoked while the running thread is in a critical section (see Section 10.2.23). Invoking a signal handler implicitly enters a critical section and the normal return of a signal handler implicitly exits the critical section; hence, a signal handler is never interrupted by another signal handler.

Signal handling interacts in a non-trivial way with those functions in the Basis Library that correspond directly to interruptable system calls (a subset of those functions that may raise OS.SysError). The desire is that these functions should have predictable semantics. The principal concerns are:
  1. system calls that are interrupted by signals should, by default, be restarted; the alternative is to raise OS.SysError(Posix.Error.errorMsg Posix.Error.intr, SOME Posix.Error.intr). This behavior is determined dynamically by the value of Signal.restart.
  2. signal handlers should always get a chance to run (when outside a critical region). If a system call is interrupted by a signal, then the signal handler will run before the call is restarted or OS.SysError is raised; that is, before the Signal.restart check.
  3. a system call that must be restarted while in a critical section will be restarted with the handled signals blocked (and the previously blocked signals remembered). This encourages the system call to complete, allowing the program to make progess towards leaving the critical section where the signal can be handled. If the system call completes, the set of blocked signals are restored to those previously blocked.
type t
       
the type of signals.

type Handler.t
       
the type of signal handlers.

Handler.default
       
handles the signal with the default action.

Handler.handler f
       
returns a handler h such that when a signal s is handled by h, f will be passed the thread that was interrupted by s and should return the thread that will resume execution.

Handler.ignore
       
is a handler that will ignore the signal.

Handler.isDefault
       
returns true if the handler is the default handler.

Handler.isIgnore
       
returns true if the handler is the ignore handler.

Handler.simple f
       
returns a handler that executes f () and does not switch threads.

type Mask.t
       
the type of signal masks, which are sets of blocked signals.

Mask.all
       
a mask of all signals.

Mask.allBut l
       
a mask of all signals except for those in l.

Mask.block m
       
block all signals in m.

Mask.getBlocked ()
       
get the signal mask m, i.e. a signal is blocked if and only if it is in m.

Mask.isMember (m, s)
       
returns true if the signal s is in m.

Mask.none
       
a mask of no signals.

Mask.setBlocked m
       
set the signal mask to m, i.e. a signal is blocked if and only if it is in m.

Mask.some l
       
a mask of the signals in l.

Mask.unblock m
       
unblock all signals in m.

getHandler s
       
returns the current handler for signal s.

handled
       
returns the signal mask m corresponding to the currently handled signals; i.e., a signal is handled if and only if it is im m.

prof
       
SIGPROF, the profiling signal.

restart
       
dynamically determines the behavior of interrupted system calls; when true, interrupted system calls are restarted; when false, interrupted system calls raise OS.SysError.

setHandler (s, h)
       
sets the handler for signal s to h.

suspend m
       
temporarily sets the signal mask to m and suspends until an unmasked signal is received and handled, at which point suspend resets the mask and returns.

vtalrm
       
SIGVTALRM, the signal for virtual timers.

10.2.20  MLton.Socket

signature MLTON_SOCKET =
   sig
      structure Address:
         sig
            type t = word
         end
      structure Host:
         sig
            type t = {name: string}

            val getByAddress: Address.t -> t option
            val getByName: string -> t option
         end
      structure Port:
         sig
            type t = int
         end

      type t

      val accept: t -> Address.t * Port.t * TextIO.instream * TextIO.outstream
      val connect: string * Port.t -> TextIO.instream * TextIO.outstream
      val listen: unit -> Port.t * t
      val listenAt: Port.t -> t
      val shutdownRead: TextIO.instream -> unit
      val shutdownWrite: TextIO.outstream -> unit
   end
This module contains a bare minimum of functionality to do TCP/IP programming. This module is implemented on top of the Socket module of the Standard Basis Library. We encourage you to use the standard Socket module, since we may eliminate MLton.Socket some day.
type Address.t
       
the type of IP addresses.

Host.getByAddress a
       
lookup the hostname (using gethostbyaddr) corresponding to a.

Host.getByName s
       
lookup the hostname (using gethostbyname) corresponding to s.

type Port.t
       
the type of TCP ports.

type t
       
the type of sockets.

accept s
       
accept a connection on socket s and return the address and port of the connecting socket, as well as streams corresponding to the connection.

connect (h, p)
       
connect to host h on port p, returning the streams corresponding to the connection.

listen ()
       
listen to a port chosen by the system. Returns the port and the socket.

listenAt p
       
listen to port p. Returns the socket.

shutdownRead ins
       
cause the read part of the socket associated with ins to be shutdown.

shutdownWrite out
       
cause the write part of the socket associated with out to be shutdown.

10.2.21  MLton.Syslog

signature MLTON_SYSLOG =
   sig
      type openflag
         
      val CONS     : openflag
      val NDELAY   : openflag
      val PERROR   : openflag
      val PID      : openflag

      type facility

      val AUTHPRIV : facility
      val CRON     : facility
      val DAEMON   : facility
      val KERN     : facility
      val LOCAL0   : facility
      val LOCAL1   : facility
      val LOCAL2   : facility
      val LOCAL3   : facility
      val LOCAL4   : facility
      val LOCAL5   : facility
      val LOCAL6   : facility
      val LOCAL7   : facility
      val LPR      : facility
      val MAIL     : facility
      val NEWS     : facility
      val SYSLOG   : facility
      val USER     : facility
      val UUCP     : facility

      type loglevel

      val EMERG    : loglevel
      val ALERT    : loglevel
      val CRIT     : loglevel
      val ERR      : loglevel
      val WARNING  : loglevel
      val NOTICE   : loglevel
      val INFO     : loglevel
      val DEBUG    : loglevel

      val closelog: unit -> unit
      val log: loglevel * string -> unit
      val openlog: string * openflag list * facility -> unit
   end
MLton.Syslog is a complete interface to the system logging facilities. See man 3 syslog for more details.
closelog ()
       
close the connection to the system logger.

log (l, s)
       
log message s at a loglevel l.

openlog (name, flags, facility)
       
open a connection to the system logger. name will be prefixed to each message, and is typically set to the program name.

10.2.22  MLton.TextIO

signature MLTON_TEXT_IO =
   MLTON_IO
   where type instream = TextIO.instream
   where type outstream = TextIO.outstream
See Section 10.2.9.

10.2.23  MLton.Thread

signature MLTON_THREAD =
   sig
      structure AtomicState :
         sig
            datatype t = NonAtomic | Atomic of int
         end
      val atomicBegin: unit -> unit
      val atomicEnd: unit -> unit
      val atomically: (unit -> 'a) -> 'a
      val atomicState: unit -> AtomicState.t

      structure Runnable :
         sig
            type t
         end

      type 'a t

      val new: ('a -> unit) -> 'a t
      val prepend: 'a t * ('b -> 'a) -> 'b t
      val prepare: 'a t * 'a -> Runnable.t
      val switch: ('a t -> Runnable.t) -> 'a
      val atomicSwitch: ('a t -> Runnable.t) -> 'a
   end
Threads are data structures that represent a paused computation. Runnable threads are threads that will begin or continue computing when switched to. MLton.Thread does not include a default scheduling mechanism, but it can be used to implement both preemptive and non-preemptive threads. For examples, see thread1.sml and thread2.sml in the examples directory.
type AtomicState.t
       
the type of atomic states.

atomicBegin ()
       
begin a critical section.

atomicEnd ()
       
end a critical section.

atomically f
       
runs f in a critical section.

atomicState ()
       
return the current atomic state.

type Runnable.t
       
the type of threads that can be resumed.

type 'a t
       
the type of threads that expect a value of type 'a.

new f
       
create a new thread that, when run, applies f to the value given to the thread. f must terminate by switching to another thread or exiting the process.

prepend (t, f)
       
create a new thread (destroying t in the process) that first applies f to the value given to the thread and then continues with t. This is a constant time operation.

prepare (t, v)
       
prepare a new runnable thread (destroying t in the process) that will evaluate t on v.

switch f
       
apply f to the current thread to get rt, and then start running thread rt. It is an error for f to perform another switch. f is guaranteed to run atomically.

atomicSwitch f
       
as switch, but assumes an atomic calling context. Upon switching back to the current thread, an implicit atomicEnd is performed.

10.2.24  MLton.Vector

signature MLTON_VECTOR =
   sig
      val unfoldi: int * 'b * (int * 'b -> 'a * 'b) -> 'a vector
   end
unfoldi (n, b, f)
       
construct a vector v of a length n, whose elements vi are determined by the equations b0 = b and (vi, bi+1) = f (i, bi).

10.2.25  MLton.Weak

signature MLTON_WEAK =
   sig
      type 'a t

      val get: 'a t -> 'a option
      val new: 'a -> 'a t
   end
A weak pointer is a pointer to an object that is nulled if the object becomes unreachable due to garbage collection. The weak pointer does not itself cause the object it points to be retained by the garbage collector -- only other strong pointers can do that. For objects that are not allocated in the heap, like integers, a weak pointer will always be nulled. So, if w: int Weak.t then Weak.get w = NONE.
type 'a t
       
the type of weak pointers to objects of type 'a

get w
       
returns NONE if the object pointed to by w no longer exists. Otherwise, returns SOME of the object pointed to by w.

new x
       
returns a weak pointer to x.

10.2.26  MLton.Word, MLton.Word8

signature MLTON_WORD =
   sig
      type t
         
      val rol: t * word -> t
      val ror: t * word -> t
   end
type t
       
the type of words. For MLton.Word this is Word.word, for MLton.Word8 this is Word8.word.

rol (w, w')
       
rotate left (circular).

ror (w, w')
       
rotate right (circular).

10.2.27  MLton.World

signature MLTON_WORLD =
   sig
      datatype status = Clone | Original

      val load: string -> 'a
      val save: string -> status
      val saveThread: string * Thread.Runnable.t -> unit
   end
datatype status
       
used to specify whether a world is original or restarted (a clone).

load f
       
load the saved computation from file f.

save f
       
save the entire state of the computation to the file f. The computation can then be restarted at a later time using World.load or the load-world runtime system option. The call to save in the original computation returns Original and the call in the restarted world returns Clone. The following example is a transcript run in the examples/save-world directory.
% mlton save-world.sml
% save-world
I am the original
% save-world @MLton load-world world --
I am the clone


saveThread (f, rt)
       
save the entire state of the computation to the file f that will resume with thread rt upon restart.

10.3  SMLofNJ: SML_OF_NJ

signature SML_OF_NJ =
   sig
      structure Cont:
         sig
            type 'a cont
            val callcc: ('a cont -> 'a) -> 'a
            val throw: 'a cont -> 'a -> 'b
         end
      structure SysInfo:
         sig
            exception UNKNOWN
            datatype os_kind = BEOS | MACOS | OS2 | UNIX | WIN32

            val getHostArch: unit -> string
            val getOSKind: unit -> os_kind
            val getOSName: unit -> string
         end

      val exnHistory: exn -> string list
      val exportFn: string * (string * string list -> OS.Process.status) -> unit
      val exportML: string -> bool
      val getAllArgs: unit -> string list
      val getArgs: unit -> string list
      val getCmdName: unit -> string
   end
SMLofNJ implements a subset of the structure of the same name provided in Standard ML of New Jersey. It is included to make it easier to port programs between the two systems. The semantics of these functions may be different than in SML/NJ.
structure Cont
       
implements continuations.

SysInfo.getHostArch ()
       
returns the string for the architecture.

SysInfo.getOSKind
       
returns UNIX.

SysInfo.getOSName ()
       
returns the string for the host.

exnHistory
       
the same as MLton.Exn.history.

getCmdName ()
       
the same as CommandLine.name ().

getArgs ()
       
the same as CommandLine.arguments ().

getAllArgs ()
       
the same as getCmdName() :: getArgs().

exportFn f
       
save the state of the computation to a file that will apply f to the command-line arguments upon restart.

exportML f
       
save the state of the computation to file f and continue. Return true in the restarted computation and false in the continuing computation.

10.4  Unsafe: UNSAFE

This module is a subset of the Unsafe module provided by SML/NJ.
signature UNSAFE_MONO_ARRAY =
   sig
      type array
      type elem

      val create: int -> array
      val sub: array * int -> elem
      val update: array * int * elem -> unit
   end

signature UNSAFE_MONO_VECTOR =
   sig
      type elem
      type vector

      val sub: vector * int -> elem
   end

signature UNSAFE =
   sig
      structure Array:
         sig
            val create: int * 'a -> 'a array
            val sub: 'a array * int -> 'a
            val update: 'a array * int * 'a -> unit
         end
      structure CharArray: UNSAFE_MONO_ARRAY
      structure CharVector: UNSAFE_MONO_VECTOR
      structure Real64Array: UNSAFE_MONO_ARRAY
      structure Vector:
         sig
            val sub: 'a vector * int -> 'a
         end
      structure Word8Array: UNSAFE_MONO_ARRAY
      structure Word8Vector: UNSAFE_MONO_VECTOR
   end

Previous Up Next