General Usage

Starting Inlab Scheme

Inlab Scheme can be started in different ways: in interactive mode, with a file name argument, with an expression as argument, piping into stdin and in script mode.

In each mode an existing file .schemerc in the user’s home directory (detected by the standard environment variable HOME) is loaded first after initialization.

If an error occurs loading .schemerc Inlab Scheme displays the error message and exits with the return code 2 (the error handler of interactive mode is not invoked).

Starting Inlab Scheme in Interactive Mode

This is the the simple case of just typing scheme in your shell. Inlab Scheme starts and initialises, prints any initial messages and starts the Inlab Scheme top level REP (read-eval-print) loop.

For further information about the command line editing capabilities of the top level REP loop see the chapter “Command Line Editing” below.

The only thing that you may have to configure in your shell environment is to make sure that the binary of Inlab Scheme is found by your shell usually by configuring your PATH environment variable. If an error occurs in interactive mode the error handler is invoked (see below).

Example (ksh):

$ scheme
> (exit)
$

Starting Inlab Scheme with a File Name Argument

If Inlab Scheme is started with one argument supplied and this argument is regarded by (read) as a symbol this symbol (converted to a string) is treated as a file name.

Inlab Scheme is then initialized, the Inlab Scheme top level REP loop is not started and the filename is loaded using (load). If the loading succeeds by evaluating each expression found in that file and no more expressions are found therein Inlab Scheme internally executes an (exit 0) returning to the command level of the operating system (shell).

If Inlab Scheme is started in this mode no initial welcome and copyright message is displayed, if an error occurs during load an error message is printed on stderr and Inlab Scheme exits with the return code 2.

Example:

$ echo ’(writeln "hello")’ > try1.scm
$ scheme try1.scm
hello
$ echo $?
0
$

Starting Inlab Scheme with an Expression Argument

When Inlab Scheme is started with one argument supplied and this argument would be internalised to a list by (read) this one list is treated as an expression that is evaluated after initialising. No welcome and copyright message is displayed in this case.

If the evaluation of this single expression does not explicitly cause Inlab Scheme to exit internally an (exit 0) is performed after evaluating this expression. In case of an error an error message is displayed on stderr and Inlab Scheme exits with a return code of 2.

This mode may be used to use Inlab Scheme to execute smaller programs that are supplied directly via the command line interface.

Example:

$ scheme ’(writeln "hello")’
hello
$ echo $?
0
$

Piping into stdin

Inlab Scheme also accepts any input piped into stdin, any greeting message and the REP-loop prompt is suppressed when stdin is not an interactive terminal.

Example:

$ echo '(pp pp)' | scheme
(lambda (obj . opt)
  ((named-lambda
     (() port)
     (if (compound-procedure? obj)
       (set! obj
         (cons 'lambda
               (cons (procedure-parameters obj)
                     (procedure-body obj)))))
     (if (syntax-procedure? obj)
       (set! obj
         `(named-syntax-lambda
            (,(procedure-name obj)
             ,@(procedure-parameters obj))
            ,@(procedure-body obj))))
     (generic-write
       obj
       #f
       79
       (named-lambda (() s) (display s port) #t))
     'ok)
   (if (special-or-pair? opt)
     (special-car opt)
     (current-output-port))))
ok
$

Running Inlab Scheme Scripts

Putting the path of Inlab Scheme in the first line of a Scheme source preceded by #! enables the use of the program invocation in most standard shells.

Internally this is achieved by the fact that the evaluation of this first line is a valid scheme expression causing no error. Inlab Scheme allows symbols with "#!" at the beginning, the following possible locations are predefined:

/usr/bin/scheme
/bin/scheme
/sbin/scheme
/usr/sbin/scheme
/opt/bin/scheme
/usr/local/scheme
/usr/local/bin/scheme

Example (assuming the binary on /usr/local/scheme):

$ echo ’#!/usr/local/scheme’ > try2
$ echo ’(writeln "hello")’ >> try2
$ chmod +x try2
$ try2
hello
$ echo $?
0
$

Command Line Editing

Inlab Scheme provides a simple top level REP (read-eval-print) loop with basic command line and history editing capabilities.

Example:

$ scheme
> (define a 12)
a
> (define b 13)
b
>

Top Level Error Handling

Inlab Scheme in its interactive mode uses a simple error handler to display and further analyse an error. The interactive error handler displays the error message, an irritant (which caused the error in most cases) and the current content of the expr register of the virtual machine.

Some errors will allow you to continue the flow of execution. If that is the case you will be informed. Then you are in the error-handler indicated by a change of the prompt. Here you are able to enter a few commands. Just typing a EOF (usually Ctrl-D) or entering the command “r” returns you directly to the main read-eval-print loop.

The following commands may be entered in that mode:

? h this help-screen
ee  eval in error-environment
eg  eval in global-environment
ce  continue with value (evaluated
in  error-environment)
cg  continue with value (evaluated
in  global-environment)
i   continue and return ’()
d   (re-) display initial error-message
fd  display current environment-frame
fu  move one environment-frame
up  to the caller
fi  restore initial environment-frame
r   (or EOF) reset to top-level
x   exit immediately

If you are evaluating an expression using the commands “ee” or “eg” a nested “sub”-error handler is started if the entered expression is causing an error again.

Displaying the environment frames may sometimes be not very informative because of the proper tail recursive implementation of Inlab Scheme.

The current error handling of Inlab Scheme lacks of several advanced features (like a “stack trace”) and will be improved in future releases.

The following example demonstrates an error caused by an undefined variable and the use and continuation of program flow using the error handler:

> (define (test input)
(let ((aa 12))
(+ aaa input)))
test
> (test 12)
ERROR!
  message   : variable not found
  irritant  : aaa
  expression: aaa
  continue  : possible, continue with
              value as obtained from
              variable
Error (? for help) >> fd
aa=12
Error (? for help) >> cg
enter value to be returned: ’12
24
>

Interrupting Inlab Scheme

A running program may be interrupted by SIGINT (signal 2) which causes a BREAK error condition. This may be done by pressing the current intr character on your terminal (usually Ctrl-C or sometimes DEL).

See also disable-interrupt and enable-interrupt.

Quitting Inlab Scheme

Inlab Scheme exits generally by calling (exit) returning the return code 0 to the invoking shell. You may supply explicitly a return code e.g. (exit 3). If you are using the interactive mode of Inlab Scheme you may also exit by typing the EOF character of your terminal twice (usually Ctrl-D). If Inlab Scheme is called with one argument (an expression or an file name) and Inlab Scheme is not forced to exit explicitly, an implicit (exit 0) is performed at the end of evaluating the expression or at the end of loading the supplied file.

Customising Memory and Stack Usage

Inlab Scheme allocates several different memory areas when started. The allocation of memory can be controlled and customised using ordinary environment variables. The current state of Inlab Scheme can be displayed using the procedure (stat). Please see the description in the “Expressions and Procedures” chapter below.

The following table shows the variables that can be set together with the minimum and default settings:

                   Min   Default
SCHEME_PSTACKSIZE  4096  16K
SCHEME_CSTACKSIZE  4096  16K
SCHEME_HASHSIZE    4096  4096
SCHEME_HEAPSIZE    2M    4M

Inlab Scheme uses internally a two stack model. One stack is used to hold pointers to ordinary Scheme objects (that must be tracked during garbage collection), the other is used to hold the internal continuations of the interpreter. SCHEME_PSTACKSIZE refers to the stack holding Scheme objects, SCHEME_CSTACKSIZE to the continuation stack.

The hashsize SCHEME_HASHSIZE is used to determine the size of the hash table for symbols and should be (only) increased if you are running programs with a extremely large amount of symbols.

The SCHEME_HEAPSIZE determines the total size of the heap in bytes. Please note that on a 64-bit machine the default-value of 4M means actually half the number of pointers that can be hold in the heap compared to a 32-bit machine. Internally the heap is divided into two parts and is collected using a traditional stop and copy algorithm.

The values of the variables can be abbreviated using ’K’ or ’M’ as the last character of the value indicating multiplication with 1024 or 1048576 respectively.

The following shows an example dialog using a Bourne shell type environment which increases the size of the heap to 16 megabytes:

$ export SCHEME_HEAPSIZE=16M
$ scheme
...

A further customisation possibility is the use of the file .schemerc in your home directory. If this file exists and Inlab Scheme is started this file is loaded using load in every mode.

C-Style Comments

For general convenience Inlab Scheme supports C-style multiline and single line comments. C-style multiline comment have a higher precedence than both single line comments.

This small example demonstrates all available possibilities:

/* This is a multiline comment
 * ;  this is still part of the multiline comment
 * // and this as well
 */
(define a /* an inside comment */ 12) ; usual single line comment
(define string "/* this is not a comment */") // this is C-style