CML Help Contents Page

Welcome to CML Help. This gives help on using the CML system as well as tutorial material on the ML language and CML's extra features.

If you are unfamiliar with Windows then try running the Windows Tutorial which can be found under the Help menu of the Program Manager.

From here you can get help on:

Getting Started

Simple Editing and File Use

CML Menus

CML Reference

A Simple Glossary

Installing CML on your own computer

Credits

Please send any comments to Arthur.Norman@cl.


Getting Started

When you start CML it loads up its main data file and then becomes quiescent. The (red) "-" is the prompt, and indicates that CML is waiting for your input.

Evaluating expressions

Try typing "2+2" and pressing return. CML replies with another prompt (a red "="); it has remembered the previous line but is still expecting some more text. The end of sentence marker in ML is a semicolon (like a fullstop in English). Typing ";" and pressing return completes the input and CML replies with "4 : int". 4 is the value of the result and int is its type, i.e., the type of integer values. CML always tells you the type of any value it displays. Try typing in a few arithmetic expressions (using +,-,* and div) to see what response you get (don't forget the semicolons).

Declaring Values

Each time you type in an expression at the prompt, CML evaluates it, displays the result and assigns the result to the special variable it. Just typing it; and pressing return should redisplay the value of the last expression you entered.

You can assign a value to a name using the val construct. For instance, typing this into CML:

val foo = 400 div 2 + 17 - 33;

gives the reply:

val foo = 184 : int

The value 184 has now been bound to the name foo and can be used in any expressions from this point onward, foo-30; for instance. Looked at the other way round foo has been declared (defined) to be the value 184.

The val binding for foo above is only the simplest form of binding allowed in CML.

Should really finish this section!


Simple editing and file use

For your first few sessions with CML it will make sense to type in all of your programs each time you want to try them. However after a while you will want to save programs as files and edit existing ones to correct the mistakes in them or to extend their capabilities.

One reasonable way to do all this is to use the NOTEPAD application that Windows stores in its "Accessories" folder.  Locate the accessories folder and if it is shown in your "program manager" group as just a little icon, double-click on it to see the items available in it, then double-click on "Notepad" to start that up.  You should see an area into which you can type text, with File, Edit, Search and Help menus available.

If you type a program into the notepad you can use the FILE menu to store your code away.  For ML programs please use a name that ends in ".ml", for instance "mycode.ml". The notepad allows you to re-position the caret and insert, delete or change characters. It is not a very elaborate editor. The HELP menu from the Notepad gives full information on what it can do.

If use the Select All command from the Notepad EDIT menu then all your text should go to inverse vidoe, indicating that it has been "selected". Then EDIT-Copy grabs a copy of the selected text into a (usually invisible) place known as the clipboard.  If you now click somewhere in your CML window (its title bar should then change colour to show you that it has become active) and select EDIT-Paste the text from the notepad is fed to CML just as if you had typed it in.  This is a big extra effort if you only type things in once, but can be a big help later on since it makes it easy to use Notepad to correct the text of your program and then you cxan go Copy-Paste again to get the corrected version into CML.

To "select" something less than the whole contents of the notapad, point the cursor at the first character you want, press (and hold down) the left mouse button and move the mouse to the last character you want before releasing the button.

You can select and copy text from the CML window and paste it into the notepad one it that is useful.


Installing CML on your own computer

Doing this is only for people with enough experience to cope with the inevitable curiosities that may arise. For the Windows version of this package you should have a 386 or 486 machine with Windows 3.1 and at least 4 Mbytes of memory. You will need a few megabytes free on your hard disc.

The first thing to do is to check that you have a good and up-to-date virus control package on your computer, and that you understand how to use it. Do not assume that just because a disc is supposed to contain software related to a course that that guarantees that the disc is safe. It is your responsibility to ensure that your system is kept secure, and any time you install fresh software on it you should act with caution.

Before attempting to install CML itself you need to make sure that a package called Win32s is installed on your machine. This is a set of extensions to Windows 3.1 (or Windows fopr Workgroup 3.11) that make support of large applications much easier. The easiest check is tyhat is Win32s is installed you will probably have game called "freespace" present. If not, you need to borrow a Win32s installation disc, use the file manager to run the "setup" program on it, and follow Microsoft's instructions.

With Win32s installed, you just need copies of three files, cml.exe, cml.hlp and cml.exp, into some directory on your hard disc. Open some folder (eg APPLICATIONS). You then need to find the FILE menu from the "program manager" and use the "New" command from it.  You want a new program item, and when invited to fill in the details you can press the "browse" buttom and then find the file cml.exe that you just installed. Select that, and give it as its description something like "ML for Windows". There is no need to fill in a working directory or a shortcut key. If all goes well you should then see the CML icon in your applications directory ready for use.

If ANYTHING goes wrong with CML on anything other than one of the laboratory-supported computers you are on your own: we can not guarantee to reproduce or correct problems that arise in such cases. But a first thing to try if something unexpected happens is to verify that the same bad behaviour is seen on one of the central machines. Despite the fact that problems on students own machines will not be investigated or fixed at all fast, we would like to know what problems have been encountered so that the version issued next year can be better behaved.

ML can be compiled for and will run on a large range of machines other than DOS or Windows ones, but during the initial course that uses it the Computer Laboratory only intends to support one version of the software. Check again later on in the year if you have real enthusiasm for making a version that works on something else, and expect it to be a somewhat fiddly process.  The lab maintains versions on ML running on various of the Unix workstations that is uses.  But note again that the Windows version is the one intended for and supported for direct use in the course.


Credits

The ML execution engine here was developed at the University of Edinburgh, with major contributions from Alan Mycroft and others. Sam Nelson from Stirling made further improvements. Arthur Norman re-instated support for big-number arithmetic and is responsible for the Windows interface code. Much of this help text was written by G Procida and D R Jones.

This version of ML is provided under the terms of the attached licence from the University of Edinburgh.  A version is available for raw MSDOS and another for Microsoft Windows.  If you collect a copy of these files on floppy disc it is your responsibility to install the system on your computer, and you will need a amall amount of experience to do so:

Windows:

Ensure that "win32s" is installed on your Windows machine.  This is a Microsoft extension to regular Windows 3.1 that allows some 32-bit applications to run.  If it is installed you probably have a game called "freecell" available (which is installed as a test of win32s). If not, install win32s before doing anything else.

Put the files cml.exe, cml.exp and cml.hlp all in the same directory on your hard disc.

Create a new program group if you want.  Create a program item in this group, and make it refer to the file cml.exe.

That should be all!  Run CML by double-clicking on the ML icon. Leave it by selecting EXIT from the FILE menu.

MSDOS:

Ensure that your machine is an 80386 or 80486 or Pentium computer with at least 4 Mbytes of memory.

Copy the file cmldos.exe from the distribution disc, but call it just cml.exe on your hard disc.  Copy the file cml.exp to the same directory on your hard disc.

check the "path" statement in your "autoexec.bat" file and either ensure that you put the cml files in one of the directories listed there, or edit "autoexec.bat" to add the name of the new directory you used for cml.

If you altered autoexec.bat, re-start your computer so that the new settings come into force.

Start ML by typing "cml".  Leave it by typing control-Z.

                                A C Norman.   August 1994

There may be some sample ML programs on this disc with name thatend ".ml".  To try them under Windows select READ from the FILE menu andthen locate the file.  Type ENTER after ML has displayed a linethet starts off "use". Under DOS go

    use "filename.ml";

where "filename.ml" is the name of the file to be processed.

Laboratory for Foundations of Computer Science

----------------------------------------------

Department of Computer Science - University of Edinburgh

Standard ML Licence Agreement

-----------------------------

Return one copy of this document to LFCS Software Distribution at the

address below and keep one copy for your records.

LFCS,                                              031-667-1081 ext. 2987

Department of Computer Science,                  Telex: 727442 (UNIVED G)

University of Edinburgh,                          E-Mail:ml@uk.ac.ed.lfcs

King's Buildings,

Edinburgh, EH9 3JZ

UK

I, the licensee, agree to the conditions below in respect of the Standard ML

System supplied by the Laboratory for Foundations of Computer Science of the

University of Edinburgh.

Signed: 	____________________________   Date:________________________

Name(printed):	____________________________________________________________

Title:	        ____________________________________________________________

Organisation:	____________________________________________________________

Address:	____________________________________________________________

                ____________________________________________________________

Telephone:	__________________ Electronic Mail: ________________________

Conditions of Licence:

1. Title to and copyright of the Standard ML System remains with the Laboratory

for Foundations of Computer Science at the University of Edinburgh.

2. The ML System may be used freely within the licensee's organisation for

research and educational purposes. Commercial and revenue earning use are

excluded form this agreement. Evaluation for potential commercial use is

permitted, but licencees are advised to contact LFCS in advance of this

activity.

3. The licensee will not pass the ML System to anyone outside their

organisation unless they are already signatories to this licence in which case

the system may be copied to them under the same terms as this licence. No

charge may be levied for this distribution.

4. The licensee accepts the ML system "as is". The University of Edinburgh

makes no warranty in respect of the ML System. Nevertheless licensees are

encouraged to report to LFCS any problems with or suggestions for improvement

of the the ML System.

5. The licensee may modify the supplied ML System on condition that any

significant changes are notified to LFCS and made available to LFCS such that

they may be incorporated within future releases of the ML System and licenced

under the conditions of this licence agreement.  "Significant changes" will

include, for example, changes to the language accepted by the system or ports

to previously unsupported host computer types. Licencees are strongly advised

to consult LFCS before starting such work in order to avoid duplication and to

assess the feasibility of the work.

6. Licencees will acknowledge LFCS and The University of Edinburgh as the

designers of the ML language and implementors of this implementation in any

relevant document or publication.


CML Menus

Each of the following topics has help on the corresponding menu:

File Menu Commands

Edit Menu Commands

Break Menu Commands

Graphics Menu Command

Help Menu Commands

Many of the commands on menus have key short-cuts. For instance, the Interrupt command has the key short-cut CTRL+G (pronounced "control G"), to activate it hold done the control key and tap 'G'. All the short-cuts are shown on the menus themselves.


File Commands Menu

Read

Lets you specify a file to load into CML. It produces the appropriate use command as if you had typed it, giving you the opportunity to edit it. You will normally just need to type a carriege return (the ENTER key) to get ML to accept the file that you have selected.

Save As

Saves the entire current history buffer to a file you name.

Save Selection

Saves the text you have selected to a file you name.

File/Terminate Log

Allows you to specify a file into which any further input and output text will go. It may be useful to set up such a transcript if you will later want to look back at exactly what you did. When a log file has been opened this menu item switches to one that allows you to terminate logging. The file is also closed when you quit CML.

Exit

Quits the CML application.


Edit Menu Commands

Copy

Copies the selected text into the Clipboard, where it can be pasted back into another application (Notepad for example) or back into CML. Note that the prompt characters are not copied which makes it easier to correct code you have written. If you want an exact copy of the selection (to print out say) then you should save it to a file.

Paste

Inserts the contents of the Clipboard into CML as if you had typed them in. A convenient way to replay commands to CML.

Move

Exactly the same as a Copy followed by a Paste.

Select All

Selects all of the text in the CML history buffer. If you were thinking of making a transcript of your session, the Save As command on the File menu is probably a better bet.

Clear All

Clears the CML history buffer. Wipes out those embarrassing mistakes and starts you on a clean slate (NB: CML stills remembers all the functions you defined, only the contents of the windows are erased).

Undo

This command is not available. You probably didn't want to make any mistakes anyway.

Redraw

Redraws the contents of the CML windows, just in case anything corrupted them. If you find that you are needing to do this please report the fact since the screen OUGHT not to get scrambled!

Home

Moves the window to the top of the history buffer so that you can see what you first typed.  There is a limit to how much can be stored so in a long session this may not be able to take you all the way back to the start. Note that you can also use the scroll bars or the HOME key to do this.

End

Moves the window to the bottom of the history buffer (where the prompt is).  Note that you can also use the scroll bars or the END key to do this, and that whenever you type anything in CML tries to make the line you are typing into visible.

Font

Allows you to change the typeface and size of the fount that CML uses to display your typing and its output. Some combinations of fonts and sizes may lead to ugly or unclear display. Useful for group demonstrations, to allow for different size screens or to make the text easier to read.

Greek

Use this command to switch between the special display of type variables using greek letters and the normal display using apostrohpes. This option is on by default as long as CML has been able to find an appropriate typeface; if it hasn't then the menu item will ber greyed out. The switch only applies new output. If you install CML on a computer that does not have the TrueType symbol fonts installed as part of Windows you may need to do this to avoid rubbish characters being displayed in ML polymorphic types. If in doubt try typing in "fun i x = x;" and seeing if the result is displayed as "Fun : x -> x" with x replaced by a nice Greek "alpha" character.


Break Menu Commands

Interrupt

Use this when CML gets stuck on a lengthy calculation and you're fed up waiting. CML will stop whatever it's doing and return you to the prompt. You can also use Interrupt in the middle of giving some input but it doesn't do anything particularly useful.

Backtrace

You cannot use and don't need to worry about this! It is included on the menu as a possible future extension.


Graphics Menu Commands

Note: there is more detailed information about CML's graphics facilities here.

Show

This manually pops up CML's graphics window. Whenever you evaluate something of type picture CML pops up this window (if it isn't already present) and displays the picture. Show will also bring the window to the top when it is hidden underneath some other windows.

Hide

Makes the graphics window vanish. Use this command if you find the window is getting in your way. You can use the Show command to bring it back along with the last picture you displayed.

Clear

Clears the graphics window. Useful perhaps when the demonstrator comes see what you've been up to.


Help Menu Commands

Contents

Runs the Windows Help program starting with the CML help contents page.

Search for Help on...

Windows Help lets you search according to particular keywords. See How To Use Help for further instructions if you need any. But the fact that you are reading this suggests that you can manage at least the basics!

How to Use Help

Starts Windows Help on Windows Help help. Try this if you need help on how to use the help system. The information given under this menu item is not al all specific to CML. If there is something seriously wrong or misleading in the CML help text you might want to send some email to Arthur.Norman@cl.

About CML

Some copyright information is displayed.


  CML Reference

CML's built-in types

Defining simple values and functions

Predeclared Values and Constructors

Defining types

Exceptions and handling them

Error Messages


CML's Types

What is a type? It is simply a set of values which can be treated uniformly by CML under all circumstances. For instance the whole number 1 is of type int and so is any other whole number. Any expression that evaluates to an integer also has type int.

CML supports a variety of types as standard and in addition you can define your own types. This section catalogs the built-in types and values.

The Booleans

Unlike in BASIC or C truth values have their own type in CML. The values are true and false and they have type bool. They are returned by the relational operators (<, <=, =, <>, >= and >) are used in conditional expressions.

The function not, the operators andalso and orelse and the conditional expression if ... then ... else ... are provided.

not is boolean negation and has type bool -> bool; not true is false and vice versa.

andalso is boolean conjunction; it is not quite an ordinary infix operator but is used just like one. abc andalso def is true if both abc and def are true, otherwise it is false. CML evaluates abc first and only if it is true does it need to evaluate def.

orelse is boolean disjunction. abc orelse def is false if both abc and def are false, otherwise it is true. Again CML will only evaluate def if it has to.

Given three expressions abc, def and ghi, the form if abc then def else ghi is another expression, however, abc must have type bool and the other two expressions must be of the same type which is then the type of the overall expression. CML evaulates the expression as follows: firstly it evaluates abc, if this is true then the result is had by evaluating def, if it is false then the result is had by evaulating ghi.

Try out the following examples:

2 = 3;

true = true;

true = false;

if true then 13 else 24;

false andalso (1.0/0.0 = 18.0);

if (if 2+2=4 then true else false) then 2+2=5 else 2+3=5;

The Integers

These are your basic whole numbers, both positive and negative. Every whole number belongs to the type int. CML can handle rather large integers, just try typing in a very large number (and a semicolon), it won't faze CML. Now try:

it * it;

This gives the square of the number you just entered. * is the multiplication operator. The operators + and - perform addition and subtraction respectively. Division on the integers is done with the operator div which has a companion operator mod.

How about negative numbers? The minus sign "-" is a subtraction operator (taking two arguments) and cannot be used as a negation prefix, use "~" instead: try ~2 + 3;.

You can use all the comparison operators (<= etc) on the integers. Here is an example function which takes two integer arguments and returns another integer. See if you can work out what it does:

fun puzzle (x,y) = if x < y

       then if x = 0 then y else puzzle (x,y-x)

       else puzzle (y,x-y);

Does it work for negative arguments?

Tuples

In CML you can build composite values using parentheses and commas. So the pair (1,true) is a new value which packages 1 and true together. In general, given a of type t and b of type s the pair (a,b) has type s * t.

You can also make tuples of any size bigger than two; quintuples (and so on) are fine and have corresponding large types. There is also a special zero-tuple, (). This has type unit and is normally called unit itself.

Floating point numbers

In any programming language these are some approximation to the real numbers and CML the type of these numbers is real.

To have CML recognise a number as a real rather than an int it must have at least one of:

a decimal point in the number

a trailing exponent consisting of the letter E followed by a (possibly negated) integer.

These are valid floating point numbers: 2.3, 3E4, ~2E~6, 2.0E2.

All the relational (comparison) operators can be used on values of type real as well as the operators +, -, * and /. The negation operator is ~, the same as for integers.

These functions are also provided:

abs : real -> real - absolute value

sqrt : real -> real - square root :real -> real

sin : real -> real - sine

cos : real -> real - cosine

arctan : real -> real - inverse tangent

exp : real -> real - exponentiation (base e)

ln : real -> real - natural logarithm (base e)

floor : real -> int - floating point to integer conversion (rounding towards negative infinity)

real : int -> real - integer to floating point conversion

Strings

Strings are sequences of characters, written between double quotes. "string one", "" and "the previous string was empty" are two example values of type string.

The type string is a peculiarity of ML. Most functional languages have some type of characters and define strings simply as lists (see below) of characters. ML has no separate type for characters, though you could use ints as a substitute.

All the comparison operators can be used on strings; in addition ^ is the string concatenation (joining) operator. The function size : string -> int yields the number of characters in a string.

The function chr : int -> string converts an integer n in the range 0 to 255 into a string of length 1 consisting of the single character with character value n.

The function ord : string -> int does the reverse thing; to be precise, given a non-empty string it returns the character value of the first element of the string.

implode takes a list of strings and returns their concatenation. explode turns a string into a list of single character strings. They allow you define string processing functions in term of list processing functions.

Lists

Lists are sequences of values where all the values in a list must have the same type.


Defining simple values and functions

Declarations are phrases that effect the environment enabling values to be bound to names. A simple use is val a = 7; which binds a to the value 7, you can then type a; and ML will respond with something like 7 : int. Defining functions using fun is an example of a declaration. Declarations can be to create variables, functions, types, datatypes, and exceptions.

Some of the following declarations below are deliberately presented in a restricted form, see "Standard ML" (Harper, MacQueen, Milner) for in-depth details.

val

val <pattern> = <expression>

Used to give a value a name. Examples are

val a = "Hot Dogs";      (* gives a the string value "Hot Dogs" *)

val b::c = [1,2,3,4];    (* gives b the value 1, c the value [2,3,4] *)

Notice that patterns can be used with contructors as in the second example above.

fun

fun <name> <pat11> ... <pat1n> = exp1

  |

...

  | <name> <patm1> ... <patmn> = expm

Declares a function. Simple use is fun addone x = x+1; which defines the function addone (which has the effefct of adding one to an integer). Slightly more complex use involving pattern matching might be

fun map f nil = nil

  | map f (x::x') = f x :: map f x';

which defines the familiar map function.

type

type <name> = <type>

Declares an abbreviation for an existing type. If you had a vector manipulation package, you might want something like type vector = real*real to define a two-dimensional vector type for example.

datatype

datatype <type-variable-list> <constructor> =

<con1> of <type1> | ... | <conn> of <typen>

Datatypes are used to declare new types (or type constructors). The name of the new type is introduced on the left, and the possible constructions the type are on the right. Paulson gives the following example:

datatype person = King

                | Peer of string*string*int

                | Knight of string

                | Peasant of string;

This declares the type person, and four constructors (King, Peer, Knight, Peasant). Notice that King is a nullary type constructor, hence there is only one King. The constructors can be used to create values of type person as in Peer("Duke","Norfolk",9), creating the 9th Duke of Norfolk. They can also be used in pattern matches:

fun title King               = "His Majesty the King"

  | title (Peer(deg,terr,_)) = "The " ^ deg ^ " of " ^ terr

  | title (Knight name)      = "Sir " ^ name

  | title (Peasant name)     = name;

exception

exception name [of <type>]

Declares an exception. An exception is used in conjunction with handle and raise forms to perform non-local exit from an expression. Perhaps you should see the topic on exceptions and handling them.


Predeclared Variables and Constructors

In the following list, the type "num" stands for either int or real, "nums" stands for integer, real, or string. "ty" stands for an arbitrary type, "mty" stands for any monotype, "ety" stands for any equality type.

Nonfix Values

nil : 'a list

Type constructor for the empty list.

map : ('a -> 'b) -> 'a list -> 'b list

The map function takes a function and returns a function that applies the function to every element of a list.

rev : 'a list -> 'a list

Reverses a list.

true, false : bool

The two boolean constructors.

not : bool -> bool

The logical not operator.

~ : num -> num

Unary minus for integers and reals.

abs : num -> num

Returns the absolute value of a number.

floor : real -> int

The floor of a number is defined to be the greatest integer no bigger than it.

real : int -> real

Converts an integer into a floating point number.

sin, cos, arctan : real -> real

The mathematical functions of the same name. All three work in radians not degrees.

exp, ln : real -> real

Exponentiation and logarithms in the natural base (e).

size : string -> int

Returns the length of a string (which is the number of characters in it).

chr : int -> string

Converts an integer into a one character string represented by that number. A bit hacky really.

ord : string -> int

Takes a string and returns the integer representing the first character of that string. ord (chr n) = n.

explode : string -> string list

Takes a string and returns a list of one-character strings.

implode : string list -> string

Takes a list of one-character strings and joins them all together to form a single string. Implode and explode are inverse.

ref : mty -> mty ref

Creates a reference containing a value.

! : 'a ref -> 'a

Returns the contents of a reference.

print : ty -> ty

Prints out a value. Extremely imperative.

makestring : ty -> string

Returns the string that would be printed if you used print to print out the value.

Infix Values

Precedence 7

/ : real * real -> real

Division on real numbers.

div : int * int -> int

Integer division.

mod : int * int -> int

Returns its first argument modulo the second. The result has the same sign as the second argument.

* : num * num -> num

Multiplication on integers or reals.

Precedence 6

+ : num * num -> num

Addition; what did you expect?

- : num * num -> num

The first argument is the subtrahend, the second is the subtractor.

^ : string * string -> string

Returns the concatenation of two strings.

Precedence 5

:: : 'a * 'a list -> 'a list

The cons operator for building lists.

@ : 'a list * 'a list -> 'a list

The append operator, returns the concatenation of the two lists.

Precedence 4

= : ety * ety -> bool

The equality relation.

<> : ety * ety -> bool

Test for not-equal.

< : nums * nums -> bool

The standard ordering for numbers, and lexical comparison for strings.

> : nums * nums -> bool

a > b iff b < a.

<= : nums * nums -> bool

Less than or equal to.

>= : nums * nums -> bool

Greater than or equal to.

Precedence 3

o : ('b -> 'c) * ('a -> 'b) -> ('a -> 'c)

Performs function composition. So f o g returns the function that is the composition of f and g.

:= : mty ref * mty -> unit

Assignment.

Notes

All binary operators except cons (::) associate to the left with other operators of the same precedence. Cons (::) is right associative.


Defining types

New types can be introduced using the constructions "type", "dattype" and "abstype". This last is in many respects similar to datatype, but arranges to encapsulate the type so that most users have no access to its internal structure. It is not documented further in this help text.


Exceptions and handling them

New exceptions can be introduced using the "exception" declaration. If smash is the name of such an exception, raise smash activates it. The operator handle may be used to allow programs to trap and recover from exceptions. More details will be given in the lectures or books.


Error messages

Many of the error messages generated by CML and cryptic and unhelpful. The main resonse to seeing one that you should have is to re-read and double-check your code. The system insists that you get all types in your program utterly consistent, and that you never refer to any function or value that has not already been defined. If in doubt you can COPY your output including both what you typed and the error messages you got and PASTE it into a notepad, from where you can print a copy to take to your supervisor or a demonstrator for further assistence.


Graphics in CML

Introduction

CML has a graphics window in which it can display simple graphics. Whenever anything of type picture is evaluated at the top level in CML the corresponding picture gets drawn into the graphics window. The graphics window is a subset of the plane covering approximately from -2.0 to 2.0 in both directions. The following simple values and functions are available to create and manipulate pictures:

Note that the arguments to various of the picture drawing functions are REAL numbers and not integers. Thus an attempt to say "circle(1)" will fail, and you must say "circle(1.0)" or "circle(real 1)".

nullpic

nullpic : picture

A value reprsenting the empty picture. This can be used as the base case for defining pictures recursively; such an example is given below.

point

point : picture

A value that is the picture with a single (black) point at the origin. Note that isolated points will often not be easy to see.

line

line : real -> picture

Returns a picture that is a horizontal (black) line centred on the origin of the length you specify. So line 4.0; draws a line that cuts the graphics window in half.

circle

circle : real -> picture

Returns a picture that is a (black) circle centred on the origin with the given radius.

shift

shift : real*real*picture -> picture

Takes an amount to shift by (in the x and y directions) and a picture and returns that picture shifted by that amount. shift (1.0,0.0,line 2.0) draws a horizontal ray emerging from the origin.

rotate

rotate : real*picture -> picture

The amount to rotate by is specified in degrees by a real number, and the picture returned is a rotation of the picture that is passed as an argument. Positive rotation is clockwise. An example use is

fun vline l = rotate(90.0,line l);

which defines a function similar to line except it returns lines that are vertical in orientation.

scale

scale : real*picture -> picture

Scale takes a scale factor and a picture and returns a picture scaled by that amount. Eg scale(2.0, picture) makes a picture twice the size of the original.

scalex

scalex : real*picture -> picture

Scales a picture in the x direction only. The effect is that the picture is stretched. Combine rotations with scalex to get stretches along other directions.

add

add : picture*picture -> picture

Creates a superposition of pictures. An example of its use is

fun almost_lemniscate r =

add(shift(r,0.0,circle r),shift(~r,0.0,circle r));

paint

paint : colour*picture -> picture

Takes a picture and a colour and returns a similar picture that has been painted with the colour.

rgb

rgb : int*int*int -> colour

Converts triple of Red Green Blue values into a colour (RGB values should be from 0 to 255). Note that the range of colours that can actually be displayed will depend on the setup of your computer, but frequently only a very limited range will be usable. The predefined colour names are often more convenient to use than rgb().

Primary and Secondary colours

The primary and secondary colours are defined as identifiers and have the (hopefully obvious) names black, red, green, yellow, blue, magenta, cyan, white.

An example, drawing polygons

The following function draws polygons (including rational polygons), it is included here to show how complex pictures can be built up using the operations provided, and not necessarily of an example of good coding style.

(* polygon numer denom ll

 * numer and denom are integers and should be the numerator

 * and denominator of the rational polygon you wish to draw

 * (eg 5 1 for drawing a pentagon, 5 2 for drawing a

 * pentagram).

 * The fraction should be represented in reduced

 * form.

 * ll is a real denoting the length of a side.

 *)

fun polygon numer denom ll =

 let

  val hray = shift(ll/2.0,0.0,line ll)

  val rotatestep = (360.0 * real denom) / real numer

  fun poly 0 p = p

    | poly d p = poly (d-1) (add(shift(ll,0.0,rotate(rotatestep,p)),hray))

 in

  poly numer nullpic

 end;

Note that excessively complicated pictures may cause CML to crash, and will certainly made re-drawing the pictures tedious.


CML Glossary

In the definitions that follow an entry in the glossary is referred to in emphasised text like this.

Binding

Binding refers both to the process of associating a value with an identifier and to the association itself. Bindings are placed in environments, and are introduced using declarations. Essentially they give names to objects.

Constructor

A constructor is the function use to create instances of a data type. For instance the declaration datatype a = b of int will define b as a constructor for the new type a.Declaration

Declarations are ways of introducing identifiers in CML. Some of the declarations in ML are val which declares values, type for types, datatype for datatypes, and exception for exceptions. See the declaration topics.

Environment

The environment consists of three components, the Value Environment, the Exception Environment, and the Type Environment. Each component is an association of names to values, exceptions or types respectively. The environment is used essentially as a way of giving of name to something. declarations are used to modify the environment.

Exceptions

Exceptions are used for handling exceptional conditions. The exception declaration names an exit, and this can be invoked using raise inside a handle clause. The basic idea is that an expression can either evaluate to a value or raise an exception. The exception be caught and handled separately from other cases by a surrounding expression. See the topic on exceptions and handling them.

Identifiers

Identifiers are basically names. In ML an identifier is either alphanumeric: a sequence of letters, numbers, underscore, and prime (or quote), or symbolic: a sequence consisting of the characters ! % & $ + - / : < = > ? @ \ ~ ' ^ | *.

Prompt

The prompt is a string issued by CML and printed in the window to envourage you to type things in. There are 2 prompts in CML. The normal prompt is a dash (-), the secondary prompt is an equals sign (=). The secondary prompt is issued when it expects more input to form an expression, which happens when you forget the terminating semicolon.

Type

A type is collection of values which have similar properties and are able to be acted on similarly by certain functions. For example 7 is a member of the type int, the type int is the set of all integers.

Value

A value is andthing in ML that can either be used as an argument to a function or can be the result of a computation.  All ML values have known types.