Some MzScheme Interactive Stuff for console/emacs use
Sunday, October 15, 2006
Eli Barzilay today mentioned on the PLT Scheme mailing list that he has made available a number of hacks that he frequently uses interactively in the MzScheme (or MrEd) REPL. These are quite convenient for use either when running MzScheme by itself or when using it with an Emacs Scheme mode (my personal favorite is Neil Van Dyke's Quack). Here is a summary of the features it provides:
This file provides some useful facilities for interactive use of mzscheme. It is best used as a ".mzschemerc" file or "mzschemerc.ss" on Windows (evaluate `(find-system-path 'init-file)' to know where this file is on your system).I tried Eli's hacks out today and found them quite useful. As a CL SLIME user, it was nice to see the addition of the comma commands! A small thing, but I've really gotten used to having them available in a REPL.
The highlights are:
- Defines a `debug' module that provides a few useful utilities for use in code while debugging:
> (eprintf fmt arg ...) Like `printf', but uses the current error port. > (warn ...) Same as `error', but only prints the error message. > *** > (*** value) > (*** fmt args ...) This is macro that is useful for debugging: the first form prints (on stderr) the source file and line number, the second also prints a value (and returns it), and the third uses a format string. For example, to see where a problem happens in a function, you spread `***'s around, and the printout. > (define*** (name args ...) ...) Macro that defines `name' as a traced function. (The idea is that you append a `***' to functions that you want to trace.) This is a cheap hack: it kills tail-recursiveness.The `***' is supposed to be a token that stands out textually in *your* code while you're debugging it, so it is customizable: set the `MZ_DEBUGGER_TOKEN' environment variable to whatever you want -- for example, set it to `@@' and you'll get bindings for `@@' and `define@@' instead of the above.- Provides a `mzscheme*' module that can be used as a `mzscheme' drop-in replacement. Basically lets you be lazy and change `mzscheme' to `mzscheme*' instead of adding a `(require debug)'.
- The following REPL functionality is used only when there is some REPL interaction, so non-interactive use (scripts) is not affected.
- Uses the readline library if we're running in an xterm (and if it's present). (Again, triggered by repl interaction.)
- Makes a convenient syntax for requiring, hooked on using 'foo as a module spec:
(require 'foo1/foo2/bar) will require the first of (lib "bar" "foo1" "foo2") (lib "bar.ss" "foo1" "foo2") (lib "bar.scm" "foo1" "foo2") (lib "bar{,.ss,.scm}" "mzlib" "foo1" "foo2") (lib "bar{.ss,.scm}" "foo1" "foo2" "bar") when `bar' is suffixless "./foo1/foo2/bar{,.ss,.scm}"Here are a few examples for `obvious' things that it gets right:(require 'list) -> (lib "list.ss") (require 'net/sendmail) -> (lib "sendmail.ss" "net") (require 'r5rs) -> (lib "r5rs.ss" "r5rs") (require 'foo) -> (file "foo.ss") ; if the file existsThis is intended for convenient interactive use, not for programs.- Toplevel commands, in the form of ",cmd". Some of these commands read an argument that is at the end of the line (eg, ",cd foo", ",ls"), and some read an expression (eg, ",stx (...expr...)"). These commands make it convenient to perform many otherwise-tedious operations in MzScheme. Use ",h" for a list of available commands.
- Two of these commads allow you to go into and out of module namespaces. The prompt shows you which module you're currently in. For example:
> ,enter 'list (quote list)> foldl #<procedure:foldl> (quote list)> ,toplevelTo enable more debugging capabilities, uncomment the(compile-enforce-module-constants #f)line, which will avoid compiler inlining (and enable arbitrary mutation). (Better than putting it in your .mzschemerc, because it will have an effect only on REPL use.)- Previous toplevel results are accessible: `^' is the last result, `^^' is the second to last (or the second value of the last multiple-value result) etc. This is done in a way that is trying to avoid clobbering a binding that you already have for these identifiers.
Incidentally, if you use MzScheme with Emacs, you might find my page on Setting up Emacs for PLT Scheme useful. Some of the things in the related Setting up Emacs for use with PLT Scheme on Windows or Mac OS X page might be a bit out-of-date as I use CL more than Scheme these days and Mac OS X more than Windows. So, if you come across any errors or things that should be added/changed, I'd appreciate any corrections.

