The Read-Eval-Print Loop in SML
These are some notes for dealing with the SML N/J REP-loop from within
emacs. Your mileage may vary.
- 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 REP-loop, it will look for foo.sml in the
directory you want.)
- Use SML-mode for files ending in .sml. (See
Quick & Dirty Guide to Getting Started
in CSE 341/emacs
for how to
modify your .emacs file appropriately.)
Use the tab key to indent your code. Style matters!
- Open or create a .sml file.
- To create the *sml* buffer (which holds the REP loop), type Ctrl-c
Ctrl-s (and then return) in the buffer with the .sml file. (Note:
This will not work in the *scratch* buffer that emacs starts in.)
- To end and restart a REP-loop session, type Ctrl-d (to end it) and
Ctrl-c Ctrl-s (and then return) (to restart it). You must type Ctrl-d
while in the *sml* buffer; you can type Ctrl-c Ctrl-s from the *sml*
buffer or a buffer with a .sml file.
- 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 REP-loop session.
- Evaluation can go into an infinite loop. This has likely occurred if:
- You are not getting the - - prompt back and nothing appears to be
happening.
- Or your are getting more and more GC messages
In either case, Ctrl-c Ctrl-c will interrupt evaluation and get you your
prompt back.
- If you forget to end your binding with a ; character, the REP
loop 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 REP loop is waiting for you) so Ctrl-c Ctrl-c doesn't
do anything.
- If the printed result looks "pretty good", but part of what you
expected to see has been replaced by a #, don't worry. The REP
loop 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:
- In each REP-loop session, follow this pattern:
- first type use "foo.sml";
for any sml files you want to use
- then use the REP-loop manually as long as you wish
- but do not use use to load (or reload) any more files
- when tempted to violate the previous point, end and restart your
REP-loop session
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.
- If you find yourself typing the same non-trivial things over and
over again in the REP-loop, stop wasting your time.
- 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).
Dan Grossman -- Fall 2004