Dan Grossman -- Fall 2004 These are some notes for dealing with the SML N/J REP-loop from within emacs. Your mileage may vary. 0. 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.) 1. Use SML-mode for files ending in .sml. See other notes for how to modify your .emacs file appropriately. * Use the tab key to indent your code. Style matters! 2. Open or create a .sml file. 3. 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.) 4. 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. 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 REP-loop session. 6. 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. 7. 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. 8. 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! a. 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. b. If you find yourself typing the same non-trivial things over and over again in the REP-loop, stop wasting your time. * move the repeated parts to a second file, e.g., test.sml * then (see part a), when you restart your session, begin with use "foo.sml"; use "test.sml"; * in fact, there's an even faster way! * begin test.sml with the expression use "foo.sml"; * then begin your session with use "test.sml"; 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. c. 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).