Top Level Environment Comparison

From SML/NJ 0.93 to SML/NJ 110 (SML '97)

This document is a quick reference for those who need to port code from SML/NJ 0.93 to SML/NJ 110 and later versions, which implement the new SML '97 Standard Basis.

It should also be useful as a supplement for those who want to use new versions of SML/NJ in conjunction with textbooks based on the SML/NJ 0.93 Basis environment.

Please send any error reports or questions regarding this document to Dave MacQueen at dbm@research.bell-labs.com.

Infixes

Here are the top level infix declarations for SML/NJ 0.93:

  infix 0 before
  infix 3 o :=
  infix 4 = <> > < >= <=
  infixr 5 :: @
  infix 6 + - ^
  infix 7 * / div mod quot rem

SML '97 is the same except that quot and rem are no longer infixes, and are not bound at top level (use Int.quot, Int.rem).

Overloading

Here are the overloaded operators of 0.93:

  makestring : ('a -> string) {Bool.makestring, Real.makestring, Integer.makestring}
  print : ('a -> unit)    {Bool.print, Integer.print, Real.print, String.print}
  ~ :   ('a -> 'a)        {Integer.~, Real.~}
  + :   ('a * 'a -> 'a)   {Integer.+, Real.+}
  - :   ('a * 'a -> 'a)   {Integer.-, Real.-}
  * :   ('a * 'a -> 'a)   {Integer.*, Real.*}
  < :   ('a * 'a -> bool) {Integer.<, Real.<, String.<}
  > :   ('a * 'a -> bool) {Integer.>, Real.>, String.>}
  <= :  ('a * 'a -> bool) {Integer.<=, Real.<=, String.<=}
  >= :  ('a * 'a -> bool) {Integer.>=, Real.>=, String.>=}
  abs : ('a -> 'a)        {Integer.abs, Real.abs}

SML '97 eliminates makestring and print as overloaded functions. At top level,

      val print = TextIO.print: string -> unit

while the overloaded makestring is replaced by the functions Bool.toString, Real.toString, and Int.toString.

mod, div are now overloaded on int and word types of various precisions, and / is overloaded on various precisions of reals. The other arithmetic and relational operators are overloaded on more types (e.g. integers, words, reals of various sizes). The relational operators are also overloaded on chars as well as strings, and there can potentially be more than one variety of chars (e.g. Ascii, Unicode), with corresponding varieties of strings.

Module Replacements

The former Basis structures

  Array
  Bool
  General
  IO
  List
  Real
  RealArray
  String
  Vector
continue to exist in SML '97, but their signatures have changed. The Ref structure no longer exists. The functions ! and := are now found in General, while the type ref and constructor ref are only bound at top level. The following former Basis structures have been renamed or replaced as indicated, again with modified signatures:
  Bits      => Word31
  ByteArray => Word8Array
  Integer   => Int
  IO        => TextIO, BinIO
Although there actually is an IO structure in SML '97, the old IO structure corresponds to the new TextIO and BinIO structures.

The Top Level Environment

SML/NJ 0.93 opens the following structures at top level:

  Ref String IO Bool List Integer Real General
It then adds the overloaded bindings and infix bindings to create the top-level environment. The top level environment also includes module bindings, which we are ignoring in this document.

The following table lists the elements in the SML/NJ 0.93 top-level environment (excluding overloaded symbols and infix declarations) with their corresponding elements in SML '97. The SML/NJ 0.93 top-level elements appear in the first column, grouped under subheadings corresponding to their home modules in SML/NJ 0.93. The second column gives the corresponding element of the SML '97 (SML/NJ 110) Basis. This is displayed as a simple identifier when it is also bound at top level, annotated by its type if different from the type in the first column. If the corresponding element is bound at top level, but comes from a different structure, a path in italics indicates its home structure. If the corresponding element is not defined at top level, column two contains a full path (nonitalicized), once again annotated by a type if the types differ.

When column two contains a simple identifier, indicating it is bound at the top level in SML '97 (SML/NJ 110), the third column gives its home module in SML '97.

Entries in column two that do not have a corresponding entry in column one are new top level bindings not present in SML/NJ 0.93.

SML/NJ 0.93 SML '97 (SML/NJ 110)
No structure
eqtype 'a ref ref
val ref : '_a -> '_a ref ref : 'a -> 'a ref
Ref
val ! : 'a ref -> 'a General.!
val := : 'a ref * 'a -> unit General.:=
val inc : int ref -> unit  
val dec : int ref -> unit  
  Char
  eqtype char
String
eqtype string string
exception Substring General.Subscript
exception Chr General.Chr
exception Ord  
val length : string -> int  
val size : string -> int size
val substring : string * int * int -> string substring
val explode : string -> string list explode: string -> char list
val implode : string list -> string implode: char list -> string
  val concat: string list -> string
val ^ : string * string -> string ^
val chr : int -> string Char.chr: int -> char
val ord : string -> int Char.ord: char -> int
val ordof : string * int -> int String.sub : string * int -> char
  val str: char -> string
IO
type instream TextIO.instream
type outstream TextIO.outstream
exception Io of string
IO.Io of {name : string,
          function : string,
          cause : exn}
val std_in : instream TextIO.stdIn : TextIO.instream
val std_out : outstream TextIO.stdOut : TextIO.outstream
val std_err : outstream TextIO.stdErr : TextIO.outstream
val open_in : string -> instream TextIO.openIn : string -> TextIO.instream
val open_out : string -> outstream TextIO.openOut : string -> TextIO.outstream
val open_append : string -> outstream TextIO.openAppend : string -> TextIO.outstream
val open_string : string -> instream TextIO.openString : string -> TextIO.instream
val close_in : instream -> unit TextIO.closeIn : TextIO.instream -> unit
val close_out : outstream -> unit TextIO.closeOut : TextIO.outstream -> unit
val output : outstream * string -> unit TextIO.output : TextIO.outstream * string -> unit
val outputc : outstream -> string -> unit  
val input : instream * int -> string TextIO.inputN : TextIO.instream * int -> string
val inputc : instream -> int -> string  
val input_line : instream -> string TextIO.inputLine : TextIO.instream -> string
val lookahead : instream -> string TextIO.lookahead : TextIO.instream -> char option
val end_of_stream : instream -> bool TextIO.endOfStream : TextIO.instream -> bool
val can_input : instream -> int TextIO.canInput : TextIO.instream * int -> bool
val flush_out : outstream -> unit TextIO.flushOut : TextIO.outstream -> unit
val is_term_in : instream -> bool [Note 1]
val is_term_out : outstream -> bool [Note 2]
val set_term_in : instream * bool -> unit  
val set_term_out : outstream * bool -> unit  
val execute :
 (string * string list)
 -> instream * outstream
Unix.execute :
 string * string list -> Unix.proc [Note 3]
val execute_in_env :
 string * string list * string list
 -> instream * outstream
Unix.executeInEnv :
 string * string list * string list
 -> Unix.proc
val exportML : string -> bool SMLofNJ.exportML
val exportFn :
 string *
 (string list * string list -> unit)
 -> unit					    
SMLofNJ.exportFn: 
 string *
 (string * string list -> OS.Process.status)
 -> 'a
  val TextIO.print: string -> unit
Bool
datatype bool = true | false
datatype bool = true | false
datatype 'a option = NONE | SOME of 'a
Option.option
Option.NONE
Option.SOME
val not : bool -> bool not
List
datatype 'a list
  = nil
  | :: of ('a * 'a list)
datatype 'a list
  = nil
  | :: of ('a * 'a list)
  exception Empty
exception Hd Empty
exception Tl Empty
exception Nth General.Subscript
exception NthTail General.Subscript
val hd : 'a list -> 'a hd
val tl : 'a list -> 'a list tl
val null : 'a list -> bool null
val length : 'a list -> int length
val @ : 'a list * 'a list -> 'a list @
val rev : 'a list -> 'a list rev
val map : ('a -> 'b) -> 'a list -> 'b list map
val fold :
 ('a * 'b -> 'b) -> 'a list
 -> 'b -> 'b
foldr :
 ('a * 'b -> 'b) -> 'b
 -> 'a list -> 'b
val revfold :
 ('a * 'b -> 'b) -> 'a list
 -> 'b -> 'b
foldl :
 ('a * 'b -> 'b) -> 'b
 -> 'a list -> 'b
val app : ('a -> 'b) -> 'a list -> unit app: ('a -> unit) -> 'a list -> unit
val revapp : ('a -> 'b) -> 'a list -> unit  
val nth : 'a list * int -> 'a List.nth
val nthtail : 'a list * int -> 'a list List.drop
val exists : ('a -> bool) -> 'a list -> bool List.exists
IntegerInt
eqtype int int
exception Sum General.Overflow
exception Diff General.Overflow
exception Prod General.Overflow
exception Neg General.Overflow
exception Quot General.Div
exception Abs General.Overflow
exception Div General.Div
exception Mod General.Div
exception Overflow General.Overflow
val div : int * int -> int div (overloaded: Int.div)
val mod : int * int -> int mod (overloaded: Int.mod)
val quot : int * int -> int Int.quot
val rem : int * int -> int Int.rem
val min : int * int -> int Int.min
val max : int * int -> int Int.max
Real
eqtype real type real [not eqtype!]
exception Sum General.Overflow
exception Diff General.Overflow
exception Prod General.Overflow
exception Floor General.Overflow
exception Sqrt General.Overflow
exception Exp General.Overflow
exception Ln General.Overflow
exception Div General.Div
exception Overflow General.Overflow
val / : (real * real) -> real / (Real./,...)
val real : int -> real Real.fromInt
val floor : real -> int floor
val truncate : real -> int trunc
val ceiling : real -> int ceil
  val round : real -> int
val sqrt : real -> real Math.sqrt
val sin : real -> real Math.sin
val cos : real -> real Math.cos
val arctan : real -> real Math.atan
val exp : real -> real Math.exp
val ln : real -> real Math.ln
General
type 'a cont SMLofNJ.cont
type exn type exn
type unit type unit
datatype 'a frag
  = QUOTE of string
  | ANTIQUOTE of 'a
SMLofNJ.frag
SMLofNJ.QUOTE
SMLofNJ.ANTIQUOTE
 
datatype order
  = LESS | EQUAL | GREATER
exception Bind Bind
exception Match Match
exception Interrupt  
exception Fail of string Fail
  exception Option
  exception Subscript
  exception Chr
  exception Div
val use : string -> unit use (= Compiler.Interact.useFile)
val callcc : ('_a cont -> '_a) -> '_a SMLofNJ.Cont.callcc : ('a cont -> 'a) -> 'a
val throw : 'a cont -> 'a -> 'b SMLofNJ.Cont.throw
val o : ('b -> 'c) * ('a -> 'b) -> ('a -> 'c) o
val before : ('a * 'b) -> 'a before : ('a * unit) -> 'a
  val ignore : 'a -> unit
  val exnName : exn -> string
  val exnMessage : exn -> string
val = : ''a * ''a -> bool =
val <> : ''a * ''a -> bool <>
  Option
  datatype 'a option = NONE | SOME of 'a
  val getOpt : ('a option * 'a) -> 'a
  val isSome : 'a option -> bool
  val valOf : 'a option -> 'a
  Other New SML '97 Elements
  eqtype Word.word
  type Substring.substring
  eqtype 'a Array.array
  eqtype 'a Vector.vector
  val Vector.vector : 'a list -> 'a vector

Notes

  1. The is_term_in function can be defined as follows:
        fun is_term_in (instream : TextIO.instream) =
    	let val (rd as TextPrimIO.RD{ioDesc,...}, buf) =
    		 TextIO.StreamIO.getReader(TextIO.getInstream instream)
    	 in TextIO.setInstream (instream, TextIO.StreamIO.mkInstream(rd, SOME buf));
    	    case ioDesc
    	      of NONE => false
    	       | SOME desc => (OS.IO.kind desc = OS.IO.Kind.tty)
    	end
    
  2. The is_term_out function can be defined as follows:
        fun is_term_out (outstream: TextIO.outstream) =
            let val (wr as TextPrimIO.WR{ioDesc,...},buf) =
    	        TextIO.StreamIO.getWriter(TextIO.getOutstream outstream)
             in TextIO.setOutstream (outstream, TextIO.StreamIO.mkOutstream(wr,buf));
    	    case ioDesc
    	      of NONE => false
    	       | SOME desc => (OS.IO.kind desc = OS.IO.Kind.tty)
            end