The Incomplete Scheme 48 Reference Manual for release 1.9

#
Chapter 2
User's guide

This chapter details Scheme 48's user interface: its command-line arguments, command processor, debugger, and so forth.

## 2.1 Command line arguments

A few command line arguments are processed by Scheme 48 as it starts up.

`scheme48` [`-i` image] [`-h` heapsize] [`-a` argument `...`]

`-i` image
  specifies a heap image file to resume. This defaults to a heap image that runs a Scheme command processor. Heap images are created by the `,dump` and `,build commands`, for which see below.

`-h` heapsize
  specifies how much space should be reserved for allocation. Heapsize is in words (where one word = 4 bytes), and covers both semispaces, only one of which is in use at any given time (except during garbage collection). Cons cells are currently 3 words, so if you want to make sure you can allocate a million cons cells, you should specify `-h 6000000` (actually somewhat more than this, to account for the initial heap image and breathing room). The default heap size is 3000000 words. The system will use a larger heap if the specified (or default) size is less than the size of the image being resumed.

`-a` argument `...`
  is only useful with images built using `,build`. The arguments are passed as a list of OS strings (see section 5.15) to the procedure specified in the `,build` command. For example:

      > ,open os-strings
      > (define (f xs)
          (write (map os-string->string xs))
          (newline)
          0)                                        ;must return an integer
      > ,build f foo.image
      > ,exit
      % scheme48vm -i foo.image -a mumble "foo x" -h 5000000
      ("mumble" "foo x" "-h" "5000000")
      %

`-I` image argument `...`
  is equivalent to `-i image -a argument `...``. On most Unix-like systems, a heap image can be made executable with the following Bourne shell commands:

      % (echo '#!/s48/install/prefix/lib/scheme48-1.9/scheme48vm -I'
         cat original.image) >new.image
      % chmod +x new.image

The usual definition of the `s48` or `scheme48` command is actually a shell script that starts up the Scheme 48 virtual machine with a `-i imagefile` specifying the development environment heap image and a `-o vm-executable` specifying the location of the virtual-machine executable (the executable is needed for loading external code on some versions of Unix; see section 8.4 for more information). The file `go` in the Scheme 48 installation source directory is an example of such a shell script.

## 2.2 Command processor

When you invoke the default heap image, a command processor starts running. The command processor acts as both a read-eval-print loop, reading expressions, evaluating them, and printing the results, and as an interactive debugger and data inspector. See Chapter 3 for a description of the command processor.

## 2.3 Editing

We recommend running Scheme 48 under GNU Emacs or XEmacs using the `cmuscheme48` command package. This is in the Scheme 48 distribution's `emacs/` subdirectory and is included in XEmacs's `scheme` package. It is a variant of the `cmuscheme` library, which comes to us courtesy of Olin Shivers, formerly of CMU. You might want to put the following in your Emacs init file (`.emacs`):

    (setq scheme-program-name "scheme48")
    (autoload 'run-scheme
              "cmuscheme48"
              "Run an inferior Scheme process."
              t)

The Emacs function `run-scheme` can then be used to start a process running the program `scheme48` in a new buffer. To make the `autoload` and `(require `...`)` forms work, you will also need to put the directory containing `cmuscheme` and related files in your emacs load-path:

    (setq load-path
      (append load-path '("scheme-48-directory/emacs")))

Further documentation can be found in the files `emacs/cmuscheme48.el` and `emacs/comint.el`.

## 2.4 Performance

If you want to generally have your code run faster than it normally would, enter `inline-values` mode before loading anything. Otherwise calls to primitives (like `+` and `cons`) and in-line procedures (like `not` and `cadr`) won't be open-coded, and programs will run more slowly.

The system doesn't start in `inline-values` mode by default because the Scheme report permits redefinitions of built-in procedures. With this mode set, such redefinitions don't work according to the report, because previously compiled calls may have in-lined the old definition, leaving no opportunity to call the new definition.

`Inline-values` mode is controlled by the `inline-values` switch. `,set inline-values` and `,unset inline-values` turn it on and off.

## 2.5 Disassembler

The `,dis` command prints out the disassembled byte codes of a procedure.

    > ,dis cons
    cons
      0 (protocol 2)
      2 (pop)
      3 (make-stored-object 2 pair)
      6 (return)
    >

The current byte codes are listed in the file `scheme/vm/interp/arch.scm`. A somewhat out-of-date description of them can be found in [5].

The command argument is optional; if unsupplied it defaults to the current focus object (`##`).

The disassembler can also be invoked on continuations and templates.

## 2.6 Module system

This section gives a brief description of modules and related entities. For detailed information, including a description of the module configuration language, see chapter 4.

A module is an isolated namespace, with visibility of bindings controlled by module descriptions written in a special configuration language. A module may be instantiated as a package, which is an environment in which code can be evaluated. Most modules are instantiated only once and so have a unique package. A structure is a subset of the bindings in a package. Only by being included in a structure can a binding be made visible in other packages. A structure has two parts, the package whose bindings are being exported and the set of names that are to be exported. This set of names is called an interface. A module then has three parts:

- a set of structures whose bindings are to be visible within the module

- the source code to be evaluated within the module

- a set of exported interfaces

Instantiating a module produces a package and a set of structures, one for each of the exported interfaces.

The following example uses `define-structure` to create a module that implements simple cells as pairs, instantiates this module, and binds the resulting structure to `cells`. The syntax `(export name `...`)` creates an interface containing name `...`. The `open` clause lists structures whose bindings are visible within the module. The `begin` clause contains source code.

    (define-structure cells (export make-cell
                                    cell-ref
                                    cell-set!)
      (open scheme)
      (begin (define (make-cell x)
               (cons 'cell x))
             (define cell-ref cdr)
             (define cell-set! set-cdr!)))

Cells could also have been implemented using the record facility described in section 5.9 and available in structure `define-record-type`.

    (define-structure cells (export make-cell
                                    cell-ref
                                    cell-set!)
      (open scheme define-record-types)
      (begin (define-record-type cell :cell
               (make-cell value)
               cell?
               (value cell-ref cell-set!))))

With either definition the resulting structure can be used in other modules by including `cells` in an `open` clause.

The command interpreter is always operating within a particular package. Initially this is a package in which only the standard Scheme bindings are visible. The bindings of other structures can be made visible by using the `,open` command described in section 3.4 below.

Note that this initial package does not include the configuration language. Module code needs to be evaluated in the configuration package, which can be done by using the `,`config command:

    > ,config (define-structure cells ...)
    > ,open cells
    > (make-cell 4)
    '(cell . 4)
    > (define c (make-cell 4))
    > (cell-ref c)
    4

## 2.7 Library

A number of useful utilities are either built in to Scheme 48 or can be loaded from an external library. These utilities are not visible in the user environment by default, but can be made available with the `open` command. For example, to use the `tables` structure, do

    > ,open tables
    >

If the utility is not already loaded, then the `,open` command will load it. Or, you can load something explicitly (without opening it) using the `load-package` command:

    > ,load-package queues
    > ,open queues

When loading a utility, the message "Note: optional optimizer not invoked" is innocuous. Feel free to ignore it.

See also the package system documentation, in chapter 4.

Not all of the the libraries available in Scheme 48 are described in this manual. All are listed in files `rts-packages.scm`, `comp-packages.scm`, `env-packages.scm`, and `more-packages.scm` in the `scheme` directory of the distribution, and the bindings they export are listed in `interfaces.scm` and `more-interfaces.scm` in the same directory.