|
|
1.1 root 1: \chapter{The standard library}
2: \label{library}
3:
4: A standard set of values, types, exceptions, etc. are {\em
5: pervasive}---they are in the initial environment and available in
6: every structure. This {\em standard library} is grouped into
7: structures; each structure deals with the operations on one or two
8: abstract types. The signature of each of these modules, with an
9: informal explanation of the semantics, is given in this chapter.
10:
11: \begin{verbatim}
12: signature GENERAL =
13: sig
14: infix 3 o
15: infix before
16: exception Bind
17: exception Match
18: exception Interrupt
19: exception SystemCall of string
20: val callcc : ('a cont -> 'a) -> 'a
21: val throw : 'a cont -> 'a -> 'b
22: val o : ('b -> 'c) * ('a -> 'b) -> ('a -> 'c)
23: val before : ('a * 'b) -> 'a
24: datatype 'a option = NONE | SOME of 'a
25: type 'a cont
26: type exn
27: type unit
28: infix 4 = <>
29: val = : ''a * ''a -> bool
30: val <> : ''a * ''a -> bool
31: end
32:
33: abstraction General : GENERAL
34: \end{verbatim}
35: The structure \verb"General" contains various miscellaneous and
36: general-purpose values, types, and exceptions. The infix \verb"o"
37: is the function composition operator. The infix \verb"before" evaluates
38: both of its arguments and returns the first one. The exceptions
39: \verb"Bind" and \verb"Match" are automatically raised by patterns
40: that fail to match, as explained in chapter~\ref{eval}. The exception
41: \verb"Interrupt" is raised when the INTERRUPT signal is received
42: (e.g. when the user types Control-C or its equivalent).
43: The functions \verb"callcc" and \verb"throw" and the type \verb"'a cont"
44: are used for explicit manipulation of continuations, as explained nowhere.
45: The standard type \verb"exn"
46: is the type of all exceptions and \verb"unit" is the type of empty
47: records. The \verb"=" and \verb"<>" operators are defined here {\it pro
48: forma}. And finally, the \verb"option" datatype is one we have often found
49: convenient.
50:
51: \section{List}
52: \begin{verbatim}
53: signature LIST =
54: sig
55: infixr 5 :: @
56: datatype 'a list = :: of ('a * 'a list) | nil
57: exception Hd
58: exception Tl
59: exception Nth
60: exception NthTail
61: val hd : 'a list -> 'a
62: val tl : 'a list -> 'a list
63: val null : 'a list -> bool
64: val length : 'a list -> int
65: val @ : 'a list * 'a list -> 'a list
66: val rev : 'a list -> 'a list
67: val map : ('a -> 'b) -> 'a list -> 'b list
68: val fold : (('a * 'b) -> 'b) -> 'a list -> 'b -> 'b
69: val revfold : (('a * 'b) -> 'b) -> 'a list -> 'b -> 'b
70: val app : ('a -> 'b) -> 'a list -> unit
71: val revapp : ('a -> 'b) -> 'a list -> unit
72: val nth : 'a list * int -> 'a
73: val nthtail : 'a list * int -> 'a list
74: val exists : ('a -> bool) -> 'a list -> bool
75: end
76: \end{verbatim}
77: The semantics of this module are defined by the
78: following implementation.
79: \begin{verbatim}
80: abstraction List: LIST =
81: struct
82: infixr 5 :: @
83: infix 6 + -
84: datatype 'a list = :: of ('a * 'a list) | nil
85: exception Hd
86: fun hd (a::r) = a | hd nil = raise Hd
87: exception Tl
88: fun tl (a::r) = r | tl nil = raise Tl
89: fun null nil = true | null _ = false
90: fun length nil = 0 | length (a::r) = 1 + length r
91: fun op @ (nil,l) = l | op @ (a::r, l) = a :: (r@l)
92: fun rev l = let fun f (nil, h) = h
93: | f (a::r, h) = f(r, a::h)
94: in f(l,nil)
95: end
96: fun map f = let fun m nil = nil | m (a::r) = f a :: m r
97: in m
98: end
99: fun fold f = let fun f2 nil = (fn b => b)
100: | f2 (e::r) = (fn b => f(e,(f2 r b)))
101: in f2
102: end
103: fun revfold f l = fold f (rev l)
104: fun app f l = (map f l; ())
105: fun revapp f l = app f (rev l)
106: exception Nth
107: fun nth(e::r,0) = e
108: | nth(e::r,n) = nth(r,n-1)
109: | nth _ = raise Nth
110: exception NthTail
111: fun nthtail(e,0) = e
112: | nth(e::r,n) = nthtail(r,n-1)
113: | nth _ = raise NthTail
114: fun exists f =
115: let fun g nil = false | g (h::t) = f h orelse g t
116: in g
117: end
118: end
119: \end{verbatim}
120: \section{Array}
121: \begin{verbatim}
122: signature ARRAY =
123: sig
124: infix 3 sub
125: type 'a array
126: exception Subscript
127: val array : int * '1a -> '1a array
128: val sub : 'a array * int -> 'a
129: val update : 'a array * int * 'a -> unit
130: val length : 'a array -> int
131: val arrayoflist : 'a list -> 'a array
132: end
133: \end{verbatim}
134: Arrays may be made whose elements are any type. \verb"array(n,x)"
135: returns a new array of $n$ elements, indexed from $0$ to $n-1$,
136: initialized to $x$. \verb"a sub i" returns the $i^{th}$ element of
137: the array $a$. \verb"update(a,i,z)" sets the $i^{th}$ element of the
138: array $a$ to the value $z$.
139:
140: Two arrays are equal if and only if they are the same array (created
141: with the same call to \verb"array"); except that all arrays of length
142: 0 may be equal to each other, depending on the implementation.
143:
144: The following implementation defines the semantics of arrays, though
145: in practice arrays are implemented much more efficiently.
146: \begin{verbatim}
147: abstraction Array : ARRAY =
148: struct
149: type 'a array = 'a ref list
150: exception Subscript
151: fun array(0,x) = nil | array(n,x) = ref x :: array(n-1,x)
152: fun a sub i = !(nth(a,i)) handle Nth => raise Subscript
153: fun update(a,i,z) = nth(a,i) := z handle Nth => raise Subscript
154: fun length a = List.length a
155: fun arrayoflist l = l
156: end
157: \end{verbatim}
158: \section{Input/Output}
159: The input/output primitives are intended as a simple basis that may
160: be compatibly superseded by a more comprehensive I/O system that
161: provides for streams of arbitrary type or a richer repertoire of I/O
162: operations. The IO structure contains all I/O primitives; this
163: structure will in all implementation
164: match (with thinning) the BASICIO signature provided
165: below, but may contain other primitives as well.
166:
167: \begin{verbatim}
168: signature BASICIO =
169: sig
170: type instream
171: type outstream
172: exception Io of string
173: val std_in : instream
174: val std_out : outstream
175: val open_in : string -> instream
176: val open_out : string -> outstream
177: val close_in : instream -> unit
178: val close_out : outstream -> unit
179: val output : outstream -> string -> unit
180: val input : instream -> int -> string
181: val lookahead : instream -> string
182: val end_of_stream : instream -> bool
183: end
184:
185: \end{verbatim}
186: The type \verb"instream" is the type of input streams and the type
187: \verb"outstream" is the type of output streams. The exception
188: \verb"Io" is used to represent all of the errors that may
189: arise in the course of performing I/O. The value associated with
190: this exception is a string representing the type of failure. In
191: general, any I/O operation may fail if, for any reason, the host
192: system is unable to perform the requested task. The value associated
193: with the exception should describe the type of failure, insofar as
194: this is possible.
195:
196: The standard prelude binds \verb"std_in" to an instream and
197: \verb"std_out" to an outstream. For interactive ML processes, these
198: are expected to be associated with the user's terminal. However, an
199: implementation that supports the connection of processes to streams
200: may associate one process's \verb"std_in" to another's
201: \verb"std_out".
202:
203: The \verb"open_in" and \verb"open_out" primitives are used to
204: associate a disk file with a stream. The expression
205: \verb"open_in(s)" creates a new instream whose producer is the file
206: named \verb"s" and returns that stream as a value.
207: Similarly, \verb"open_out(s)" creates a new \verb"outstream"
208: associated with the file \verb"s", and returns that stream.
209:
210: The \verb"input" primitive is used to read characters from a stream.
211: Evaluation of \verb"input s n" causes the removal of \verb"n"
212: characters from the input stream \verb"s". If fewer than \verb"n"
213: characters are currently available, then the ML system will block
214: until they become available from the producer associated with
215: \verb"s"\footnote{The exact definition of ``available'' is
216: implementation-dependent. For instance, operating systems typically
217: buffer terminal input on a line-by-line basis so that no characters
218: are available until an entire line has been typed.}.
219: If the end of stream is reached while processing an \verb"input",
220: fewer than \verb"n" characters may be returned.
221: Attempting \verb"input" from a closed stream raises
222: \verb"Io".
223:
224: The function \verb"lookahead(s)" returns the next character on
225: \verb"instream s" without removing it from the stream. Input streams
226: are terminated by the \verb"close_in" operation. This primitive is
227: provided primarily for symmetry and to support the re-use of
228: unused streams on resource-limited systems. The end of an input
229: stream is detected by \verb"end_of_stream", a derived form that is
230: defined as follows:
231: \begin{verbatim}
232: fun end_of_stream(s) = (lookahead(s)="")
233: \end{verbatim}
234:
235: Characters are written to an \verb"outstream" with the \verb"output"
236: primitive. The string argument consists of the characters to be
237: written to the given outstream. The function \verb"close_out" is
238: used to terminate an output stream. Any further attempts to output
239: to a closed stream cause \verb"Io" to be raised.
240:
241: \begin{verbatim}
242: signature IO =
243: sig
244: type instream
245: type outstream
246: exception Io of string
247: val std_in : instream
248: val std_out : outstream
249: val open_in : string -> instream
250: val open_out : string -> outstream
251: val open_append : string -> outstream
252: val open_string : string -> instream
253: val close_in : instream -> unit
254: val close_out : outstream -> unit
255: val output : outstream -> string -> unit
256: val input : instream -> int -> string
257: val input_line : instream -> string
258: val lookahead : instream -> string
259: val end_of_stream : instream -> bool
260: val can_input : instream -> int
261: val flush_out : outstream -> unit
262: val is_term_in : instream -> bool
263: val is_term_out : outstream -> bool
264: val set_term_in : instream * bool -> unit
265: val set_term_out : outstream * bool -> unit
266: val execute : string -> instream * outstream
267: val exportML : string -> bool
268: val exportFn : string * (string list * string list -> unit) -> unit
269: val use : string -> unit
270: val use_stream : instream -> unit
271: val reduce : ('a -> 'b) -> ('a -> 'b)
272: val mtime : instream -> int
273: (* the following are temporary components *)
274: val reduce_r : ((unit -> unit) -> (unit -> unit)) ref
275: val cleanup : unit -> unit
276: val use_f : (string -> unit) ref
277: val use_s : (instream -> unit) ref
278: end
279:
280: structure IO : IO
281: \end{verbatim}
282:
283: In addition to the basic I/O primitives, provision is made for some
284: extensions that are likely to be provided by many implementations.
285: The functions listed above are provided by Standard ML of New Jersey.
286:
287: The function \verb"execute" is used to create a pair of streams, one an
288: \verb"instream" and one an \verb"outstream", and associate them with
289: a process. The string argument to \verb"execute" is the
290: operating-system command that starts the process.
291:
292: The function \verb"flush_out" ensures that the consumer associated
293: with an \verb"out_stream" has received all of the characters
294: associated with that stream. It is provided primarily to allow the
295: ML user to circumvent undesirable buffering characteristics that may
296: arise in connection with terminals and other processes. All output
297: streams are flushed when they are closed, and in many implementations
298: an output stream is flushed whenever a newline character is written
299: if that stream is connected to a terminal.
300:
301: The function \verb"can_input" returns the number of characters
302: which may be read from its instream argument without blocking.
303: For instance, a command processor may wish
304: to test whether or not a user has typed ahead in order to avoid an
305: unnecessary prompt. The exact definition of ``currently available''
306: is implementation specific, perhaps depending on such things as the
307: processing mode of a terminal.
308:
309: The \verb"input_line" primitive returns a string consisting of the
310: characters from an \verb"instream" up through, and including, the
311: next end of line character. If the end of stream is reached without
312: reaching an end of line character, all remaining characters from the
313: stream ({\em without} an end of line character) are returned.
314:
315: Files may be open for output while preserving their contents by using
316: the \verb"open_append" primitive. Subsequent \verb"output" to the
317: outstream returned by this primitive is appended to the contents of
318: the specified file.
319:
320: Basic support for the complexities of terminal I/O are provided. The
321: pair of functions \verb"is_term_in" and \verb"is_term_out" test
322: whether or not a stream is associated with a terminal; and \verb"set_term_in"
323: and \verb"set_term_out" tell the ML system that a stream is (or is not)
324: a terminal. These
325: functions are especially useful with \verb"std_in" and \verb"std_out"
326: because they are opened as part of the standard prelude. A terminal
327: may be associated with a stream using the ordinary \verb"open_in" and
328: \verb"open_out" functions; the naming convention to do this is
329: implementation-dependent.
330:
331: Given a name of a file, \verb"use" compiles
332: and executes its contents as if they were typed into the top-level
333: prompt of the interactive system. \verb"use" may be nested
334: recursively. Similarly, \verb"use_stream"
335: compiles an already-opened instream.
336:
337: \verb"exportML" creates an executable file whose name is
338: given by the argument. When this file is executed, it is an ML
339: system in exactly the same state as the one that wrote the file. For
340: example, the command
341: \verb|(exportML "foo"; print "Hello");| writes a file that, when
342: executed, prints \verb"Hello" and then returns to the top-level
343: prompt. exportML returns true when the executable file is run,
344: and false when simply returning.
345:
346: \verb"exportFn" creates an executable file whose name is given
347: by the first argument. When this file is executed, it is an ML
348: system that calls the function given as the second argument, then
349: exits. The ML system created will not have a compiler or a
350: top-level, so it will be significantly more compact.
351: The command-line arguments and environment
352: are passed as the string list arguments to the
353: function that is called. \verb"exportFn" terminates
354: execution of the ML system that called it.
355:
356: \section{Bool}
357: \begin{verbatim}
358: signature BOOL =
359: sig
360: datatype bool = true | false
361: val not: bool -> bool
362: val print: bool -> bool
363: val makestring: bool -> string
364: end
365: \end{verbatim}
366: These are quite straightforward, and can be defined as follows:
367: \begin{verbatim}
368: abstraction Bool: BOOL =
369: struct
370: datatype bool = true | false
371: fun not true = false | not false = true
372: fun makestring true = "true" | makestring false = "false"
373: fun print b = (output(std_out, makestring b); b)
374: end
375: \end{verbatim}
376: \section{ByteArray}
377: \begin{verbatim}
378: signature BYTEARRAY =
379: sig
380: infix 3 sub
381: eqtype bytearray
382: exception Subscript
383: exception Range
384: val array : int * int -> bytearray
385: val sub : bytearray * int -> int
386: val update : bytearray * int * int -> unit
387: val length : bytearray -> int
388: val extract : bytearray * int * int -> string
389: val fold : ((int * 'b) -> 'b) -> bytearray -> 'b -> 'b
390: val revfold : ((int * 'b) -> 'b) -> bytearray -> 'b -> 'b
391: val app : (int -> 'a) -> bytearray -> unit
392: val revapp : (int -> 'b) -> bytearray -> unit
393: end
394: \end{verbatim}
395: Byte arrays are just like arrays of integers, with the restriction
396: that the values of the component integers must be between 0 and 255.
397: The intent is that the implementation may store them more efficiently
398: than the equivalent array.
399:
400: Note that, by default, the ByteArray structure is present but
401: not opened in the
402: initial environment. The declaration \verb"open ByteArray" may be
403: used to open it. The use of ByteArray is discouraged; future versions of the
404: compiler may not support it, or (for example) debuggers might
405: not support it.
406:
407: The semantics can be defined by this implementation:
408: \begin{verbatim}
409: abstraction ByteArray : BYTEARRAY =
410: struct
411: infix 3 sub
412: type bytearray = int array
413: exception Subscript = Array.Subscript
414: exception Range
415: fun check x = if x<0 orelse x>255 then raise Range else ()
416: fun array(i,x) = (check x; Array.array(i,x))
417: val length = Array.length
418: fun update(a,i,x) = (check x; Array.update(a,i,x))
419: val op sub = Array.sub
420: fun extract(b,i,0) = if i<0 orelse i>length(b)
421: then raise Subscript else ""
422: | extract(b,i,n) = chr(b sub i) ^ extract(b,i,n-1)
423: val fold = . . .
424: val revfold = . . .
425: val app = ...
426: val revapp = ...
427: end
428: \end{verbatim}
429:
430: \section{Integer}
431: \begin{verbatim}
432: signature INTEGER =
433: sig
434: infix 7 * div mod
435: infix 6 + -
436: infix 4 > < >= <=
437: exception Div
438: exception Overflow
439: type int
440: val ~ : int -> int
441: val * : int * int -> int
442: val div : int * int -> int
443: val mod : int * int -> int
444: val + : int * int -> int
445: val - : int * int -> int
446: val > : int * int -> bool
447: val >= : int * int -> bool
448: val < : int * int -> bool
449: val <= : int * int -> bool
450: val min : int * int -> int
451: val max : int * int -> int
452: val abs : int -> int
453: val print : int -> unit
454: val makestring : int -> string
455: end
456: \end{verbatim}
457: This should be mostly self-explanatory.
458: The function \verb"div" raises \verb"Div" on divide by zero,
459: otherwise \verb"Overflow" if the result doesn't fit; similarly
460: \verb"mod" may raise \verb"Div" or \verb"Overflow". Other operators
461: may raise \verb"Overflow" if the result doesn't fit into their
462: representation.
463: Standard ML of New Jersey uses finite precision signed 31-bit integers,
464: which can represent a range from $-2^{30}$ to $2^{30}-1$.
465: \section{Real}
466: \begin{verbatim}
467: signature REAL =
468: sig
469: infix 7 * /
470: infix 6 + -
471: infix 4 > < >= <=
472: type real
473: exception Floor and Sqrt and Exp and Ln
474: exception Real of string
475: val ~ : real -> real
476: val + : (real * real) -> real
477: val - : (real * real) -> real
478: val * : (real * real) -> real
479: val / : (real * real) -> real
480: val > : (real * real) -> bool
481: val < : (real * real) -> bool
482: val >= : (real * real) -> bool
483: val <= : (real * real) -> bool
484: val abs : real -> real
485: val real : int -> real
486: val floor : real -> int
487: val truncate : real -> int
488: val ceiling : real -> int
489: val sqrt : real -> real
490: val sin : real -> real
491: val cos : real -> real
492: val arctan : real -> real
493: val exp : real -> real
494: val ln : real -> real
495: val print : real -> unit
496: val makestring : real -> string
497: end
498: structure Real : REAL
499: \end{verbatim}
500:
501: This should be mostly self-explanatory. Except for the special
502: exceptions \verb"Floor", \verb"Sqrt", \verb"Exp", \verb"Ln", raised by
503: the functions of the corresponding names, all real-number functions
504: raise only the \verb"Real" exception with some system dependent
505: argument string.
506:
507: \section{Ref}
508: \begin{verbatim}
509: signature REF =
510: sig
511: infix 3 :=
512: val ! : 'a ref -> 'a
513: val := : 'a ref * 'a -> unit
514: val inc : int ref -> unit
515: val dec : int ref -> unit
516: end
517: \end{verbatim}
518:
519: Reference values are described in chapter~\ref{reference}. The functions
520: \verb"inc" and \verb"dec" can be defined as
521: \begin{verbatim}
522: fun inc i = i := !i+1
523: fun dec i = i := !i-1
524: \end{verbatim}
525:
526: \section{String}
527: \begin{verbatim}
528: signature STRING =
529: sig
530: infix 6 ^
531: infix 4 > < >= <=
532: type string
533: exception Substring
534: val length : string -> int
535: val size : string -> int
536: val substring : string * int * int -> string
537: val explode : string -> string list
538: val implode : string list -> string
539: val <= : string * string -> bool
540: val < : string * string -> bool
541: val >= : string * string -> bool
542: val > : string * string -> bool
543: val ^ : string * string -> string
544: exception Chr
545: val chr : int -> string
546: exception Ord
547: val ord : string -> int
548: val ordof : string * int -> int
549: val print : string -> string
550: end
551: \end{verbatim}
552: Strings can be explained by the implementation below; of course, in
553: practice a more efficient implementation is used.
554: \begin{verbatim}
555: abstraction String : STRING =
556: struct
557: infix 6 ^
558: infix 4 > < >= <=
559: type string = int list
560: exception Substring
561: val length = List.length
562: val size = length
563: fun substring(s,0,0) = nil
564: | substring(a::b,0,len) = a::substring(b,0,len-1)
565: | substring(nil,_,_) = raise Substring
566: | substring(a::b,i,len) = substring(b,i-1,len)
567: fun explode nil = nil
568: | explode (i::l) = [i] :: explode l
569: fun implode nil = nil
570: | implode (s::l) = s @ implode l
571: fun (_::_) > nil = true
572: | nil > (_::_) = false
573: | (i::r) > (j::s) = Integer.>(i,j) orelse i=j andalso r>s
574: fun a <= b = not (a>b)
575: fun a < b = b > a
576: fun a >= b = b <= a
577: val op ^ = op @
578: exception Chr
579: fun chr i = if i<0 orelse i>255 then raise Chr else [i]
580: exception Ord
581: fun ord nil = raise Ord | ord (i::r) = i
582: fun ordof(s,i) = nth s handle Nth => raise Ord
583: fun print s = (output(std_out,s); s)
584: end
585: \end{verbatim}
586: \section{Bits}
587: \begin{verbatim}
588: signature BITS =
589: sig
590: type int
591: val orb : int * int -> int
592: val andb : int * int -> int
593: val xorb : int * int -> int
594: val lshift : int * int -> int
595: val rshift : int * int -> int
596: val notb : int * int -> int
597: end
598: structure Bits : BITS
599: \end{verbatim}
600: The structure Bits allows shifting and masking of integers (viewed as
601: strings of binary digits). This structure is present but
602: {\em not} opened in the standard environment; its use is discouraged.
603: The right shift (rshift) operator may shift 0's, 1's, or sign bits
604: into the left end of an integer at its discretion.
605: \section{System}
606: \begin{verbatim}
607: signature SYSTEM =
608: sig
609: structure Control : CONTROL
610: structure Tags : TAGS
611: structure Timer : TIMER
612: structure Stats : STATS
613: structure Unsafe : UNSAFE
614: val exn_name : exn -> string
615: val version : string
616: val interactive : bool ref
617: val cleanup : unit -> unit
618: val system : string -> unit
619: val cd : string -> unit
620: val argv : unit -> string list
621: val environ : unit -> string list
622: end
623: structure System : SYSTEM
624: \end{verbatim}
625: Features of Standard ML of New Jersey
626: that should not be expected in any other implementation of ML
627: are grouped into the System structure, which is present but not opened
628: in the standard environment.
629:
630: The substructures \verb"Control" of \verb"System" are not documented.
631:
632: The function \verb"exn_name" returns the name of the exception constructor
633: that was used to build a given exception value. The \verb"version" string
634: indicates which version of Standard ML of New Jersey is running.
635: The variable \verb"interactive" may be set to indicate whether the
636: compiler's input stream should be treated as interactive (i.e. issue
637: primary and secondary prompts, read a line at a time) or non-interactive
638: (i.e. no prompts, read a large block at a time). The \verb"cleanup"
639: function closes all files. The \verb"system" function runs an operating-system
640: (shell) command specified by its argument. \verb"cd" changes the
641: current working directory. \verb"argv" and \verb"environment" return
642: the command-line
643: argument-list and (Unix) environment with which the Standard ML
644: process was created.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.