Go to the first, previous, next, last section, table of contents.


The Language

This section describes features which are either present in all builds of SCM or which must be enabled when SCM is compiled.

Standards Compliance

Scm conforms to the [IEEE], IEEE Standard 1178-1990. IEEE Standard for the Scheme Programming Language. and [R4RS], Revised(4) Report on the Algorithmic Language Scheme. All the required features of these specifications are supported. Many of the optional features are supported as well.

Optionals of [R4RS] Supported by SCM

two clause if: (if <test> <consequent>)
See section `Conditionals' in Revised(4) Scheme.
let*
named let
See section `Binding constructs' in Revised(4) Scheme.
do
See section `Iteration' in Revised(4) Scheme.
All varieties of define
See section `Definitions' in Revised(4) Scheme.
list-tail
See section `Pairs and lists' in Revised(4) Scheme.
string-copy
string-fill!
See section `Strings' in Revised(4) Scheme.
make-vector of two arguments
vector-fill!
See section `Vectors' in Revised(4) Scheme.
apply of more than 2 arguments
See section `Control features' in Revised(4) Scheme.
- and / of more than 2 arguments
exp
log
sin
cos
tan
asin
acos
atan
sqrt
expt
make-rectangular
make-polar
real-part
imag-part
magnitude
angle
exact->inexact
inexact->exact
See section `Numerical operations' in Revised(4) Scheme.
delay
force
See section `Control features' in Revised(4) Scheme.
with-input-from-file
with-output-to-file
See section `Ports' in Revised(4) Scheme.
char-ready?
See section `Input' in Revised(4) Scheme.
transcript-on
transcript-off
See section `System interface' in Revised(4) Scheme.

Optionals of [R4RS] not Supported by SCM

numerator
denominator
rationalize
See section `Numerical operations' in Revised(4) Scheme.
[R4RS] appendix Macros
See section `Macros' in Revised(4) Scheme.

[SLIB] Features of SCM and SCMLIT

delay
full-continuation
ieee-p1178
object-hash
rev4-report
source
See SLIB file `Template.scm'.
current-time
See section `Time' in SLIB.
defmacro
See section `Defmacro' in SLIB.
dynamic-wind
See section `Dynamic-Wind' in SLIB.
eval
See section `System' in SLIB.
getenv
system
See section `System Interface' in SLIB.
hash
See section `Hashing' in SLIB.
logical
See section `Bit-Twiddling' in SLIB.
multiarg-apply
See section `Multi-argument Apply' in SLIB.
multiarg/and-
See section `Multi-argument / and -' in SLIB.
rev4-optional-procedures
See section `Rev4 Optional Procedures' in SLIB.
string-port
See section `String Ports' in SLIB.
tmpnam
See section `Input/Output' in SLIB.
transcript
See section `Transcripts' in SLIB.
vicinity
See section `Vicinity' in SLIB.
with-file
See section `With-File' in SLIB.

[SLIB] Features of SCM

array
See section `Arrays' in SLIB.
array-for-each
See section `Array Mapping' in SLIB.
bignum
complex
inexact
rational
real
See section `Require' in SLIB.

System Interface

For documentation of the procedures getenv and system See section `System Interface' in SLIB.

Function: quit
Function: quit n
Function: exit
Function: exit n
Aliases for exit (see section `System' in SLIB). On many systems, SCM can also tail-call another program. See section I/O-Extensions.

Function: vms-debug
If SCM is compiled under VMS these commands will invoke the editor or debugger respectively.

Function: ed filename
If SCM is compiled under VMS ed will invoke the editor with a single the single argument filename.

Function: ed arg1 ...
Otherwise, the value of the environment variable EDITOR (or just ed if it isn't defined) is invoked as a command with arguments arg1 ....

Function: program-arguments
Returns a list of strings of the arguments scm was called with.

Function: errno
Function: errno n
With no argument returns the current value of the system variable errno. When given an argument, errno sets the system variable errno to n and returns the previous value of errno. (errno 0) will clear outstanding errors. This is recommended after try-load returns #f since this occurs when the file could not be opened.

Function: perror string
Prints on standard error output the argument string, a colon, followed by a space, the error message corresponding to the current value of errno and a newline. The value returned is unspecified.

Errors

A computer-language implementation designer faces choices of how reflexive to make the implementation in handling exceptions and errors; that is, how much of the error and exception routines should be written in the language itself. The design of a portable implementation is further constrained by the need to have (almost) all errors print meaningful messages, even when the implementation itself is not functioning correctly. Therefore, SCM implements much of its error response code in C.

The following common error and conditions are handled by C code. Those with callback names after them can also be handled by Scheme code (see section Interrupts). If the callback identifier is not defined at top level, the default error handler (C code) is invoked. There are many other error messages which are not treated specially.

  1. Wrong type in arg 0
  2. Wrong type in arg 1
  3. Wrong type in arg 2
  4. Wrong type in arg 3
  5. Wrong type in arg 4
  6. Wrong type in arg 5
  7. Wrong number of args
  8. numerical overflow
  9. Argument out of range
  10. Could not allocate (out-of-storage)
  11. EXIT (end-of-program)
  12. hang up (hang-up)
  13. user interrupt (user-interrupt)
  14. arithmetic error (arithmetic-error)
  15. bus error
  16. segment violation
  17. alarm (alarm-interrupt)

Variable: errobj
If SCM encounters a non-fatal error it aborts evaluation of the current form, prints a message explaining the error, and resumes the top level read-eval-print loop. The value of errobj is the offending object if appropriate. The builtin procedure error does not set errobj.

Function: error arg1 arg2 arg3 ...
Alias for section `System' in SLIB. Outputs an error message containing the arguments, aborts evaluation of the current form and resumes the top level read-eval-print loop. Error is defined in `Init.scm'; Feel free to redefine it to suit your purposes.

CAUTIOUS enhancements

If SCM is built with the `CAUTIOUS' flag, then when an error occurs, a stack trace of certain pending calls are printed as part of the default error response. A (memoized) expression and newline are printed for each partially evaluated combination whose procedure is not builtin. See section Memoized Expressions for how to read memoized expressions.

Also as the result of the `CAUTIOUS' flag, both error and user-interrupt (invoked by C-c) are defined to print stack traces and conclude by calling breakpoint (see section `Breakpoints' in SLIB). This allows the user to interract with SCM as with Lisp systems.

Function: stack-trace
Prints information describing the stack of partially evaluated expressions. stack-trace returns #t if any lines were printed and #f otherwise. See `Init.scm' for an example of the use of stack-trace.

Memoized Expressions

SCM memoizes the address of each occurence of an identifier's value when first encountering it in a source expression. Subsequent executions of that memoized expression is faster because the memoized reference encodes where in the top-level or local environment its value is.

When procedures are displayed, the memoized locations appear in a format different from references which have not yet been executed. I find this a convenient aid to locating bugs and untested expressions.

For instance, open-input-file is defined as follows in `Init.scm':

(define (open-input-file str)
  (or (open-file str OPEN_READ)
      (and (procedure? could-not-open) (could-not-open) #f)
      (error "OPEN-INPUT-FILE couldn't open file " str)))

If open-input-file has not yet been used, the displayed procedure is similar to the original definition (lines wrapped for readability):

open-input-file =>
#<CLOSURE (str) (or (open-file str open_read)
 (and (procedure? could-not-open) (could-not-open) #f)
 (error "OPEN-INPUT-FILE couldn't open file " str))>

If we open a file using open-input-file, the sections of code used become memoized:

(open-input-file "r4rstest.scm") => #<input-port 3>
open-input-file =>
#<CLOSURE (str) (#@or (#@open-file #@0+0 #@open_read)
 (and (procedure? could-not-open) (could-not-open) #f)
 (error "OPEN-INPUT-FILE couldn't open file " str))>

If we cause open-input-file to execute other sections of code, they too become memoized:

(open-input-file "foo.scm") =>

ERROR: No such file or directory
ERROR: OPEN-INPUT-FILE couldn't open file  "foo.scm"

open-input-file =>
#<CLOSURE (str) (#@or (#@open-file #@0+0 #@open_read)
 (#@and (#@procedure? #@could-not-open) (could-not-open) #f)
 (#@error "OPEN-INPUT-FILE couldn't open file " #@0+0))>

Internal State

Variable: *interactive*
The variable *interactive* determines whether the SCM session is interactive, or should quit after the command line is processed. *interactive* is controlled directly by the command-line options `-b', `-i', and `-s' (see section Invoking SCM). If none of these options are specified, the rules to determine interactivity are more complicated; see `Init.scm' for details.

Function: abort
Resumes the top level Read-Eval-Print loop.

Function: restart
Restarts the SCM program with the same arguments as it was originally invoked. All `-l' loaded files are loaded again; If those files have changed, those changes will be reflected in the new session.

Note: When running a saved executable (see section Dump), restart is redefined to be exec-self.

Function: exec-self
Exits and immediately re-invokes the same executable with the same arguments. If the executable file has been changed or replaced since the beginning of the current session, the new executable will be invoked. This differentiates exec-self from restart.

Function: verbose n
Controls how much monitoring information is printed. If n is:

0
no prompt or information is printed.
>= 1
a prompt is printed.
>= 2
the CPU time is printed after each top level form evaluated.
>= 3
messages about heap growth are printed.
>= 4
garbage collection (see section Garbage Collection) messages are printed.
>= 5
a warning will be printed for each top-level symbol which is defined more than one time.

Function: gc
Scans all of SCM objects and reclaims for further use those that are no longer accessible.

Function: room
Function: room #t
Prints out statistics about SCM's current use of storage. (room #t) also gives the hexadecimal heap segment and stack bounds.

Constant: *scm-version*
Contains the version string (e.g. `5a0') of SCM.

For other configuration constants and procedures See section `Configuration' in SLIB.

Miscellaneous Procedures

Function: try-load filename
If the string filename names an existing file, the try-load procedure reads Scheme source code expressions and definitions from the file and evaluates them sequentially and returns #t. If not, try-load returns #f. The try-load procedure does not affect the values returned by current-input-port and current-output-port.

Variable: *load-pathname*
Is set to the pathname given as argument to load, try-load, and dyn:link (see section Compiling And Linking). *load-pathname* is used to compute the value of section `Vicinity' in SLIB.

Function: line-number
Returns the current line number of the file currently being loaded.

Function: eval obj
Alias for section `System' in SLIB.

Function: eval-string str
Returns the result of reading an expression from str and evaluating it. eval-string does not change *load-pathname* or line-number.

Function: load-string str
Reads and evaluates all the expressions from str. As with load, the value returned is unspecified. eval-string does not change *load-pathname* or line-number.

Function: vector-set-length! object length
Change the length of string, vector, bit-vector, or uniform-array object to length. If this shortens object then the remaining contents are lost. If it enlarges object then the contents of the extended part are undefined but the original part is unchanged. It is an error to change the length of literal datums. The new object is returned.

Function: copy-tree obj
See section `Tree Operations' in SLIB. This extends the SLIB version by also copying vectors.

Function: acons obj1 obj2 obj3
Returns (cons (cons obj1 obj2) obj3). The expression (set! a-list (acons key datum a-list)) adds a new association to a-list.

Function: terms
This command displays the GNU General Public License.

Function: list-file filename
Displays the text contents of filename.

Procedure: print arg1 ...
Print writes all its arguments, separated by spaces. Print outputs a newline at the end and returns the value of the last argument.

Time

Constant: internal-time-units-per-second

Is the integer number of internal time units in a second.

Function: get-internal-run-time
Returns the integer run time in internal time units from an unspecified starting time. The difference of two calls to get-internal-run-time divided by internal-time-units-per-second will give elapsed run time in seconds.

Function: get-internal-real-time
Returns the integer time in internal time units from an unspecified starting time. The difference of two calls to get-internal-real-time divided by interal-time-units-per-second will give elapsed real time in seconds.

Function: current-time
Returns the time since 00:00:00 GMT, January 1, 1970, measured in seconds. See section `Time' in SLIB. current-time is used in section `Time' in SLIB.

Interrupts

Function: ticks n
Returns the number of ticks remaining till the next tick interrupt. Ticks are an arbitrary unit of evaluation. Ticks can vary greatly in the amount of time they represent.

If n is 0, any ticks request is canceled. Otherwise a ticks-interrupt will be signaled n from the current time. ticks is supported if SCM is compiled with the ticks flag defined.

Callback procedure: ticks-interrupt ...
Establishes a response for tick interrupts. Another tick interrupt will not occur unless ticks is called again. Program execution will resume if the handler returns. This procedure should (abort) or some other action which does not return if it does not want processing to continue.

Function: alarm secs
Returns the number of seconds remaining till the next alarm interrupt. If secs is 0, any alarm request is canceled. Otherwise an alarm-interrupt will be signaled secs from the current time. ALARM is not supported on all systems.

Callback procedure: user-interrupt ...
Callback procedure: alarm-interrupt ...
Establishes a response for SIGINT (control-C interrupt) and SIGALRM interrupts. Program execution will resume if the handler returns. This procedure should (abort) or some other action which does not return if it does not want processing to continue after it returns.

Interrupt handlers are disabled during execution system and ed procedures.

To unestablish a response for an interrupt set the handler symbol to #f. For instance, (set! user-interrupt #f).

Callback procedure: out-of-storage ...
Callback procedure: could-not-open ...
Callback procedure: end-of-program ...
Callback procedure: hang-up ...
Callback procedure: arithmetic-error ...
Establishes a response for storage allocation error, file opening error, end of program, SIGHUP (hang up interrupt) and arithmetic errors respectively. This procedure should (abort) or some other action which does not return if it does not want the default error message to also be displayed. If no procedure is defined for hang-up then end-of-program (if defined) will be called.

To unestablish a response for an error set the handler symbol to #f. For instance, (set! could-not-open #f).

Process Synchronization

Function: make-arbiter name

Returns an object of type arbiter and name name. Its state is initially unlocked.

Function: try-arbiter arbiter

Returns #t and locks arbiter if arbiter was unlocked. Otherwise, returns #f.

Function: release-arbiter arbiter

Returns #t and unlocks arbiter if arbiter was locked. Otherwise, returns #f.

Files and Ports

These procedures generalize and extend the standard capabilities in section `Ports' in Revised(4) Scheme.

Function: open-file string modes
Returns a port capable of receiving or delivering characters as specified by the modes string. If a file cannot be opened #f is returned.

Constant: open_read
Constant: open_write
Constant: open_both
Contain modes strings specifying that a file is to be opened for reading, writing, and both reading and writing respectively.

Function: _ionbf modestr
Returns a version of modestr which when open-file is called with it as the second argument will return an unbuffered port. A non-file input-port must be unbuffered in order for char-ready? to work correctly on it. The initial value of (current-input-port) is unbuffered if the platform supports it.

Function: close-port port
Closes port. The same as close-input-port and close-output-port.

Function: open-io-file filename
Function: close-io-port port
These functions are analogous to the standard scheme file functions. The ports are open to filename in read/write mode. Both input and output functions can be used with io-ports. An end of file must be read or a file-set-position done on the port between a read operation and a write operation or vice-versa.

Function: current-error-port
Returns the current port to which diagnostic output is directed.

Function: with-error-to-file string thunk
thunk must be a procedure of no arguments, and string must be a string naming a file. The file is opened for output, an output port connected to it is made the default value returned by current-error-port, and the thunk is called with no arguments. When the thunk returns, the port is closed and the previous default is restored. With-error-to-file returns the value yielded by thunk.

Function: with-input-from-port port thunk
Function: with-output-to-port port thunk
Function: with-error-to-port port thunk
These routines differ from with-input-from-file, with-output-to-file, and with-error-to-file in that the first argument is a port, rather than a string naming a file.

procedure: char-ready?
procedure: char-ready? port

Returns #t if a character is ready on the input port and returns #f otherwise. If char-ready? returns #t then the next read-char operation on the given port is guaranteed not to hang. If the port is at end of file then char-ready? returns #t. Port may be omitted, in which case it defaults to the value returned by current-input-port.

Rationale: Char-ready? exists to make it possible for a program to accept characters from interactive ports without getting stuck waiting for input. Any input editors associated with such ports must ensure that characters whose existence has been asserted by char-ready? cannot be rubbed out. If char-ready? were to return #f at end of file, a port at end of file would be indistinguishable from an interactive port that has no ready characters.

Soft Ports

A soft-port is a port based on a vector of procedures capable of accepting or delivering characters. It allows emulation of I/O ports.

Function: make-soft-port vector modes
Returns a port capable of receiving or delivering characters as specified by the modes string (see section Files and Ports). vector must be a vector of length 6. Its components are as follows:

  1. procedure accepting one character for output
  2. procedure accepting a string for output
  3. thunk for flushing output
  4. thunk for getting one character
  5. thunk for closing port (not by garbage collection)

For an output-only port only elements 0, 1, 2, and 4 need be procedures. For an input-only port only elements 3 and 4 need be procedures. Thunks 2 and 4 can instead be #f if there is no useful operation for them to perform.

If thunk 3 returns #f or an eof-object (see section `Input' in Revised(4) Scheme) it indicates that the port has reached end-of-file. For example:

(define stdout (current-output-port))
(define p (make-soft-port
           (vector
            (lambda (c) (write c stdout))
            (lambda (s) (display s stdout))
            (lambda () (display "." stdout))
            (lambda () (char-upcase (read-char)))
            (lambda () (display "@" stdout)))
           "rw"))

(write p p) => #<input-output-soft#\space45d10#\>

Syntax Extensions

Read syntax: #. expression
Is read as the object resulting from the evaluation of expression. This substitution occurs even inside quoted structure.

In order to allow compiled code to work with #. it is good practice to define those symbols used inside of expression with #.(define ...). For example:

#.(define foo 9)                        => #<unspecified>
'(#.foo #.(+ foo foo))                  => (9 18)

Read syntax: #+ feature form
If feature is provided? (by *features*) then form is read as a scheme expression. If not, then form is treated as whitespace.

Feature is a boolean expression composed of symbols and and, or, and not of boolean expressions.

For more information on provided? and *features*, See section `Require' in SLIB.

Read syntax: #- feature form
is equivalent to #+(not feature) expression.

Read syntax: #' form
is equivalent to form (for compatibility with common-lisp).

Read syntax: #| any thing |#
Is a balanced comment. Everything up to the matching |# is ignored by the read. Nested #|...|# can occur inside any thing.

Read syntax: #! any thing
On the first line of a file will be ignored when loaded by SCM. This makes SCM files usable as POSIX shell scripts if the first line is:

#!/usr/local/bin/scm

When such a file is invoked it executes /usr/local/bin/scm with the name of this file as the first argument. The following shell script will print factorial of its argument:

#!/usr/local/bin/scm
;;; -*-scheme-*- tells emacs this is a scheme file.
(define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n)))))
(display (fact (string->number (caddr (program-arguments)))))
(newline)
(quit)

This technique has some drawbacks:

The following approach solves both problems -- at the expense of slightly slower startup. type; should appear on every line to be executed by the shell. These lines do not have the length restriction mentioned above. Also, /bin/sh searches the directories listed in the `PATH' environment variable for `scm', eliminating the need to know absolute locations in order to invoke a program.

#!/bin/sh
type;exec scm $0 $*
;;; -*-scheme-*- tells emacs this is a scheme file.
(define (fact n) (if (< n 2) 1 (* n (fact (+ -1 n)))))
(display (fact (string->number (caddr (program-arguments)))))
(newline)
(quit)

Special Form: defined? symbol
Equivalent to #t if symbol is a syntactic keyword (such as if) or a symbol with a value in the top level environment (see section `Variables and regions' in Revised(4) Scheme). Otherwise equivalent to #f.

Special Form: defvar identifier initial-value
If identifier is unbound in the top level environment, then identifier is defined to the result of evaluating the form initial-value as if the defvar form were instead the form (define identifier initial-value) . If identifier already has a value, then initial-value is not evaluated and identifier's value is not changed.

SCM also supports the following constructs from Common Lisp: defmacro, macroexpand, macroexpand-1, and gentemp. See section `Defmacro' in SLIB.

Low Level Syntactic Hooks

Callback procedure: read:sharp c port
If a # followed by a character (for a non-standard syntax) is encountered by read, read will call the value of the symbol read:sharp with arguments the character and the port being read from. The value returned by this function will be the value of read for this expression unless the function returns #<unspecified> in which case the expression will be treated as whitespace. #<unspecified> is the value returned by the expression (if #f #f).

Note: When adding new # syntaxes, have your code save the previous value of read:sharp when defining it. Call this saved value if an invocation's syntax is not recognized. This will allow #+, #-, #!, and section Uniform Arrays to still be supported (as they use read:sharp).

Function: procedure->syntax proc
Returns a macro which, when a symbol defined to this value appears as the first symbol in an expression, returns the result of applying proc to the expression and the environment.

Function: procedure->macro proc
Function: procedure->memoizing-macro proc
Returns a macro which, when a symbol defined to this value appears as the first symbol in an expression, evaluates the result of applying proc to the expression and the environment. The value returned from proc which has been passed to PROCEDURE->MEMOIZING-MACRO replaces the form passed to proc. For example:

(define trace
  (procedure->macro
   (lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))

(trace foo) == (set! foo (tracef foo 'foo)).

An environment is a list of environment frames. There are 2 types of environment frames:

((lambda (variable1 ...) ...) value1 ...)
(let ((variable1 value1) (variable2 value2) ...) ...)
(letrec ((variable1 value1) ...) ...)
result in a single enviroment frame:
((variable1 ...) value1 ...)
(let ((variable1 value1)) ...)
(let* ((variable1 value1) ...) ...)
result in an environment frame for each variable:
(variable1 . value1) (variable2 .  value2) ...

Special Form: @apply procedure argument-list
Returns the result of applying procedure to argument-list. (apply procedure argument-list) will produce the same result.

Special Form: @call-with-current-continuation procedure)
Returns the result of applying procedure to the current continuation. A continuation is a SCM object of type contin (see section Continuations). The procedure (call-with-current-continuation procedure) is defined to have the same effect as (@call-with-current-continuation procedure).

The following procedures and special forms are used to implement hygienic and referentially transparent macros. "Macro transformer" means a procedure passed as the first argument to procedure->syntax, procedure->macro, or procedure->memoizing-macro.

Function: rename-identifier parent env
Returns a unique synthetic identifier, which may be inserted in expanded code by a macro transformer instead of a symbol. parent must be a symbol or a synthetic identifier. env must be a lexical environment passed to a macro transformer at macro expansion time, or #f, which is equivalent to a null lexical environment. The resulting macro must be bound either by a top level define, or by the special forms @let-syntax or @letrec-syntax. These last two forms are used to implement let-syntax and letrec-syntax. For almost all purposes the higher level forms define-syntax, let-syntax, and letrec-syntax See section `Macros' in Revised(4) Scheme. are to be preferred.

If a synthetic identifier is inserted bound, then no symbol, and no synthetic identifier not having the bound identifier as parent, may have the same denotation, and so may not be captured. If a synthetic identifier is inserted free, then it will denote the same object that parent did in env. It is an error to insert a synthetic identifier outside the lexical scope of the env used for its creation.

Special Form: syntax-quote obj
Synthetic identifiers are converted to their parent symbols by quote and quasiquote so that literal data in macro definitions will be properly transcribed. syntax-quote behaves like quote, but preserves synthetic identifier intact.

Function: identifier? obj
Returns #t if obj is a symbol or a synthetic identifier, and #f otherwise.

Function: identifier-equal? id1 id2 env
Returns #t if identifiers id1 and id2 would denote the same binding in lexical environment env, and #f otherwise.

Special Form: @let-syntax
Special Form: @letrec-syntax
Behave as let and letrec, but may also put extra information in the lexical environment so that rename-identifier will work properly during expansion of the macros bound by these forms.

Special Form: the-macro mac
mac may be a syntactic keyword (macro name) or an expression evaluating to a macro, otherwise an error is signaled. mac is evaluated and returned once only, after which the same memoizied value is returned.


Go to the first, previous, next, last section, table of contents.