## 9 MLton extensions

### 9.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 `*)`.

### 9.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 safe: bool
          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

#### 9.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 basis library, and is always false in a stub library.
`safe`
  a compile time constant that reflects the value of the `-safe` switch. It make it easy to include assertions and checks in code that you would like removed when running at full speed. MLton's optimizer will remove any uses of `safe` at compile time. For example, array subscripting might be implemented as:

      fun sub (a, i) =
         if MLton.safe andalso (i < 0 orelse i >= length a)
            then raise Subscript
         else unsafeSub (a, i)

  When compiled `-safe false`, `sub` will reduce to `unsafeSub`.
`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`.

#### 9.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).

#### 9.2.3 `MLton.BinIO`

    signature MLTON_BIN_IO =
       MLTON_IO
       where type instream = BinIO.instream
       where type outstream = BinIO.outstream

See Section 9.2.9.

#### 9.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.

#### 9.2.5 `MLton.Exn`

    signature MLTON_EXN =
       sig
          val history: exn -> string list
          val topLevelHandler: exn -> 'a
       end

`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.

#### 9.2.6 `MLton.Finalizable`

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 9.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 9.2.23).
For an example, see the `examples/finalizable` directory.

    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

`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 caleed 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.

#### 9.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.

#### 9.2.8 `MLton.IntInf`

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.

    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
          val size: t -> int
       end

`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.
`size i`
  return the number of heap words taken by `i`. Returns `0` if `i` is small.

#### 9.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`.

#### 9.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`.

#### 9.2.11 `MLton.Platform`

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

                val fromString: string -> t option
                val host: t
                val toString: t -> string
             end

          structure OS:
             sig
                datatype t = Cygwin | FreeBSD | Linux | NetBSD | 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.

#### 9.2.12 `MLton.Pointer`

    signature MLTON_POINTER =
       sig
          eqtype t

          val add: t * word -> t
          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.
`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.

#### 9.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.

#### 9.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`.

#### 9.2.15 `MLton.Profile`

This structure 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`.

    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

`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 ()`.

#### 9.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.

#### 9.2.17 `MLton.Rlimit`

This structure provides a wrapper around the C `getrlimit` and `setrlimit`.

    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

`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`.

#### 9.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.

#### 9.2.19 `MLton.Signal`

Signals handlers are functions from threads to 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. To avoid the possibility of aynchronous exceptions, it is an error for to `Thread.switch'` to an interrupted thread with a thunk that raises an exception (either directly, or via `Thread.prepend`). All signals are automatically blocked for the duration of a handler. Signal handlers will never run during a critical section (see Section 9.2.23).

    signature MLTON_SIGNAL =
       sig
          type t
          type signal = t

          structure Handler:
             sig
                type t

                val default: t
                val handler: (unit Thread.t -> unit Thread.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 none: t
                val setBlocked: t -> unit
                val some: signal list -> t
                val unblock: t -> unit
             end

          val getHandler: t -> Handler.t
          val prof: t
          val setHandler: t * Handler.t -> unit
          val suspend: Mask.t -> unit
          val vtalrm: t
       end

`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.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`.
`prof`
  `SIGPROF`, the profiling signal.
`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.

#### 9.2.20 `MLton.Socket`

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.

    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

`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.

#### 9.2.21 `MLton.Syslog`

A complete interface to the system logging facilities. See `man 3 syslog` for more details.

    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

`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.

#### 9.2.22 `MLton.TextIO`

    signature MLTON_TEXT_IO =
       MLTON_IO
       where type instream = TextIO.instream
       where type outstream = TextIO.outstream

See Section 9.2.9.

#### 9.2.23 `MLton.Thread`

Threads are data structures that will begin computing when `switch`ed to with a value. `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.

    signature MLTON_THREAD =
       sig
          type 'a t

          val atomicBegin: unit -> unit
          val atomicEnd: unit -> unit
          val new: ('a -> unit) -> 'a t
          val prepend: 'a t * ('b -> 'a) -> 'b t
          val switch: ('a t -> 'b t * 'b) -> 'a
          val switch': ('a t -> 'b t * (unit -> 'b)) -> 'a
       end

`type 'a t`
  the type of threads that expect a value of type `'a`.
`atomicBegin ()`
  begin a critical section.
`atomicEnd ()`
  end a critical section.
`new f`
  create a new thread that, when run, applies `f` to the value given to the thread.
`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.
`switch f`
  apply `f` to the current thread to get `(t, v)`, and then start running thread `t` on value `v`. It is an error for `f` to perform another `switch`. `f` is guaranteed to run atomically.
`switch' f`
  apply `f` to the current thread to get `(t, g)`, and then start running thread `t` computing the value `g ()`.

#### 9.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).

#### 9.2.25 `MLton.Weak`

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`.

    signature MLTON_WEAK =
       sig
          type 'a t

          val get: 'a t -> 'a option
          val new: 'a -> 'a t
       end

`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`.

#### 9.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).

#### 9.2.27 `MLton.World`

    signature MLTON_WORLD =
       sig
          datatype status = Clone | Original

          val load: string -> 'a
          val save: string -> status
          val saveThread: string * unit Thread.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, t)`
  save the entire state of the computation to the file `f` that will resume with thread `t` upon restart.

### 9.3 `SMLofNJ: SML_OF_NJ`

`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.

    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

`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.

### 9.4 `Unsafe: UNSAFE`

This module is a subset of the `Unsafe` module provided by SML/NJ. It is included in MLton because the code generated by ML-Yacc includes references to unsafe subscript operations.

    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