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.
(if <test> <consequent>)
make-vectorof two arguments
applyof more than 2 arguments
/of more than 2 arguments
#t. If not, try-load returns
#f. The try-load procedure does not affect the values returned by
dyn:link(see section Compiling And Linking).
*load-pathname*is used to compute the value of section `Vicinity' in SLIB.
eval-stringdoes not change
load, the value returned is unspecified.
eval-stringdoes not change
@copy-treeif you depend on this feature;
copy-treecould get redefined.
newlineat the end and returns the value of the last argument.
Is the integer number of internal time units in a second.
internal-time-units-per-secondwill give elapsed run time in seconds.
interal-time-units-per-secondwill give elapsed real time in seconds.
current-timeis used in section `Time' in SLIB.
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
ticksis 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.
alarm-interruptwill be signaled secs from the current time. ALARM is not supported on all systems.
milli-alarmis similar to
alarm, except that the first argument millisecs, and the return value are measured in milliseconds rather than seconds. If the optional argument interval is supplied then alarm interrupts will be scheduled every interval milliseconds until turned off by a call to
profile-alarm are similar.
virtual-alarm decrements process execution time rather than real
time, and causes
SIGVTALRM to be signaled.
profile-alarm decrements both process execution time and
system execution time on behalf of the process, and causes
SIGPROF to be signaled.
supported only on systems providing the
setitimer system call.
SIGINT(control-C interrupt) and
SIGPROFinterrupts. 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
To unestablish a response for an interrupt set the handler symbol to
#f. For instance,
(set! user-interrupt #f).
To unestablish a response for an error set the handler symbol to
#f. For instance,
(set! could-not-open #f).
Returns an object of type arbiter and name name. Its state is initially unlocked.
#t and locks arbiter if arbiter was unlocked.
#t and unlocks arbiter if arbiter was locked.
These procedures generalize and extend the standard capabilities in section `Ports' in Revised(4) Scheme.
Internal functions opening files callback to the SCM function
open-file. You can extend
open-file by redefining it.
try-open-file is the primitive procedure; Do not redefine
#t if a character is ready on the input port and
#f otherwise. If
read-char operation on the given port is
not to hang. If the port is at end of file then
Port may be omitted, in which case it defaults to
the value returned by
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
cannot be rubbed out. If
char-ready? were to return
end of file, a port at end of file would be indistinguishable from an
interactive port that has no ready characters.
#tif port is input or output to a serial non-file device.
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.
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#\>
If the body of a
lambda (or the definition of a procedure) has
more than one expression, and the first expression (preceeding any
internal definitions) is a string, then that string is the
documentation string of that procedure.
(procedure-documentation (lambda (x) "Identity" x)) => "Identity" (define (square x) "Return the square of X." (* x x)) => #<unspecified> (procedure-documentation square) => "Return the square of X."
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)
*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
not of boolean expressions.
For more information on
See section `Require' in SLIB.
#+(not feature) expression.
|#is ignored by the
#|...|#can occur inside any thing.
A similar read syntax #! (exclamation rather than vertical bar) is supported for Posix shell-scripts (see section Shell Scripts).
#.(integer->char (string->number token 8)).
If token is
^ followed by a
character, then this syntax is read as a control character. If
m- followed by a character, then a
meta character is read.
m- prefixes may be
#tif 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
defined to the result of evaluating the form initial-value as if the
defvarform 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.
defconstis valid only when used at top-level.
defined to the result of evaluating the form value as if the
defconstform were instead the form
(define identifier value). If identifier already has a value, then value is not evaluated, identifier's value is not changed, and an error is signaled.
defconstis valid only when used at top-level.
casevis an extension of standard Scheme
case: Each clause of a
casevstatement must have as first element a list containing elements which are:
casev statement is equivalent to a
case statement in
which these symbolic constants preceded by commas have been replaced by
the values of the constants, and all symbolic constants preceded by
comma-at-signs have been replaced by the elements of the list values of
the constants. This use of comma, (or, equivalently,
similar to that of
quasiquote except that the unquoted
expressions must be symbolic constants.
Symbolic constants are defined using
defconst, their values are
substituted in the head of each
casev clause during macro
defconst constants should be defined before use.
casev can be substituted for any correct use of
(defconst unit '1) (defconst semivowels '(w y)) (casev (* 2 3) ((2 3 5 7) 'prime) ((,unit 4 6 8 9) 'composite)) ==> composite (casev (car '(c d)) ((a) 'a) ((b) 'b)) ==> unspecified (casev (car '(c d)) ((a e i o u) 'vowel) ((,@semivowels) 'semivowel) (else 'consonant)) ==> consonant
SCM also supports the following constructs from Common Lisp:
gentemp. See section `Defmacro' in SLIB.
readwill call the value of the symbol
read:sharpwith arguments the character and the port being read from. The value returned by this function will be the value of
readfor 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).
readwill call the value of the symbol
read:sharp-charwith the token (a string of length at least two) as argument. If the value returned is a character, then that will be the value of
readfor this expression, otherwise an error will be signaled.
Note: When adding new # syntaxes, have your code save the
previous value of
defining it. Call this saved value if an invocation's syntax is not
recognized. This will allow
section Uniform Arrays to still be supported (as they use
PROCEDURE->MEMOIZING-MACROreplaces 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)).
environment->treereturns a representation of the environment env as a list of environment frames. There are 2 types of environment frames:
((lambda (variable1 ...) ...) value1 ...)
(let ((variable1 value1) (variable2 value2) ...) ...)
(letrec ((variable1 value1) ...) ...)
((variable1 ...) value1 ...)
(let ((variable1 value1)) ...)
(let* ((variable1 value1) ...) ...)
(variable1 . value1) (variable2 . value2) ...
applywhen the identifiers bound by the closure being applied are
set!; setting affects argument-list.
(define lst (list 'a 'b 'c)) (@apply (lambda (v1 v2 v3) (set! v1 (cons v2 v3))) lst) lst => ((b . c) b c)
Thus a mutable environment can be treated as both a list and local bindings.
contin(see section Continuations). The procedure
(call-with-current-continuation procedure)is defined to have the same effect as
SCM provides a synthetic identifier type for efficient implementation of
hygienic macros (for example,
syntax-rules see section `Macros' in Revised(4) Scheme) A synthetic identifier may be inserted in
Scheme code by a macro expander in any context where a symbol would
normally be used. Collectively, symbols and synthetic identifiers are
#tif obj is a symbol or a synthetic identifier, and
If it is necessary to distinguish between symbols and synthetic identifiers,
use the predicate
A synthetic identifier includes two data: a parent, which is an
identifier, and an environment, which is either
#f or a lexical
environment which has been passed to a macro expander
(a procedure passed as an argument to
#for a lexical environment passed to a macro expander.
renamed-identifierreturns a distinct object for each call, even if passed identical arguments.
There is no direct way to access the data internal to a synthetic identifier, those data are used during variable lookup. If a synthetic identifier is inserted as quoted data then during macro expansion it will be repeatedly replaced by its parent, until a symbol is obtained.
renamed-identifier may be used as a replacement for
(define gentemp (let ((name (string->symbol "An unlikely variable"))) (lambda () (renamed-identifier name #f))))
If an identifier returned by this version of
gentemp is inserted
in a binding position as the name of a variable then it is guaranteed
that no other identifier may denote that variable. If an identifier
gentemp is inserted free, then it will denote the
top-level value bound to its parent, the symbol named "An unlikely
variable". This behavior, of course, is meant to be put to good use:
(define top-level-foo (procedure->memoizing-macro (lambda (exp env) (renamed-identifier 'foo #f))))
Defines a macro which may always be used to refer to the top-level binding
(define foo 'top-level) (let ((foo 'local)) (top-level-foo)) => top-level
In other words, we can avoid capturing
If a lexical environment is passed as the second argument to
renamed-identifier then if the identifier is inserted free
its parent will be looked up in that environment, rather than in
the top-level environment. The use of such an identifier must
be restricted to the lexical scope of its environment.
There is another restriction imposed for implementation convenience:
Macros passing their lexical environments to
may be lexically bound only by the special forms
@letrec-syntax. No error is signaled if this restriction is not
met, but synthetic identifier lookup will not work properly.
letrec, but may also put extra information in the lexical environment so that
renamed-identifierwill work properly during expansion of the macros bound by these forms.
In order to maintain referential transparency it is necessary to
determine whether two identifiers have the same denotation. With
synthetic identifiers it is not necessary that two identifiers be
eq? in order to denote the same binding.
#tif identifiers id1 and id2 denote the same binding in lexical environment env, and
#fotherwise. env must be a lexical environment passed to a macro transformer during macro expansion.
(define top-level-foo? (procedure->memoizing-macro (let ((foo-name (renamed-identifier 'foo #f))) (lambda (exp env) (identifier-equal? (cadr exp) foo-name env))))) (top-level-foo? foo) => #t (let ((foo 'local)) (top-level-foo? foo)) => #f
quasiquoteso that literal data in macro definitions will be properly transcribed.
quote, but preserves synthetic identifier intact.
the-macrois the simplest of all possible macro transformers: 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.
the-macro may be used to protect local copies of macros against
redefinition, for example:
(@let-syntax ((let (the-macro let))) ;; code that will continue to work even if LET is redefined. ...)
Go to the first, previous, next, last section, table of contents.