FAQ
Basics on how to use SML within SOCS McGill
Q: How do I access SML on the lab compuers?
A: SML has been installed on the lab machines and you should be able to start the SML compiler by logging into one of these machines and then typing sml in a shell.
To run the code provided, you should first change to the directory where your sml code resides. Then you can start the sml compiler by typing sml. To compile the code provided, just type CM.make "sources.cm";
If you have started the sml compiler in a different directory than your code, you must change to correct directory. Within sml you can type the following: Posix.FileSys.chdir "dirname"; change directory to dirname Posix.FileSys.getcwd(); get the name of the current directory
Getting and Using SML/NJ
A: SML/NJ (Standard ML of New Jersey) is an implementation of the programming language SML (Standard ML). After having installed SML/NJ, you can run programs written in SML by feeding them to the SML/NJ interactive shell, which you can launch in a console (see "How do I use the SML/NJ interactive shell?").
Q: Where can I download SML/NJ?
A: At the official SML/NJ site. The specific files you have to download for the most recent version are linked to on this page, where you can also find installation instructions for Unix-like operating systems, Macs, and Windows.
Q: I'm using operating system <insert your favourite OS here>. How do I install SML/NJ?
A: Fairly comprehensive installation information for Unix-like OS's, MacOS X, and Windows is provided on the official SML/NJ site, on this page. OS-specific information is provided in the files INSTALL (for Unix-like OS's), WININSTALL (for Windows), and MACOSXINSTALL (for MacOS X).
Q: How do I use the SML/NJ interactive shell?
A: SML/NJ provides an interactive interpreter/evaluator, into which you can type any SML code. It will be immediately evaluated and the return value will be shown. Once SML/NJ is installed, the interactive shell can be started by typing sml at a terminal (or DOS box under Windows). Here is a sample run of the interactive shell:
Standard ML of New Jersey v110.59 [built: Thu Jul 27 11:22:51 2006]
- val foo = "hello";
val foo = "hello" : string
- val bar = "world";
val bar = "world" : string
- val baz = 123;
val baz = 123 : int
- foo ^ ", " ^ bar ^ "! " ^ Int.toString(baz);
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[autoloading done]
val it = "hello, world! 123" : string
- val foo = nil;
val foo = [] : 'a list
- 1::2::3::nil = [1,2,3];
val it = true : bool
- case [1, 2, 3] of nil => 0 | (h1::(h2::t)) => h2 | _ => ~1;
val it = 2 : int
(You can safely ignore the autoloading messages.) You can also write and use functions in the interactive shell:
- fun fac 0 = 1
= | fac n = n * (fac (n - 1));
val fac = fn : int -> int
- fac 5;
val it = 120 : int
- fac 0;
val it = 1 : int
Note that the prompt character - changes into a = when you are entering multiple lines. (Note that you should terminate every statement with a semicolon, ;, before pressing enter.)
To exit the interactive shell, type in your operating system's end-of-file (EOF) character (ctrl-d in Linux, ctrl-z followed by enter in Windows).
Q: Using the interactive shell in the console, how do I run SML code I've saved in a file?
A: Suppose you've written some SML code in a file, file.sml, and you want to test it or play around with it. First, start an SML/NJ interactive shell session by running sml at the command line (a terminal under Linux or a DOS box under Windows), and suppose your code is in a file file.sml in the current directory (where you launched the SML/NJ interactive shell). In the interactive shell, enter
- use "file.sml";
The quotes indicate that the argument is a string and are neccessary. This loads the contents of the file into the interactive shell, including any functions you've written, which you can then call directly from the interactive session.
Note that your code need not be in the current directory. If your file is ~/foo/bar/baz.sml and you launched the SML/NJ interactive shell from any directory, you can load the file by entering
- use "~/foo/bar/baz.sml";
You can also achieve this by starting SML/NJ with your filename as an argument:
sml file.sml
This is equivalent to starting SML/NJ, then using the use function, as above, to load in the file. Moreover, you can also use this approach to quickly feed multiple files into the SML/NJ interactive shell:
sml file1.sml file2.sml file3.sml ... fileN.sml
Here, too, the filenames can have arbitrary paths.
Q: The SML/NJ interpreter is showing # symbols instead of deeply nested expressions. How can I see the whole expression?
A: The SML interpreter only shows some fixed number of levels of a nested expression. This is called the "print depth", and is set to 5 by default. The reference Control.Print.printDepth can be set to change this:
- Control.Print.printDepth := 100;
will set the print depth to 100, for instance. Alternatively, you can set the print depth when you first launch the SML/NJ interpreter, by using the following command line switch:
sml -Cprint.depth=100
will launch the SML interactive shell and set the print depth to 100. Run
sml -H
to see a list of all such command line options (there are quite a few).
Q: What should I know about SML/NJ's error messages?
A: Like most programming languages and environments, SML/NJ provides two kinds of feedback: errors, which mean that typechecking failed (your code "didn't compile" and can't be run), and warnings, which aren't fatal, but might result in unpredictable exceptions being raised at runtime. Here's a silly example of one of the more common warnings, nonexhaustive matches:
- fun iszero(0) = true;
stdIn:1.4-1.20 Warning: match nonexhaustive
0 => ...
val iszero = fn : int -> bool
- iszero(0);
val it = true : bool
- iszero(1);
uncaught exception Match [nonexhaustive match failure]
raised at: stdIn:1.20
So iszero typechecks, but the pattern matching doesn't cover all possible cases for the argument (it only covers 0). Before submitting code, try to make sure that neither errors nor warnings are generated (or explain why you think they're generated, if you can't get rid of them -- sometimes warnings are, in fact, mostly harmless).
Getting and Using Emacs
Q: What is (1) emacs, (2) SML-mode?
A: (1) Emacs is a text editor that can do an astounding number of things. It is particularly suitable for writing SML programs because of the existence of SML-mode (see next point). (2) SML-mode is an extension to emacs that, once installed, allows emacs to enter a special mode customized for writing SML code. For instance, SML-mode will allow you to run an SML/NJ session from within emacs. Effectively, this allows you to write code in one buffer inside emacs, then immediately run it in SML/NJ in another buffer by pressing a single key combination. This saves you time, as otherwise, you would have to switch to a terminal or DOS box, launch SML/NJ separately and import your code into there (see "Using the interactive shell in the console, how do I run SML code I've saved in a file?" and "Using emacs, how do I run SML code I've saved in a file?" for more information on how to run SML code through both the SML/NJ interactive shell in the console and emacs).
Q: Can I use SML without emacs?
A: Yes, you can run the SML/NJ interactive shell perfectly well from a console terminal window (or DOS box under Windows) and run any SML code (written using your favourite editor) through it (see "Using the interactive shell in the console, how do I run SML code I've saved in a file?"). However, SML-mode under emacs provides some nifty shortcuts and, with practice, can significantly shorten the time you spend writing code. But is it not necessary to use emacs, and you will not be evaluated on anything related to it. Emacs has a steep learning curve, so it might be better to begin writing code in an editor your familiar with, and migrating later, if you like.
Q: Where can I download emacs?
A: There are two main forks of emacs, GNU Emacs and XEmacs, which can be downloaded from their respective sites. The two forks are very similar in behaviour and you can use either one. However, SML-mode was originally written for GNU Emacs, and it can be more difficult to get SML-mode working in XEmacs. Under Linux, it makes no difference which one you use, as SML-mode works well for both, but if using Windows, we would recommend GNU Emacs.
Some insight on why two forks exist is given here, while history and more background information is provided here.
Q: How do I install (1) GNU Emacs, (2) XEmacs?
A: (1) If you're running Linux, look here. For information on how to obtain and install GNU Emacs for Windows, look here. (2) XEmacs download and installation information for Unix-like OS's, MacOS, and Windows is provided here.
Q: I use Linux. (1) Where can I download SML-mode for emacs? (2) How do I install it?
A: (1) The latest version of SML-mode for emacs can be downloaded from here. (2) Unpack the SML-mode tarball using tar xvzf sml-mode.tar.gz. Move the files contained in it into some convenient directory, such as ~/emacs/sml-mode. If you use GNU Emacs, add the following lines to the file ~/.emacs, creating it if it doesn't exist:
(add-to-list 'load-path "/home/sam/emacs/sml-mode")
(load "sml-mode-startup")
where you must replace "/home/sam/emacs/sml-mode" with the name of the directory that contains the SML-mode files.
If you use XEmacs, you should add the lines above to the file ~/.xemacs/init.el, creating both the ~/.xemacs directory and the ~/.xemacs/init.el file if they don't exist.
If you restart emacs, SML-mode should now work. To test it, launch emacs (with emacs for GNU Emacs and xemacs for XEmacs) and open a file containing SML code (to open a file, use CTRL + x + f, then enter the name of the file). Press ALT + x to move the cursor to the minibuffer (the input line at the bottom of the Emacs window), type in run-sml and press enter. Emacs should ask you what the command is to launch SML (ML command: sml). Press enter to accept the default.
This should open a new buffer running the SML/NJ interactive shell. To test if the communication between the buffers works, place the cursor into the code buffer, then press CTRL + c + b. This should send the code in the buffer you are working on to the SML buffer and transfer control to the SML buffer, where you can play around with the code you've just written. See "How do I use emacs?" for more information.
Q: I use Windows. (1) Where can I download SML-mode for emacs? (2) How do I install it?
A: (1) The latest version of SML-mode for emacs can be downloaded as a zip file from here. (2) This depends on whether you want to use GNU Emacs or XEmacs. Getting SML-mode to work with XEmacs under Windows can be tricky, since SML-mode was originally written for GNU Emacs. Since we've been unable to get SML-mode to work with XEmacs in Windows, we strongly recommend using GNU Emacs or, better yet, Linux. But here's how to get SML-mode working with GNU Emacs under Windows.
First, download sml-mode.zip and unzip its contents into a temporary folder.
In the folder into which you unpacked GNU Emacs (eg, C:\Program Files\emacs-21.3) there should be a folder called site-lisp. Create a folder in site-lisp called sml-mode. Move the SML-mode files (which you have unpacked from sml-mode.zip) into this site-lisp\sml-mode folder.
Next, copy and paste the following two lines at the bottom of the file site-start.el in the site-lisp folder (if such a file does not exist, create it):
(add-to-list 'load-path "c:\\progra~1\\emacs\\site-lisp\\sml-mode")
(load "sml-mode-startup")
where you must replace c:\\progra~1\\emacs\\site-lisp\\sml-mode by the location of the site-lisp\sml-mode folder on your computer. Note that you need to use double backslashes (\\) in this path. If you restart GNU Emacs, SML-mode should now work. To test it, launch Emacs (bin\runemacs.exe in the Emacs folder) and open a file containing SML code (to open a file, use ctrl-x ctrl-f, then enter the name of the file; if you enter the name of a folder, Emacs will list the folder contents and will let you browse the folder). Press ALT + x to move the cursor to the minibuffer (the input line at the bottom of the Emacs window), type in run-sml and press enter. Emacs should ask you what the command is to launch SML (ML command: sml). Press enter to accept the default.
This should open a new buffer running the SML/NJ interactive shell. To test if the communication between the buffers works, place the cursor into the code buffer, then press CTRL + c + b. This should send the code in the buffer you are working on to the SML buffer and transfer control to the SML buffer, where you can play around with the code you've just written. See "How do I use emacs?" for more information.
A: Learning to use emacs is a lifelong endeavour, but here are a few key combinations that might come in handy. Again, though, bear in mind that you need not use emacs to use SML. See also "Using emacs, how do I run SML code I've saved in a file?".
Command |
Action |
ctrl-x ctrl-c |
exit emacs |
ctrl-x ctrl-s |
save the file |
ctrl-c ctrl-b |
send filel to sml buffer |
ctrl-x ctrl-f |
open file |
ctrl-x 2 |
split window horizontally |
ctrl-x 3 |
split window vertically |
ctrl-x 1 |
display current window only, hides split ones |
ctrl-x ctrl-o |
go to next window |
ctrl-x k |
kill current window (buffer) |
ctrl-a |
home |
ctrl-e |
end |
ctrl-k |
kill everything on the current line after the cursor |
alt-x sml |
starts an SML buffer |
alt-x shell |
starts a shell buffer |