Emacs and SML/NJ for CSE 341

Ben Wood, September 2011, adapted from instructions by Dan Grossman and Hal Perkins

For roughly the first half of 341, we will work with the Standard ML programming language, using the SML/NJ (Standard ML of New Jersey) compiler. You will need both SML/NJ and a text editor on whatever computer you use to do assignments. Any editor that can handle plain text will work, but you are strongly encouraged to use Emacs, for its SML Mode, which provides good syntax highlighting, indentation, and integration with the SML environment. Learning Emacs will probably serve you well in future CSE courses.

Both Emacs and SML/NJ are installed on all department Windows and Linux lab machines, but you will need to install them on your own machine if you want to use it for 341 assignments. You will need to set up SML Mode for Emacs whether you work on your own machine or in the lab.

This document describes how to use Emacs, SML/NJ, and SML Mode, as well as how to install and configure them properly on your own computer. These instructions should work for recent versions of Windows, Mac OS X, and Linux. If you are on a lab machine, start with the Emacs basics. If you are using a lab Windows machine, also skip SML/NJ installation.


  1. Preamble: Extra Windows tools
  2. Install Emacs
  3. Emacs basics
  4. Install SML/NJ
  5. Install SML Mode in Emacs
  6. Use the SML/NJ REPL (Read-Eval-Print Loop) in Emacs

Preamble: Extra Windows tools

This section is only for Windows users. Windows does not ship with support for some of the archive file formats (TAR, GZIP) in which Emacs and SML Mode are distributed. To be able to open these files and install their contents, download and install the free archive manager 7-Zip. The 32-bit installer should work with any Windows 7 system. Download and run this installer to install 7-Zip.

Install Emacs

Skip this if you are using a lab machine.

Personal Linux

If Emacs is not already installed, use your package manager to install it. (e.g., on Ubuntu and other Debian derivatives: sudo apt-get install emacs, on Fedora: sudo yum install emacs.)

Personal Windows

Download a ZIP archive of the most recent full version, currently Emacs 23.3. (More information and other versions of Emacs are available at the GNU Emacs website.)

Unpack the downloaded ZIP archive file (emacs-23.3-bin-i386.zip) by right-clicking it and choosing 7-Zip > Extract Here. This should give you a folder called emacs-23.3, which you can place anywhere you would like.

Once you have moved the emacs-23.3 folder to where you want it, look inside to find bin\addpm.exe (the .exe extension might not be visible in the folder window depending on how you have Windows configured). Double click on this file to run it one time and it should add a Gnu-Emacs folder to your Start menu and do some other setup operations. Open the Start menu and select Gnu-Emacs > Emacs to launch emacs.

Personal Mac OS X

Download Emacs as a Mac OS X application here. Open the disk image file (.dmg) and drag the Emacs application to your Applications folder. If you prefer another version of Emacs (e.g., the old school one on the command line or AquaMacs), feel free to use it.

Emacs basics

Driving Emacs is a little different than driving any other editor; it can take some getting used to, especially the keyboard shortcuts. Fortunately, the GUI versions of Emacs you will use on Linux, Windows, or Mac OS X all have some buttons and menus to help you adjust if that's your style. The following is a quick primer on Emacs terminology and keyboard commands.

Beyond the basics described here, the Emacs reference card (pdf) is a good reference. For more info, check out the Emacs Reference Manual or the Emacs Wiki.

[GNU Emacs: a labeled diagram]

Emacs uses many key combinations involving the Control and Meta keys. Such key combinations are denoted C-x (Control-x (lowercase)) or M-x (Meta-x). On keyboards that don't have Meta (just about all keyboards today), try Alt on PC keyboards or the or Option keys on a Mac keyboard. (Emacs might complain about "Super" if you get the wrong one. If you or Emacs gets confused about what you're trying to type, use C-g to cancel your current command and start fresh.) If none of these work, use ESC, but when trying to type "M-x", for example, type ESC then type "x". (This is only if using ESC as Meta. The other Meta "substitutes" work as usual: hold while pressing the second key.)

A sequence of key presses is written like C-a C-b M-x, which would mean do the three actions in sequence.

The most important keys in Emacs:

Cut, copy, paste:

Some other useful keys:

Getting help within Emacs: In addition to the help button on the right...

More advanced Emacs hacks (optional)

If you'e curious, try some of these once you've finished the rest of the setup instructions. They are unnecessary for any of the work we'll do, but may be convenient.

Install SML/NJ

Skip this if you are using a lab Windows machine.

Lab Linux

Run this only once. It will set up SML/NJ in your account for all physical lab Linux machines. (If you use the department's Linux VM image on your machine, SML/NJ is not preinstalled. You will need to follow the installation instructions for Personal Linux below.)

Open a terminal (Click on Activities in the upper left of the screen, then Applications and scroll to find it. Or search.) and enter the following command:


Hit enter. It should print the following self-explanatory message:

  SML/NJ is ready to go!

Close this terminal before trying any other commands.

NOTE: If you're used to using ssh to work remotely on attu, you must ssh to attu32 instead to be able to use SML/NJ. SML/NJ will not work on regular attu, but will work on attu32. If you didn't understand that, don't worry, you can ignore it!

Personal Linux

If your package manager has a package for SML/NJ, install it. Otherwise, follow the "Unix" instructions here.

Personal Windows

Download and run the smlnj.msi installer available here. This will add an item for SML of New Jersey to your Start menu and add a command sml that you can use at the command line.

Personal Mac OS X

Download the installer available here. (Unless your Mac was born before about 2006, you probably want the Intel (x86) version.) Open the disk image file (.dmg) and run the installer.

Once the installation is complete, use Emacs or another text editor to edit the file ".bash_profile" in your home folder. (In Emacs you can do this via: "C-x C-f   ~/.bash_profile".) If it does not already exist, create it. Add the following line to make sure SML is visible on the command line (if you chose a custom install location, change "/usr/local/smlnj-110.73" to whatever that location is):

  export PATH="$PATH:/usr/local/smlnj-110.73/bin"

This tells your shell (the program that you interact with in the terminal) to add the SML/NJ programs to the paths it searches for command you enter. (If you are not using the bash shell, which Mac OS X has used by default since 10.3, the syntax will be different.)

All Systems: Check your SML Installation

Open a terminal (Windows: Start > All Programs > Accessories > Command Prompt, Mac OS X: Applications/Utilities/Terminal.app), type "sml", and hit enter/return. (Or on Windows, use the Start menu item for SML/NJ if you prefer.) SML/NJ should print a short banner followed by a prompt:

  Standard ML of New Jersey v110.73 [built: Sun May 15 21:34:53 2011]

Make sure everything is working by typing a very simple SML program at the prompt:

  1 + 1;

Hit enter/return. In response, the SML interpreter should print something like this:

  val it = 2 : int

To exit the interpreter, type Control-D on Linux or Mac or Control-Z on Windows.

Install SML Mode in Emacs

Skip this if you are using a lab Linux machine, but make sure you did the setup described in the Install SML/NJ: Lab Linux section.

SML Mode is an extra extension to Emacs that is not Emacs itself or SML/NJ itself. It displays SML code nicely with syntax coloring and clean indentation, and provides a way to run SML from within Emacs. Go to http://www.iro.umontreal.ca/~monnier/elisp/ and download the latest version. Unpack it:

You should get a folder named sml-mode-4.1 (the current version). You can place this folder anywhere you like, although if you are running in the CSE labs you should put it somewhere in your user file directories (Z drive on Windows); not on the local disk of a particular machine.

To get sml mode to work with emacs, you need to create a .emacs file in your "home" directory/folder that emacs searches when it starts up. The easiest way to get this right is to use emacs itself to create the .emacs file. Run emacs and enter the command C-x C-f   ~/.emacs. Emacs expands the "~" to the path where it actually does look for its configuration file; this works correctly on Windows, OS X, and Linux.

Add the following two lines:

  (setq load-path (cons "path/to/where/you/stored/sml-mode-4.1" load-path))
  (load "sml-mode-startup")

Replace "path/to/where/you/stored" with the appropriate path. To get the path of a folder:

On Windows machines, the path can look like "Z:\\look\\here", but each backslash (\) needs to be doubled (\\) because backslash by itself is a special meta-character in emacs settings files and a pair \\ is needed to represent each backslash in the path.

If you're on Linux, depending on how you launch emacs, you might need to follow the next Mac-oriented step. You only do this if SML mode seems to work, but you can't get the SML REPL to run in emacs, and you'll need to replace the path given here with wherever your smlnj install lives.

If you're on a Mac, you'll need to tell Emacs a little more about your SML install. Add the following to the .emacs file:

  (setenv "PATH" (concat "/usr/local/smlnj-110.73/bin:" (getenv "PATH")))
  (setq exec-path (cons "/usr/local/smlnj-110.73/bin"  exec-path))

For everyone: To verify that sml mode is properly installed, exit emacs then restart it so it will read the new .emacs file. Then edit an existing or new sml file (try C-x C-f test.sml to create a new file if nothing else is handy). You should see the mode display at the bottom of the emacs window change from Fundamental (or whatever it was) to SML. If you enter a line of code like val n = 1; you should see colors highlighting the keywords and variable names. When you're editing code, whenever you hit the TAB key, emacs will try to reindent the current line appropriately.

If you're in SML Mode but your SML code does not have syntax coloring, add this line to your ~/.emacs file:

  (global-font-lock-mode t)

(There are much more elaborate installation instructions in the documentation included in the sml-mode folder, but these are aimed at system administrators who might want to install sml mode for an entire site instead of a single user. Please ignore these - what's given here is all you need.)

Use the SML/NJ REPL (Read-Eval-Print Loop) in Emacs

Alright, we're done installing! This section will show you how to run SML programs from within Emacs. It assumes you already have an SML file or can write your own SML program in a new one.

  1. Start emacs from a terminal in the directory where you have (or will have) your .sml files. (Justification: That way, when you type use "foo.sml" in the REPL, it will look for "foo.sml" in the directory you want.)

  2. Use SML-mode only for files ending in .sml. See other notes for how to modify your .emacs file appropriately. (Emacs is pretty smart about selecting what mode to use based on the file extension.)

  3. To create the *sml* buffer (which holds the REPL), type C-c C-s (and then return) in the buffer with the .sml file. (Note: This will not work in the scratch buffer that emacs starts in.)

  4. To end and restart a REPL session, type C-d (to end it) and C-c C-s (and then return) (to restart it). You must type C-d while in the *sml* buffer; you can type C-c C-s from the *sml* buffer or a buffer with a .sml file.

  5. By ending and restarting a session, the new session has an empty environment. Your earlier interactions are still in the *sml* buffer, so you can save them, cut-paste them, etc., but they have no effect on the evaluation in the restarted REPL session.

  6. Evaluation can go into an infinite loop.

  7. If you forget to end your binding with a ";" character, the REPL will print an "=" character on the next line, which is just its way of saying "you're not done -- continue your binding", so type a ";" and hit return. This is not an infinite loop (nothing is being evaluated; the REPL is waiting for you) so C-c C-c doesn't do anything.

  8. If the printed result looks "pretty good", but part of what you expected to see has been replaced by a "#" or "...", don't worry. The REPL has a limit on how many characters it prints, which is good since you might make a large value, such as a list with tens of thousands of elements. You can adjust the limit if you want.

Advice you'll wish you followed!

  1. In each REPL session, follow this pattern:

    Why: use "foo.sml" has a very simple semantics: it adds the bindings in the file to the environment in order. These may or may not shadow bindings from the last time you typed use "foo.sml", depending on how "foo.sml" changed. This confuses even expert programmers until they train themselves to follow the pattern above.

  2. If you find yourself typing the same non-trivial things over and over again in the REPL, stop wasting your time.

    Note: Do not put use "foo.sml" in test.sml and begin your session with use "foo.sml"; use "test.sml". That will evaluate the bindings in foo.sml twice, which is confusing.

  3. If you develop some emotional attachment to the transcript of your *sml* buffer, you can save it to a file just like any other buffer. But after you do, it's not an *sml* buffer anymore, so you will have to create a new *sml* buffer (see (3) above).


10/2/2011 clarified advanced emacs hacks section - BPW
9/30/2011 miscellaneous tweaks, added extra PATH setup for Mac OS X, added advanced emacs config section - BPW
9/26/2011 reorganize and add emacs/sml/repl primer -BPW
3/31/2011 add information about \\ in .emacs files. HP