Sizzle is an interpreter for the Scheme programming language. It is designed to be used as an embedded extension language and as a scripting language for a wide variety of purposes.
Sizzle implements a subset of Scheme as described in the Revised 5 Report on the Algorithmic Language Scheme (referred to as R5RS in this manual). That means that Sizzle employs fully parenthesized prefix notation (as known from Lisp), is statically scoped and handles builtin and user defined procedures as first-class objects. It implements most of Scheme as defined in R5RS, but it does not support complex numbers, arbitrary precision numbers (bignums) or rational numbers. In addition, only outward continuations (a.k.a. escape procedures) are implemented.
That means that Sizzle is a quite powerful language and will (as least I hope so) be useful for a lot of programming tasks.
Most of the text in the reference section of this manual is heavily inspired by R5RS, especially the description of the standard syntactic forms and standard procedures. Some parts, especially documentation on procedures compatible with Guile, have been taken from the Guile documentation strings.
The chapter after this introduction describes Sizzle from the user's point of view, you will learn how to start the interpreter and how to use it interactively as well as how to use it to execute Scheme scripts.
After that, in the third chapter, I will show how to do basic programming in the Scheme programming language and which data types are available and how to make use of them.
The fourth chapter documents the builtin variables which can be used to monitor and manipulate the interpreter's behaviour from Scheme.
The main reference section (chapter 5) documents all procedures as well as the syntactic forms available in the interpreter.
The sixth chapter lists all (known) differences between the Scheme implementation of Sizzle and the standard defined in R5RS.
The manual is closed by a a glossary and an index of all functions and variables.
I started writing Sizzle simply because I was interested in compiler and interpreter design. A long time ago, I had been porting a lisp interpreter called XLISP, which was written in C to Pascal. Ever since I was interested in parenthesized languages, and when I learned about Scheme, I was immediately fascinated by its clear and beautiful design. So I started writing small Scheme scripts and finally became more interested and decided to build an interpreter. It started out small, as always, but soon I noticed that I was able to implement even a bit more complicated features, so the interpreter grew. Now the distribution is more than half a meg big, and still grows.
I hope that I will be able to make a more accurate and complete documentation someday. Also, there are a few features I would like to see in the interpreter, such as bignum arithmetic, rationals, hygienic macros, etc. Some internal architectural changes seem desirable also, for example for speeding up the reader. Some profiling for creating a faster evaluator will be on the wishlist also, maybe more extensive syntax rewriting may help with this.
I would like to see all (at least all sensible) SRFIs implemented. Currently, only SRFI-1, SRFI-6 and SRFI-8 are implemented. SRFI-13 is implemented partly.
Sizzle is an embedding language which can be easily integrated into other programs written in C, but it also includes a command line program which can be used to do calculations in an read-eval-print loop as well as running scripts written in the Scheme language.
This chapter will explain how to make use of Sizzle as an interactive program as well as how to execute script files.
To start Sizzle, simply type `sizzle' at the command line. Sizzle will then initialize and start reading expression from the terminal. It will read and evaluate expressions and print them to the screen until you terminate it by either pressing `^D' at the prompt or entering the expression `(exit)'.
The command line interpreter understands the command line options shown in the table below.
-s, --script=file
-c, --command=expr
--
-).
-l, --load=file
-e, --eval=function
-s, --script=file, apply
function to command line arguments. This option also can be used
with -c, --command=expr.
-h, --help
-v, --version
-q, --no-init-file
-n, --no-system-init-file
-d, --debug
The command line option -s, --script=file has to be used
whenever a Scheme script is to be executed by Sizzle. The file
`file' will be read and all Scheme expression contained in it will
be evaluated in order. After evaluation is finished, Sizzle terminates.
For more details about Sizzle scripts see section Sizzle Scripts.
-c, --command=expr is similar, but instead of reading a file of
Scheme expressions, the Scheme expression expr will be evaluated.
Note that when using -s or -c, all remaining arguments on
the command line are ignored by Sizzle and are passed to the Scheme
script or the Scheme expression without interpretation and are available
via the primitive command-line, please see section System interface functions.
The pseudo--option -- will be discarded from the command line,
but all remaining parameters will be treated as normal arguments and not
as options, even if they begin with a dash (-). This can be used
when passing options to a Sizzle script.
All file names given with the option -l, --load=file (which
can be given more than once) are loaded into the interpreter by
evaluating all expressions read from the files, but unlike -s,
the interpreter will not terminate after evaluating the files, but
continue as normal. That means, that without -s and -c,
the interactive read--eval--print loop will start, otherwise the
appropriate action will be done, as described above.
-e, --eval=function is intended to be used with -s,
when you are using Scheme files which can be used both as library files
and as executable scripts. You can do this by placing library code in
the file and a function which serves as the main function. When you use
-s, the file will simply be loaded, but the main function will
normally not get called. This is exactly what -e is for. Simply
pass the name of the main function to -e and this function will
then be applied to the remaining command line arguments after the script
file has been loaded.
-h, --help will print out a short helping message and then quit.
-v, --version prints out the version of the Sizzle interpreter
you have installed, and then terminate. Use this command if you want to
complain about a bug in your version of Sizzle, in addition to as much
information about your system as possible.
Use the option -q, --no-init-file if you want to inhibit
automatic loading of your user's init file `~/.sizzle'.
Similarly the option -n, --no-system-init-file prevents the
system's init file from being loaded. Note that with this option, some
common procedures will not be available in the interpreter.
With the option -d, --debug, Sizzle will print some debugging
messages while running. Each occurence of -d increases the
debugging level and will cause more information to be printed out. This
option will not be very interesting for normal users and is intended for
being used by the Sizzle developers.
When you have started the Sizzle interpreter, you can start right away with typing in Scheme expressions and see how they evaluate. I will give some simple examples in this section.
Numbers, characters and strings can be entered in their read syntax and evaluate to themselves.
zzz: 1 1 zzz: "Hello World" "Hello World" zzz: #\H #\H
Lists and vectors need to be quoted, because they do not evaluate to themselves. Lists are considered to be function calls and therefore evaluate in a special way (see below). The reason why vector constants do not evaluate is not clear to me, but R5RS requires that. Strange...
zzz: #(1 2) exception: misc-error: vectors do not evaluate to themselves no backtrace available evaluate `(set! %save-backtrace% #t)' if you want backtraces zzz: '#(1 2) #(1 2)
zzz: (1 2) exception: misc-error: not a procedure: 1 zzz: '(1 2) (1 2)
In the above two examples, error messages have been printed in response
to the user's input. In an error message, the type of the error is
printed first: Here, it is an exception of type misc-error. The
following is a description of the error. In addition, we can see that
the first error shown to the user includes some more information: The
fact that currently backtraces are not available is noted and a tip how
to enable procedure backtraces.
Procedures are invoked by writing the function name as the first member
in a list. Consider the function +, which adds all its
arguments.
zzz: (+ 1 2) 3 zzz: (+ 1 2 -4) -4
When running the standalone interpreter, Sizzle defines automatically a special variable to ease interactive usage. The result of an evaluation is automatically assigned to the top-level variable $$, which can be used in following expressions. Note that the value of this variable is overwritten after each successul operation, so you have to save it yourself if you want to use it later.
zzz: 1 1 zzz: $$ 1 zzz: "foobar" "foobar" zzz: (string-length $$) 6
Note: Readline support has been removed from the Sizzle core, so you have to install the additional package `sizzleopt' to make use of it.
When available, Sizzle uses the `readline' library to provide command line editing to the command line interpreter.
The `readline' library enables command line editing with the cursor keys and some key sequences known from Emacs. Also, a command line history is available, you can recall previously typed in lines with the cursor-up key. Tab-completion, known from the shell is supported, too. When you type the beginning of a word and then hit the TAB key, the word will be completed; when there are several possible matching words, readline will complete as much as possible and then beep. You can then press the TAB once more to get a list of the matches.
Sizzle is a little bit context sensitive with tab-completion. When the word you are completing comes directly (or only seperated by whitespace) after an opening parentheses, only procedure names are completed, in all other positions, variable names are also completed.
The command line history which is maintained by the `readline' can
be written to the file `.sizzle_history' when Sizzle exits and read
in when it starts again. By default, this feature is disabled to avoid
filling the home directory of users who do not wish their programs to do
so. You have to set the boolean variable %write-history-file% to
#t to enable command line history saving. The best place to do
so is in the user initialization file `.sizzle' in the user's home
directory.
Sizzle is not only suitable for interactive usage, but also for
programming Scheme scripts. These scripts can manipulate text, can do
numeric calculations or can even be CGI scripts. Sizzle scripts can
include code from the Sizzle library using the load procedure.
The Sizzle program runs in non-interactive mode if you invoke it with the `-s' option, like `sizzle -s kewlt-scheme-program.scm'.
You can run Sizzle scripts without having to type the name of the Sizzle executable if you include the following two lines at the top of your script and making the script executable using the `chmod' program:
#! /usr/local/bin/sizzle -s !#
Another possibility is to make the following lines the first ones in your script. This version has the advantage that it is independent on the location of your Sizzle executable, but it is a little bit less efficient because the operating system has to start a shell, which in turn starts the Sizzle interpreter. Normally, the performance difference will not be noticable, though.
#! /bin/sh exec sizzle -s $0 !#
Scheme scripts can examine the arguments they were given by calling the
procedure command-line. It returns a list of strings, each being
one command line argument. The first member of the list is the name of
the interpreter, or (if you have a more sophisticated Unix flavour and
are using the #! notation for executing the interpreter) the name
of the script.
On startup, the file `init.scm' which was installed together with
the binaries and libraries is loaded before evaluating expressions from
source files or the command line, and before entering the
read-eval-print loop. `init.scm' is stored in the directory
`$prefix/share/sizzle/$version/', where $prefix is set
during configuration time (defaults to `/usr/local') and
$version is the version of your installed Sizzle package.
In addition, the system init file loads the file `.sizzle', if it exists, from the user's home directory. So if you like to customize Sizzle's behaviour, this file is the right one to put Scheme expressions.
Note that these startup files are loaded whenever the interpreter starts up, no matter whether it runs interactively in the read-eval-print loop or was started to run a Scheme script.
Loading of the initialization files can be suppressed by using the
command line options -q, --no-init-file and -n,
--no-system-init-file. The former inhibits the loading of the user's
initialization file `~/.sizzle', whereas the latter suppresses
loading of the system-wide initialization file.
When Sizzle starts up, it examines the contents of the environment
variable SIZZLE_LOAD_PATH. If it is set, it must contain a
colon-separated list of directory names. Each of these path names is
then prepended to the global variable %load-path, in the order
they appear in the environment variable. This environment variable
makes it possible to modify the locations where Sizzle searches for
files which are loaded via load or primitive-load-path, or
modules which are included with use-modules.
Some notes on building the Sizzle library and interpreter.
First, you have to get a Sizzle archive. You should be able to get a recent version from http://www.pintus.de/mgrabmue/sizzle/sizzle.html. Just follow the Download link and download an archive like `sizzle-0.0.30.tar.gz'. Replace the version number with the newest available version. You may also want to download the sizzleopt package, which includes some useful bindings, such as `readline' support for the interpreter.
Unpack the distribution tarball to a directory of your choice:
$ cd src $ tar xzvf sizzle-0.0.30.tar.gz sizzle-0.0.30/ sizzle-0.0.30/Makefile.in ...
Change to the newly created directory.
$ cd sizzle-0.0.30
When compiling for Windoze using Micro$oft Visual C, you can use the provided Project files. Refer to the `README-Win32' file for further information.
Now you have configure the package. Most of the times, this just requires you to type
./configure
but you may want to change the configuration to suit your needs. Invoke
`configure' with the --help option to get a list of the
supported options.
Currently, the following configuration options besides the standard options are supported:
--enable-warnings
--enable-debug
--enable-posix
getpid, fork etc.
This is on by default.
--enable-regexp
--enable-maximum-functionality
--enable-dl
--enable-uvector
--with-mingw=DIR
--enable-shared
--enable-static
--disable-nls
Every --enable option has a --disable pendent to switch
off a particular feature.
After a while, the configuration is done and you can compile the package.
$ make
When compiled, the package is ready for installation. Note that only the super-user may do this if you are installing to the default location `/usr/local'.
$ su Password: # make install # exit $
When everything worked well, you can now use the Sizzle interpreter.
$ sizzle zzz: (+ 1 2) 3 zzz:
This chapter gives a quick introduction to programming in the Scheme language. It will also mention Sizzle limitations and features where appropriate.
Scheme uses fully parenthesized prefix notation, that means that all procedure calls are enclosed in parentheses. The first element in a procedure call is the procedure which will be invoked and the other elements are the arguments which will be passed to the procedure. Note that the procedure will be evaluated in the same way as the rest parameters.
zzz: (+ 1 2) 3 zzz: ((lambda (x) x) 1) 1
All arguments in Scheme are passed by value, e.g evaluated before the
procedure is called. Special forms like if, define
etc. do not follow that rule, they evaluate their arguments only when
needed. There is no syntactic difference between a procedure call and
the application of a special form, so you need to know the names of all
special forms in order to tell how some given code will evaluate.
Variables are defined using the special form define and can be
modified lateron by using set!, which is another special form.
zzz: (define a 1) zzz: a 1 zzz: (set! a 2) zzz: a 2
Functions are either defined by defining a variable with the value of a
lambda expression or using a special form of define, which is
intended for defining procedures more easily.
zzz: (define identity (lambda (x) x)) zzz: (identity 2) 2 zzz: (exit) $ sizzle zzz: (define (identity x) x) zzz: (identity 3) 3
When you define a variable more than once in an environment, the former definition will be silently overwritten.
The Sizzle core contains a garbage collector, so that the programmer is not responsible to free objects which are not needed anymore. Internally, the garbage collector is implemented as a conservative collector which marks all objects as being used which are reachable through global variables (known to the collector) or are reachable by scanning the C stack.
At the moment, the garbage collector is a very simple, recursive mark-and-sweep collector, without generations or incremental behaviour. It has been sufficient for my needs, but maybe I will switch to a more sophisticated algorithm later when a need for it apears.
Sizzle has a lot of useful data types already built in, and provides a lot of procedures for manipulating values of various types. For detailed description of the available data manipulation functions please refer to the Programming Reference chapter in this manual.
The Scheme standard defines the so-called numeric tower, a hierarchy of numeric data types where every data type includes the values of the data types lower in the hierarchy and which is defined as follows:
number
complex
real
rational
integer
Furthermore, Scheme makes a difference between exact and inexact numbers. Exact numbers are always precise whereas inexact numbers are only an approximation. The same differentiation is made for operations on numbers. For example, the addition of two exact numbers always produces an exact result, but on the contrary, the division of exact numbers may be inexact.
The read syntax for numbers is as follows: the number may starts with an optional number of exactness and radix , followed by a number of digits which must fit into the radix scheme which may be given with a radix prefix. Then a decimal point and another sequence of numbers may follow, in decimal or scientific notation may follow. A list of the valid exactness and radix prefices is given in the following table.
#e
#i
#b
#o
#d
#x
Integers are exact numbers with the same range as the C long data
type.
Examples of integer constants:
42 -23 #xdead #o755 #b100001010 #d42
Floats are floating point values, corresponding to double values
in C. Real number constants can start with a radix and exactness prefix,
but only the radix prefix #d is allowed. When using the exactness
prefix #e (exact number), the number must have a fraction of
zero. Read syntax examples:
3.1459 -10.1e2 #i1.0 #e1.0
Complex and rational numbers are not supported by Sizzle. Maybe in the future they will. Also bignums (arbitrary precision numbers), as known from other Scheme systems, are not (yet) supported.
Booleans are the truth values true and false, in Scheme written like
this: #t means true and #f means false.
In Scheme, #f is the only value that is considered false in
conditionals, neither 0 nor the empty list '() counts as
false.
Characters are denotated in the following form: first, a hash mark (#), then a backslash and then the literal character. Examples:
#\j
#\
Scheme provides another notation for non-printable characters. A space
character can also be written like this #\space and a newline
like #\newline. Sizzle understands three additional symbolic names for characters. This table shows all of them:
#\space
#\newline
#\return
#\tab
#\bell
Strings are sequences of characters. String constants are enclosed in
double quotes and can contain all characters from the ASCII set. The
double quote character " and the backslash \ have to be
quoted with a preceding backslash. Some special non-printable characters can be included in string constants by denoting special backslash-character sequences. The following sequences are defined:
\n
\r
\t
\v
\b
\a
Strings can be mutable and immutable. Immutable are those which were
literally entered from the input source. They can not be used with
destructive procedures like string-set! or string-fill!.
Strings returned by functions like string-copy or string
are mutable and can be used with such strings.
Symbols are values with some special properties. They are written by simply writing their name, without any quotes or special markup characters. The main difference between symbols and strings is that symbols which have the same textual representation are in fact the same object. Additionally, symbols can have values associated to them, then they act as variables.
When reading symbols, the Sizzle reader considers all characters which do not explicitly end the symbol as part of the symbol. These ending characters are `(', `)', whitespace, `;' and `"'. It is even possible to include these characters into a symbol name by preceeding it with a backslash. Thus, these all are valid symbol names:
Hello i-am-a-symbol strange\ symbol
Of course, it is not too clever to use symbols with enclosed whitespace or parentheses in program source code. Their use can degrade readability of programs considerably.
Keywords are similar to symbols in that they are represented externally by a character sequence and that keywords with the same external representation are indeed the same objects internally. The difference between keywords and symbols is that symbols are normally bound to locations containing values and that these values are retrieved when a symbols is evaluated, whereas keywords evaluate to themselves. Thus it is not necessary to quote keywords on input.
Keywords are written like symbols, but are either prefixed with a colon
(:) or the sequence hashmark--colon (#:). When comparing,
only the keyword name is significant, the prefix is ignored.
zzz: #:keyword #:keyword zzz: :keyword #:keyword zzz: keyword error: unbound variable: keyword
In the above example you can see how keywords evaluate to themselves and
that evaluating an unknown symbol signals an error. Note also that
keywords are always printed in the #:--notation, regardless how
they were entered.
Cons cells are cells which can hold two other values. The first of the value is called the `car' of the cell and the second is called `cdr' (for historic reasons). In source files and on the read-eval-print prompt you can create cons cell by using the dotted pair syntax.
'(foo . bar) '(1 . 2)
Another way to create cons cells is using the constructor function cons:
zzz: (cons 1 2) (1 . 2)
Lists, the main data structure in Sizzle are also made out of cons cells, but they can be typed in a more convenient way than
(1 . (2 . (3 . '())))
by simply writing
(1 2 3)
Both result in the same value.
Vectors are similar to arrays in other programming languages. You can store a fixed count of values in a vector and can access them in constant time, as opposed to the time for accessing elements of a list, which is linear to the list length. The difference to ordinary arrays is that the elements of a vector can have different types.
Vectors are written like lists, but before the opening parentheses you have to put a hash mark.
#(1 2 3 4 5 6 7)
#("Hello" #\ "World" \#!)
#(#(1 2) #())
The last example shows that vectors may contain vectors and that vectors may be empty.
Vectors can be mutable and immutable. Immutable are those which were
literally entered from the input source. They can not be used with
destructive procedures like vector-set! or vector-fill.
Vectors returned by functions like make-vector or vector
are mutable and can be used with such strings.
Note: Currently, homogenous numeric vectors are only available if support for them has been explicitly enabled on configuration time for the package. See section Building Sizzle for how to enable the support if your installed version lacks it and you need it.
Normal Scheme vectors are heterogenous datatypes. You can store any value in them, just as you can with lists. Sizzle provides another kind of vectors, so-called homogenous numeric datatypes, as defined in SRFI-4. These vectors are special, because it is only possible to store numbers of a particular data type in there. There are 10 different types of those vectors, each for another numeric data type: signed 8-bit values, unsigned 8-bit values, signed 16-bit values, unsigned 16-bit values, signed 32-bit values, unsigned 32-bit values, signed 64-bit values, unsigned 64-bit values, 32-bit floating point values and 64-bit floating point values. Only values of their type can be stored into these vectors, so they provide additional type safety. They are also more space-efficient, because, for example, vectors of signed 8-bit quantities need only to reserve 8 bits for each elements, whereas normal vectors reserve at least 32 bit for eacht element, up to 160 bits.
Each of the data types has its own type prefix, which is used in all procedures dealing with that type. The following table defines the prefixes.
Homogenous numeric vectors have a read (and print) syntax similar to vectors, but between the hash mark and the opening parentheses the prefix for the vector type must be inserted:
#u8(1 2 3 4 5 6 7) #s16(-42 23 2 0) #f32(1.2 3.14159265)
Similar to normal vectors, literally denoted homogenous vectors are
read-only and can not be modified using primitive procedures like
u8vector-set!. Use procedures like make-f64vector to
create mutable vectors.
Hash tables (aka associative arrays) are very useful data structures, when a non-trivial programming task is at hand. Hash tables provide a mapping from one object to another and are similar to association lists, but they are significantly faster when they grow large.
In Sizzle, hash tables can be written literally with a #{
prefix, followed by key/value pairs separated by the arrow symbol
(=>), like this, terminated by a closing brace (}):
zzz: #{Joe => "cool" Jim => "lame"}
#{Jim => "lame" Joe => "cool"}
This is also the print syntax for hash tables.
Another possibility is to use the procedure make-hash which
constructs a hash table from its arguments. All arguments must be pairs
which will be taken as key/value pairs and inserted in the new hash
table.
zzz: (make-hash '(Joe . "cool") '(Jim . "lame"))
#{Jim => "lame" Joe => "cool"}
Note that the order of the key/value pairs depends on the size of the
data structure internally used to store the values and may differ for
the same input, when this size is not the same. The size is either
chosen internally, depending on the number of pairs, or can be provided
as an optional first argument to make-hash:
zzz: (make-hash '(Joe . "cool") '(Jim . "lame"))
#{Jim => "lame" Joe => "cool"}
zzz: (make-hash 32 '(Joe . "cool") '(Jim . "lame"))
#{Joe => "cool" Jim => "lame"}
The best choice for the size argument is a prime number not too near to a power of 2 (so says Knuth).
There are three kinds of procedures in Sizzle: Builtin procedures, builtin syntactic forms and user-defined procedures (lambda expressions, or closures).
The difference between builtin functions and syntactic forms is that funtions evaluate their arguments before theu are called and arguments to syntactic forms are only evaluated when needed.
Builtin functions and syntactic forms do not have any read syntax (that would not make sense) and they print in the following way:
zzz: set! #<macro set!> zzz: append #<primitive-procedure append>
Closures print as a pair of the lambda expression they stand for and the address of the environment the expression is closed over.
zzz: (define (f n) n) zzz: f #<closure #<procedure f (n)> 0x401af072>
Regular expressions are created using the primitive procedure
make-regexp. The resulting regular expression object can then be
used in calls to regexp-exec in order to match the regular
expression against strings. The format of the regular expression passed to make-regexp is the same as for the Posix regular expressions. For more information, type
man regex
Regular expressions are not part of any Scheme standard, but the procedures implemented in Sizzle are compatible to those used by Guile.
zzz: (define rx (make-regexp "foo|bar"))
zzz: (regexp-exec rx "a-foo-baz")
#("a-foo" (2 . 5))
zzz: (regexp-exec rx "bar-o-matic")
#("bar" (0 . 3))
Due to limitations in the interface of Posix regular expressions, regular expressions in Sizzle may not contain null bytes. Pattern strings are truncated at the first null byte on compilation.
In Scheme, it is possible to return more than one value from a
procedure. This is done by using the primitive procedure values
as the last expression in your procedure. Handling those values when
returned from a procedure is a bit strange, since the only standard form
defined for that purpose is call-with-values. The following
examples may (hopefully) clear up the whole mess.
zzz: (values 1 2 3) 1 2 3 zzz: (call-with-values (lambda () (values 1 2)) (lambda (x y) (+ x y))) 3
When multiple values are returned to the read-eval-print loop, they are
printed one after the other, every value on a new line. The second
example shows the usage of call-with-values, where the first
lambda expression is evaluated (and returns multiple values) and the
values returned from the first procedure are passed to the second
procedure as normal arguments.
Some values which appear in the interpreter are different from all
others and cannot be assigned to one of the data types. These values
are referred to as Special Values in this manual. Examples of
these special values are the end-of-file object which indicates
an end-of-file condition, or the unspecified object used inside
of the interpreter.
Sizzle supports a weird data type for constants. They can represent any
Scheme object, but have the additional property that references to
constants are replaced by their value when they are evaluated in a
procedure body. The result is faster execution, because the necessary
lookup step for variables is eliminated. Constants are created with the
syntactic form define-constant and can be used by variable, once
they are defined.
Notice that due to the substitution feature, it is not possible to redefine a constant. But would it be a constant then?
All input and output in Scheme is done using ports, which can be
regarded as data sources and sinks. Ports are characterized by the fact
that they provide procedures for reading and writing data, telling and
setting file pointer positions (if they are built on top of files) and
various others. Ports are either created explicitly by calls to
procedures like open-input-file, or implicitely when using
with-output-to-string and friends. They have a print syntax, but
no read syntax.
zzz: (current-input-port) #<rlport:open=1:read=1:write=0> zzz: (current-output-port) #<fdport:open=1:read=0:write=1:fd=1>
The first port in this example is a readline port, which supports command line editing, parentheses matching etc., the second is a normal file descriptor port connected to the standard output file descriptor.
Note that readline ports are only available if you have installed the
`sizzleopt' package and used the readline module with
(use-modules (readline readlie)).
At the moment, Sizzle supports so-called fdports, which use an underlying file descriptor, fports which use an underlying `stdio' file structure, string ports which use an internal character buffer for input and output, and rlports (readline ports) which read from the terminal via the `readline' library. The latter provide fancy command line editing.
Errors and Exceptions are distinct data types in Sizzle. Whenever an
error occurs (such as when you pass the wrong number of arguments to a
procedure), an error object is created and then propagated to the top
level, which may be either the read-eval-print loop or a procedure
evaluating a file. There the error is displayed, using the information
in the error object. In an error object, an error message is stored,
and if the error comes from the reader module, a file name and a line
and column number is also included. Error objects can not explicitly
created, but they are created whenever you use the error
procedure to signal an error.
Exceptions are a bit different. When raised, they also create objects
containing an error message, but they also contain a so-called
exception tag, which may be any atom. Exceptions can be raised from
the Scheme code by calling the procedure throw. Using the
exception tag for a particular exception or the catch-all exception tag
#t, the user can catch exceptions with the procedure
catch.
The rule of thumb is that exceptions are raised when an error situation
allows continued evaluation, and errors are signalled on errors which
are too serious to continue. An examples for exceptions is the
file-not-found exception, which is raised when a non-existent
file is opened; a quite common situation. Errors are signalled on
syntax errors, invalid procedure application or typing errors.
Right now, the difference between exceptions and errors in the Sizzle core is a bit half-baked. Not all continuable error situations throw exceptions, a lot of them unnecessarily signal errors. This will be changed in the future. Currently, support for errors is slowly phased out and all error--signalling places in the code are changed to throw various types of exceptions instead.
Sizzle only supports continuations usable as escape procedures. That means that one cannot export a continuation from the defining context by returning it from a procedure or storing it into a global variable, and then try to invoke it.
In the Sizzle core, some variables are defined which can be used from within Sizzle scripts to control and modify Sizzle's behaviour.
Variables labelled as Library variables are defined in the startup file `init.scm' and thus are only present if the embedding application has loaded that file on startup.
load
library procedure from the system init file uses this variable.
major.minor.patchlevel, and looks
like this: 0.0.30.
These variables are not defined when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
(Only available if the optional module (readline readline) was
used).
#t, a message will be
printed whenever the garbage collection is invoked or the cell heap
grows.
(backtrace) is much less
readable, so this is false by default.
#f, only
the procedure name is printed and the formal parameter list.
#t, the interpreter will consume a lot of memory if
your program is heavily recursive.
#t, backtraces are only printed when the primitive
backtrace is called.
eval-save-backtrace
and eval-print-backtrace to #t if you want backtraces.
Sizzle comes with a large number of builtin functions and special
forms. The difference between these two is that the arguments to a
function are evaluated before the function is called, the arguments to a
special form are only evaluated when needed. This makes a difference for
forms like set!, because the first argument (a symbol) needs not
be to be quoted like it would have to if set! was a
function. Also it is necessary for forms which evaluate their arguments
only when a certain condition holds. if, for example, only
evaluates its third argument if the first evaluates to the value
#t.
The provided procedures are grouped into two classes: primitive and library. Procedures which are labelled library are only available if the library files, which are installed together with Sizzle, are loaded on initialization. This will be the case if you installed Sizzle properly.
The following three procedures provide tests for three different degrees of equality. They are always available in the interpreter.
#t if obj1 and obj2 are the same values, that
means if both are stored at the same location in memory. Symbols with
the same textual representation pass this test, strings don't. For
numbers, the result is not predictable, (eq? 1 1) can return
#t, but not necessarily. Use eqv? or = to test
numbers for equality. Strings can only compared using the predicate
equal? or one of the string comparison predicates.
eq? but differs as far as numbers are
concerned. That means that (eqv? 1.0 1.0) return #t in any
case.
#t if the structure of obj1 and obj2 is the
same. You can use equal? to test lists, vectors and strings for
equality, these data structures are tested recursively. If you want to
compare strings, use this procedure, or use the procedure
string=?.
The numerical operations documented in this section are available on all platforms without needing additional modules.
#t if obj is a number, #f otherwise.
#t if obj is a complex number, #f
otherwise.
#t if obj is a inexact number in floating point
representation, #f otherwise.
#t if obj is a rational number, #f
otherwise.
#t if obj is an exact integer number, #f
otherwise.
#t if obj is an exact long integer number (a
non-immediate integer, not a bignum), #f otherwise.
#t if obj is an exact number, #f otherwise.
#t if obj is an inexact number, #f
otherwise.
#t if all arguments are numerically equal, #f
otherwise.
#t if all arguments after the first are not numerically
equal to the first argument, #f otherwise.
#t if all arguments are strictly ordered in increasing
order.
#t if all arguments are ordered in increasing order.
#t if all arguments are strictly ordered in decreasing
order.
#t if all arguments are ordered in decreasing order.
#t if obj is equal to zero, #f otherwise.
#t if obj is greater than zero, #f otherwise.
#t if obj is less than zero, #f otherwise.
#t if obj is an odd number, #f otherwise.
#t if obj is an even number, #f otherwise.
abs,
since Sizzle does not support complex numbers.
remainder as far as negative operands ar concerned.
#f is returned if string is not properly
formatted.
The boolean operations documented in this section are always available.
#t if obj is a boolean value, #f otherwise.
#t if obj is false, #f otherwise.
#f, 1 otherwise.
#f if i is 0, #t otherwise.
Sizzle implements all list and pair operations as defined in R5RS, plus
the list operations present in SRFI-1. All procedures without a special remark
are available at all times, whereas some procedures need inclusion of
the module (core list-lib) prior to usage.
list. With no arguments, the empty list () is returned.
(cons obj2 obj1), and is of utility only as a value
to be conveniently passed to higher--order procedures. (xcons
stands for exchanged cons.)
This procedure must be imported by using the module (core
list-lib).
list, but the last argument provides the tail of the
constructed list.
(cons* 1 2 3 4) => (1 2 3 . 4)
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
(init-proc i). The
dynamic order in which init-proc is applied to the indices is not
specified.
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
(start start+step ... start+(count-1)*step)
The start and step parameters default to 0 and 1, respectively. This procedure takes its name from the APL primitive.
This procedure must be imported by using the module (core
list-lib).
#t if obj is a list, #f otherwise. Only
finite lists pass this test, infinite lists return #f for this
predicate.
#t if x is a proper list -- a finite,
nil-terminated list. Return #f for any other object.
This procedure must be imported by using the module (core
list-lib).
#t if x is a circular list.
This procedure must be imported by using the module (core
list-lib).
#t if x is a finite, non-nil-terminated list. This
includes non-pair, non-() values (e.g. symbols, numbers), which are
considered to be dotted lists of length 0.
This procedure must be imported by using the module (core
list-lib).
#t if obj is a cons cell, #f otherwise.
#t if obj is the empty list, #f otherwise.
#t if the
argument is the empty list (), and #f otherwise. It is an error
to pass this procedure a value which is not a proper or circular list.
This procedure is recommended as the termination condition for
list--processing procedures that are not defined on dotted lists.
This procedure must be imported by using the module (core
list-lib).
#t if x is not a pair. Provided as a procedure as
it can be useful as the termination condition for list-processing
procedures that wish to handle all lists, both proper and dotted.
This procedure must be imported by using the module (core
list-lib).
It is an error to apply list= to anything except proper lists.
This procedure must be imported by using the module (core
list-lib).
car and cdr, where for example caddr could be defined by
(define caddr (lambda (x) (car (cdr (cdr x)))))
There are twenty-eight of these functions defined.
car, cadr, caddr, ...
These procedures must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
take-right returns the last i elements of flist.
drop-right returns all but the last i elements of
flist.
The returned list may share a common tail with the argument list.
These procedures must be imported by using the module (core
list-lib).
take! and drop-right! are destructive variants of
take and drop-right. If x is circular, take!
may return a shorter-than-expected list.
These procedures must be imported by using the module (core
list-lib).
split-at splits the list x at index i, returning two
values: a list of the first i elements and the remaining tail.
split-at! is the destructive variant of split-at.
These procedures must be imported by using the module (core
list-lib).
last returns the last element of the non-empty, finite list
pair. last-pair returns the last pair of the non-empty,
finite list pair.
length.
length+, on the other hand, will return #f when applied to
a circular list.
length+ must be imported by using the module (core
list-lib), whereas length is always available.
append. The result of the operation is
the same as for append, but as a side effect, the parameter lists
are modified when performing the append operation.
concatenate! may alter the cons cells of the passed lists.
This procedure must be imported by using the module (core
list-lib).
reverse. The result of the operation is
the same as for reverse, but as a side effect, the parameter list
is modified when performing the reverse operation.
append-reverse returns (append (reverse rev-head) tail). It is provided because it is a common operation.
append-reverse! is just the destructive variant.
These procedures must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
unzip1 takes a list of lists, where every list must contain at
least one element, and returns a list containing the initial element of
each such list. That is, it returns (map car lists).
unzip2 takes a list of lists, where every list must contain at
least two elements, and returns two values: a list of the first elements and a list of the second elements, unzip3 does the same for the first three elements of the lists, and so forth.
(unzip2 '((one 1) (two 2) (three 3))) => (1 2 3) (one two three)
These procedures must be imported by using the module (core
list-lib).
count
is iterative in that it is guarateed to apply pred to the
list elements in a left-to-right order. The counting stops when
the shortest list expires. At least one of the argument lists must be
finite.
This procedure must be imported by using the module (core
list-lib).
First, consider the single list-parameter case if clist1=(e1 e2 ... en) then this procedure returns
(kons en ... (kons e1 (kons e1 knil)))
That is, it obeys the (tail) recursion
(fold kons knil lis) = (fold kons (kons (car lis) knil) (cdr lis)) (fold kons knil '()) = knil
If n argument lists are provided, then the kons procedure must take n+1 parameters: one element from each list, and the "seed" or fold state, which is initially knil. The fold operation terminates when the shortest list runs out of values. At least one of the arhument lists must be finite.
This procedure must be imported by using the module (core
list-lib).
fold, but kons is applied to successive
sublists of the lists, rather than successive elements -- that is,
kons is applied to the pairs making up the lists.
For finite lists, the kons function may reliably apply
set-cdr! to the pairs it is given without altering the sequence
of execution.
This procedure must be imported by using the module (core
list-lib).
reduce is a variant of fold.
ridentity should be a "right identity" of the procedure f -- that is, for any value x acceptable to f,
(f x ridentity) = x
Note that ridentity is used only in the empty-list case. You
typically use reduce when applying f is expensive and you'd
like to avoid the extra application incurred when fol applies f to
the head of the list and the identity value, redundantly producing
the same value passed to f.
This procedure must be imported by using the module (core
list-lib).
reduce-right is the fold-right variant of reduce.
This procedure must be imported by using the module (core
list-lib).
unfold is defined as follows:
(unfold p f g seed) =
(if (p seed) (tail-gen seed)
(cons (f seed)
(unfold p f g (g seed)))))
(lambda (x) '()).
In other words, we use g to generate a sequence of seed values seed, g(seed), g^2(seed), g^3(seed), ...
These seed values are mapped to list elements by f, producing the elements of the result list in a left-to-right order. p says when to stop.
This procedure must be imported by using the module (core
list-lib).
unfold-right constructs a list with the following loop:
(let lp ((seed seed) (lis tail))
(if (p seed) lis
(lp (g seed) (cons (f seed) lis))))
'().
This procedure must be imported by using the module (core
list-lib).
map applies
proc element-wise to the elements of the lists and returns a
list of the results, in order. The dynamic order in which proc is
applied to the elements of the lists is unspecified.
map, but in order. for-each is for its side effects of
proc, therefore the return value is unspecified.
map
function. However, the results of the applications are appended
together to make the final result. append-map uses append
to append the results together; append-map! uses
append!. The dynamic order in which the various applications of
f are made is not specified.
These procedures must be imported by using the module (core
list-lib).
map. map! may be alter the cons
cells of list1 to construct the result list.
This procedure must be imported by using the module (core
list-lib).
map procedure that guarantees to apply f
across the elements of the list arguments in a left-to-right order.
This is useful for mapping procedures that both have side effects and
return useful values. At least one of the argument lists must be
finite.
This procedure must be imported by using the module (core
list-lib).
for-each, but f is applied to successive sublists of
the argument lists. That is, f is applied to the cons cells of
the lists, rather than the lists' elements. These applications occur in
left-to-right order.
This procedure must be imported by using the module (core
list-lib).
map, but only true values are saved. The dynamic order in
which the various applications of f are made is not specified. At
least one of the argument lists must be finite.
This procedure must be imported by using the module (core
list-lib).
filter! is the destructive variant of filter.
These procedures must be imported by using the module (core
list-lib).
partition! is the destructive variant of partition.
These procedures must be imported by using the module (core
list-lib).
remove! is the destructive variant of remove.
These procedures must be imported by using the module (core
list-lib).
#f if no element does.
This procedure must be imported by using the module (core
list-lib).
#f if no element does.
This procedure must be imported by using the module (core
list-lib).
take-while! is the destructive variant of take-while.
These procedures must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
span bsplits the list into the longest initial prefix whose
elements all satisfy pred, and the remaining tail. break
inverts the sense of the predicate: the tail commences with the first
element of the input list that satisfies the predicate.
span! and break! are the destructive variants.
This procedure must be imported by using the module (core
list-lib).
The iteration stops when a true value is produced or one of the lists
runs out of values, in the latter case, any returns #f.
Note the difference between find and any -- find
returns the element that satisfied the predicate, any returns the
true value that the predicate produced.
This procedure must be imported by using the module (core
list-lib).
Like any, every's name does not end with a question mark
-- this is to indicate that it does return a general value, not only
#t or #f.
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
memq uses eq? for comparing the values,
memv uses eqv? and member uses equal?. If
obj does not occur in list, #f is returned.
member is extended from R5RS to allow the client to pass an
optional equality procedure = used to compare keys.
#f is returned. assq uses eq? for comparing the
values, assv uses eqv? and assoc uses
equal?.
assoc is extended from R5RS to allow the client to pass in an
optional equality procedure = to compare keys.
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
alist-delete deletes all associations from alist with the
given key, using key-comparison procedure =, which defaults
to equal?. The dynamic order in which the various applications
of = are made is not specified.
alist-delete! is the destructive variant of alist-delete.
It may modify its argument list in order to produce its result.
This procedure must be imported by using the module (core
list-lib).
delete uses the comparison procedure =, which defaults to
equal?, to find all elements of list that are equal to
x, and deletes them from list. The dymanic order in which
the various applications of = are made is not specified.
The list is not disordered -- elements that appear in the result list occur in the same order as they occur in the argument list.
delete! is the destructive variant of delete. It is
allowed to alter the cons cells in its argument list to construct the
result.
These procedures must be imported by using the module (core
list-lib).
delete-duplicates removes duplicate elements from the list
argument. If there are multiple equal elements in the argument list,
the result list only contains the first or leftmost of these elements in
the result. The order of the surviving elements is the same as in the
original list.
delete-duplicates! is the destructive variant of
delete-duplicates. It is allowed to alter the argument list to
produce the result.
These procedures must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
The list parameter is always a suffix of the result -- even if the list parameter contains repeated elements, these are not reduced.
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
This procedure must be imported by using the module (core
list-lib).
These procedures must be imported by using the module (core
list-lib).
These procedures are always available.
eq?, eqv? or
equal? (for hashq, hashv, hash,
respectively) is used as the equality predicate. The function returns
an integer in the range 0 to n - 1. Note that these functions may
use internal addresses. Thus two calls to the same function where the
keys are equal according to the sameness predicate used are not
guaranteed to deliver the same value if the key object obj gets
garbage collected in between.
-ref cousins, but return
handles from the hash table rather than the value associated with
key. By convention, a handle in a hash table is the pair which
associates a key with a value. Where hashq-ref tab key returns
only a value, hashq-get-handle table key returns the pair
(key . value).
#f if no default argument is supplied).
hashq-ref uses eq? for equality testing, the other
functions use eqv? and equal?.
hashq-set! uses eq? for equality
testing, the other functions use eqv? and equal?.
All these procedures return the value.
hashq-remove! uses eq? for equality testing, the other
functions use eqv? and equal?. The procedures return the
handle (that is, the key--value pair) that was removed or #f if
the key was not found.
(proc key
value init), where on the first call init is the given
seed, and on subsequent calls init is the result of the
previous call.
The procedures in this section do not need any modules to be loaded.
#t if obj is a symbol, #f otherwise.
)gen, if not given.
All of these procedures are available without loading additional modules.
#t if obj is a character value, #f otherwise.
#t if char1 is the same character as char2,
#f otherwise.
#t if char1 has a smaller character value than
char2, #f otherwise.
#t if char1 has a smaller or equal character value
than char2, #f otherwise.
#t if char1 has a greater character value than
char2, #f otherwise.
#t if char1 has a greater or equal character value
than char2, #f otherwise.
#t if char1 is the same character as char2,
#f otherwise. This function ignores case when comparing.
#t if char1 has a smaller character value than
char2, #f otherwise. This function ignores case when
comparing.
#t if char1 has a smaller or equal character value
than char2, #f otherwise. This function ignores case when
comparing.
#t if char1 has a greater character value than
char2, #f otherwise. This function ignores case when
comparing.
#t if char1 has a greater or equal character value
than char2, #f otherwise. This function ignores case when
comparing.
#t if obj is an alphabetic character.
#t if obj is a numeric character.
#t if obj is whitespace character. The characters
space, tab, line feed, form feed and carriage return are considered to
be whitespace.
#t if obj is an upper case character.
#t if obj is a lower case character.
For convenient string handling, a lot of string primitives have been included into the Sizzle core. Unless otherwise noted, these procedures do not need the inclusion of additional modules.
#t if obj is a string, #f otherwise.
#t if obj is a the empty string "",
#f otherwise.
(compose string->list reverse):
(reverse-list->string '(#\a #\B #\c)) => "cBa"
This procedure will throw an exception if string-list is empty and
grammar is string-infix.
string-reverse returns a reversed version
of s, whereas string-reverse! reverses s in place and
returns an unspecified value.
(string-length string)
#t if string1 is the same string as string2,
#f otherwise.
#t if string1 is lexicographically less than
string2, #f otherwise.
#t if string1 is lexicographically less or equal to
string2, #f otherwise.
#t if string1 is lexicographically greater than
string2, #f otherwise.
#t if string1 is lexicographically greater or equal
to string2, #f otherwise.
#t if string1 is the same string as string2,
#f otherwise. This function ignores case when comparing.
#t if string1 is lexicographically less than
string2, #f otherwise. This function ignores case when
comparing.
#t if string1 is lexicographically less or equal to
string2, #f otherwise. This function ignores case when
comparing.
#t if string1 is lexicographically greater than
string2, #f otherwise. This function ignores case when
comparing.
#t if string1 is lexicographically greater or equal
to string2, #f otherwise. This function ignores case when
comparing.
#t if s1 is a prefix of s2.
#t if s1 is a prefix of s2. Case is ignored
when comparing characters.
#t if s1 is a suffix of s2.
#t if s1 is a suffix of s2. Case is ignored
when comparing characters.
#f if not found. If the second
argument is a procedure, it must be a predicate which will be applied to
each character in string, and the index of the first character for
which the predicate yields true is returned. start is the start
index and defaults to zero, end is the end index and defaults to
the length of string - 1.
#f if not found. If the second
argument is a procedure, it must be a predicate which will be applied to
each character in string from right to left, and the index of the
last character for which the predicate yields true is returned.
start is the start index and defaults to zero, end is the end
index and defatuls to the length of string - 1. This function
searches from right to left, whereas string-index searches from
left to right.
#f if not found.
If the second argument is a procedure, it must be a predicate which will
be applied to each character in string, and the index of the first
character for which the predicate yields false is returned. start
is the start index and defaults to zero, end is the end index and
defaults to the length of string - 1.
#f if
not found. If the second argument is a procedure, it must be a
predicate which will be applied to each character in string from
right to left, and the index of the last character for which the
predicate yields false is returned. start is the start index and
defaults to zero, end is the end index and defatuls to the length
of string - 1. This function searches from right to left, whereas
string-index searches from left to right.
#f. The optional start/end indices restrict
the operation to the indicated substrings. The returned index is in the
range [start1, end1). A successful match must lie entirely
in the [start1, end1) range of string1.
Note: The current implementation uses the naivest possible algorithm and is slow when string1 is a long string.
#f. The optional start/end indices restrict
the operation to the indicated substrings. The returned index is in the
range [start1, end1). A successful match must lie entirely
in the [start1, end1) range of string1. Case is
ignored when comparing individual characters.
Note: The current implementation uses the naivest possible algorithm and is slow when string1 is a long string.
#t or a positive integer, then the result of the
procedure will be in the range [0, bound). start and
end are optional parameters delimiting the characters which are
used to calculate the hash value, they default to 0 and the length of
s.
#t or a positive integer, then the result of the
procedure will be in the range [0, bound). start and
end are optional parameters delimiting the characters which are
used to calculate the hash value, they default to 0 and the length of
s. The case of the characters in s is ignored when
computing the hash value.
char-whitespace? primitive.
This procedure must be imported by using the module core
string-lib.
Note: This procedure has been deprecated. Use string-trim-both
instead.
#\space.
#\space.
dirname
returns . (meaning the current directory).
/foo/..), current directory marks (./), multiple slashes
(//) and trailing slashes. The root directory indicator /
is not deleted, though it is a trailing slash.
This procedure must be imported by using the module core
string-lib.
Vectors are heterogenous data types, similar to lists. That means that any Scheme data type can be stored into vectors. The main difference between lists and vectors is that vectors are of fixed size and that elements can be accessed in constant time, whereas lists require linear time to access individual elements.
Vectors can be created by either entering them literally in the normal
Scheme vector syntax #(...), or they can be created with one of
these functions. See section Vector conversion for the procedure
list->vector, which is also a constructor function.
Vectors created with one of these procedures are mutable and can
therefore be passed to procedures like vector-set!.
This procedure must be imported by using the module core
vector-lib.
This procedure must be imported by using the module core
vector-lib.
#t if obj is a vector, #f otherwise.
This procedure must be imported by using the module core
vector-lib.
Use one of these procedures to obtain information from a vector and to access individual elements.
The procedures in this section may only be used with mutable vectors. Vectors literally entered may not be passed to these procedures.
Homoenous vectors are different to normal Scheme vectors, because only numeric values can be stored into those vectors, and all elements must have the same type.
Please note that homogenous vectors are only available when they were included on configuration time of the Sizzle library. If you need these data types and primitives, please section Building Sizzle and build the library with enabled homogenous vectors.
In the following procedure descriptions, the placeholder TAG can
be replaced by any of the strings s8, u8, s16,
u16, s32, u32, s64, u64, f32
and f64, depending on the data type the procedure should be used
for. Examples are: s8vector?, make-u16vector or
f32vector-length.
#t if obj matches the type indicated by TAG,
#f otherwise.
The following procedures can be used to maintain the flow of control in
Scheme programs. The basic procedure apply, exception handling
using catch and throw and handling of multiple values with
values, call-with-values and receive are documented
in this section.
These procedures are always available in the Sizzle library except when otherwise noted.
#t if obj is a primitive or user-defined procedure,
#f otherwise.
#t if obj is a primitive procedure, #f
otherwise.
#t if obj is a user-defined procedure, #f
otherwise.
#t if obj is a syntactic form, #f otherwise.
(append (list arg1 ...)
args) as the actual arguments.
delay. The value of the promise is cached so that
a second force will return the cached value without evaluating it again.
call-with-values (see below).
This syntax is not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
dynamic-wind can be
used for cleaning up, since after is called even if thunk
causes an error or an exception.
SIGHUP
SIGINT
SIGQUIT
SIGILL
SIGTRAP
SIGABRT
SIGIOT
SIGBUS
SIGFPE
SIGKILL
SIGUSR1
SIGUSR2
SIGSEGV
SIGPIPE
SIGALRM
SIGTERM
SIGSTKFLT
SIGCLD
SIGCHLD.
SIGCHLD
SIGCONT
SIGSTOP
SIGTSTP
SIGTTIN
SIGTTOU
SIGURG
SIGXCPU
SIGXFSZ
SIGVTALRM
SIPROF
SIGWINCH
SIGPOLL
SIGIO
SIGPWR
Note that this procedure is only available when the Un*x signals work for the underlying platform.
catch clause for the
tag exception tag catches the exception or the top level is
reached, where the exception will be displayed on the current standard
error output port.
catch is used to implement exception handling. thunk is
evaluated but any exception which may be thrown by an expression
evaluated inside of thunk and is equal to the exception tag
tag (in the sense of eq?) is caught. Should no exception be
raised, the result of the last expression is returned. Otherwise,
handler is called with the tag which was thrown to and additional
arguments which may be passed to throw as arguments and the result of
evaluating handler is returned.
If tag is #t, all exceptions are caught.
zzz: (catch 'panic
(lambda () (throw 'panic "Help" "Me" "!" ))
(lambda (tag . rest) (display rest) (newline) #f))
(Help Me !)
#f
zzz: (catch #t
(lambda () (throw 'burgs))
(lambda (tag . rest) #f))
#f
call-with-current-continuation is either the result of proc
(if the continuation was not called) or the argument passed to the
continuation.
When calling a continuation with more then one parameter, all parameters are delivered to the continuation as multiple values.
call/cc is synonym to call-with-current-continuation.
Note that Sizzle does not implement a full-featured call/cc. The
continuation passed to proc may only be used as an escape
procedure. Storing it into a variable and using it from anywhere not in
the dynamic extent of proc is an error and will signal an
exception.
file-not-found exception
if string does not refer to an existing file. The return value is
unspecified.
primitive-load-path tries to locate the file in the current
directory and then in all directories in the pathname list
%load-path. Throws an file-not-found exception if
string does not refer to an existing file. The return value is
unspecified.
primitive-load-path.
transcript-on is to open the named file for output,
and to cause a transcript of subsequent interaction between the user and
the Scheme system to be written to the file. The transcript is ended by
a call to transcript-off, which closes the transcript file. Only
one transciript may be in progress at any time. The values returned by
these procedures are unspecified.
All of the following procedures are always defined in the Sizzle interpreter.
eval. version must be an exact integer spcifying the
supported Scheme report version, currently this is 5.
eval. version
must be an exact integer spcifying the supported Scheme report version,
currently this is 5.
eval.
eval.
safe-environment, and is not able to affect any other
environments.
The following procedures are always supported.
(set! eval-save-backtrace #t) prior to evaluating the
invalid expression or the backtrace will not be available.
If on/off is true, start tracing procedure proc, otherwise, switch tracing for proc off.
When a procedure is traced, a message will be printed to the current
error port whenever the procedure is called. Given a procedure
foo, which receives one argument, the format of the message is
+ foo <- (1)
That means that foo is entered (indicated by the +) with
the parameter list (1).
When tracing primitive procedures, a message when exiting from the
procedure is also printed. A call to the traced primitive modulo
with the parameter list (3 2) looks like this:
+ modulo <- (3 2) - modulo -> 1
The second line tells that the result of the function is 1.
Currently, no exit message is printed for non-primitive procedures is printed because of problems with tail calls. With the current scheme, it is not possible to tell easily when a procedure exits. I hope to change that behaviour in the future.
The procedures in this section all deal with input and output of data from and to various types of ports. Unless otherwise noted, all the procedures are always available in the interpreter.
#t if obj is an input port, #f
otherwise.
#t if obj is an output port, #f
otherwise.
current-input-port will return.
current-output-port will return.
current-error-port will return.
close-port, but is required by R5RS.
close-port, but is required by R5RS.
read-char. port defaults to the value
returned by current-input-port, if not given.
read-char on the same port
will return the character again. port is omitted, the current
input port is used. Returns the end-of-file object on end of file.
#t if it is, #f otherwise. If port is not
specified, the current input port is used.
read-line reads a newline-terminated string from port. The
return value depends on the value of handle-delim, which may be
one of the symbols trim, concat, peek and
split. If it is trim (the default), the trailing newline
is removed and the string is returned. If concat, the string is
returned with the trailing newline intact. If peek, the newline
is left in the input port buffer and the string is returned. If
split, the newline is split from the string and read-line
returns a pair consisting of the truncated string and the newline.
This procedure is not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
current-input-port. If start or end are specified,
store data only into the substring of buf bounded by start
and end (which default to the beginning and end of the buffer,
respectively).
Return a pair consisting of the delimiter that terminated the string and the number of characters read. If reading stopped at the end of file, the delimiter returned is the eof-object; if the buffer was filled without encountering a delimiter, this value is #f.
(current-output-port) is used. This function
is equivalent to:
(display obj [port]) (newline [port])
SEEK_SET
SEEK_CUR
SEEK_END
port may also be a string port, which means that the read/write pointer for the string port will be modified.
The return value is the new offset of the file pointer.
#t if obj is the end-of-file object, #f
otherwise.
#t if port is a closed port, #f otherwise.
display's return value is
unspecified. If port is omitted, the current output port is used.
write's return value is unspecified. If
port is omitted, the current output port is used.
write-char's return value is
unspecified. If port is omitted, the current output port is used.
display. newline's return value is
unspecified. If port is omitted, the current output port is used.
close-input-port,
though its storage will be reclaimed by the garbage collector if it
becomes inaccessible.
get-output-string. The port can be closed by
close-output-port, though its storage will be reclaimed by the
garbage collector if it becomes inaccessible.
open-output-string, returns a
string consisting of the characters that have been output to the port so
far.
#t, if port is a tty, #f otherwise.
port defaults to the current input port.
display would produce when
printing obj.
Sizzle supports Posix regular expressions. This section documents all functions provided to match text using regular expressions.
Note that Posix regular expressions only support matching of strings which do not include null bytes.
Regular expression operations are not available if the Sizzle library
was configured with the --disable-regexp option or if no usable
regular expression matching library was found on configuration time.
#t if obj is a compiled regular expression object,
#f otherwise.
regexp/icase
regexp/extended
regexp/basic
regexp/newline
regexp/notbol
regexp/noteol
The Posix standard and many traditional Unix versions define a lot of functions which are useful for systems programming. Some of the most useful functions have been included into Sizzle, so it can be used for basic system programming tasks as well as all other uses.
Not all functionality documented in this section is available on all
platforms. fork, for example cannot be implemented efficiently
under Windoze. Primitives, which do not function properly on the system
Sizzle was compiled on, will throw a not-available exception when
called.
Except when otherwise noted, procedures in this section are not
available when Sizzle was configured with the --disable-posix
option. You also need to perform a (use-modules (core posix))
call to make these procedures available.
-s
SCRIPT command line option, only the script name (as the first element
in the command line) and the arguments after SCRIPT are contained
in the command line list.
This procedure is always available.
system-error exception if an error
occurs. The return value is the exit code of the child process.
#f otherwise.
This procedure is always available.
This procedure is only available if supported by the underlying C library.
This procedure is only available if supported by the underlying C library.
system-error exception will be raised if the directory
string cannot be changed to. The return value is not specified.
This procedure is only available if supported by the underlying C library.
This procedure is only available if supported by the underlying C library.
system-error exception if an error occurs. The return value is
not specified.
This procedure is only available if supported by the underlying C library.
system-error exception may be raised if an error occurs.
This procedure is only available if supported by the underlying C library.
system-error exception if
an error occurs. The return value is not specified.
This procedure is only available if supported by the underlying C library.
system-error exception may be raised if an error occurs.
This procedure is only available if supported by the underlying C library.
system-error exception may be raised if an error occurs. The
return value is not specified.
This procedure is only available if supported by the underlying C library.
system-error exception may be raised if an error occurs.
This procedure is only available if supported by the underlying C library.
system-error exception may be raised if an error
occurs. The return value is not specified.
This procedure is only available if supported by the underlying C library.
system-error
exception if an error occurs.
This procedure is only available if supported by the underlying C library.
This procedure is only available if supported by the underlying C library.
system-error exception if
an error occurs. The returned vector contains the fields:
username
password
x if using shadow passwords
uid
gid
gecos
dir
shell
This procedure is only available if supported by the underlying C library.
system-error exception if an
error occurs. The returned vector has the same format as for
getpwnam.
This procedure is only available if supported by the underlying C library.
getpwnam and getpwuid.
system-error exception if an error
occurs.
This procedure is only available if supported by the underlying C library.
system-error exception if an error occurs.
The returned vector has the following fields:
dev
ino
mode
nlink
uid
gid
rdev
size
atime
mtime
ctime
blksize
blocks
type
regular,
directory, symlink, block-special,
char-special, fifo, socket or unknown.
perms
The file mode is a bitset which can be tested by logically combining it with one or more of the following constants:
S_ISUID
S_ISGID
S_IRWXU
S_IRUSR
S_IWUSR
S_IXUSR
S_IRWXG
S_IRGRP
S_IWGRP
S_IXGRP
S_IRWXO
S_IROTH
S_IWOTH
S_IXOTH
This procedure is only available if supported by the underlying C library.
stat, but does not follow symbolic links.
This procedure is only available if supported by the underlying C library.
stat and lstat.
#t if
access is permitted, #f otherwise. This function may raise a
system-error exception if an error occurs. mode is a mask
of one or more of the following constants:
R_OK
W_OK
X_OK
F_OK
access? is only successful if all permissions are granted.
system-error
exception if an error occurs.
This procedure is only available if supported by the underlying C library and under Windows.
O_RDONLY
O_WRONLY
O_RDWR
O_CREAT
O_EXCL
O_CREAT, if the file already exists it is an error
and the open will fail.
O_NOCTTY
O_TRUNC
O_APPEND
O_NONBLOCK
O_NDELAY
O_NONBLOCK.
O_SYNC
If O_CREAT is given and the file will be created, the additional
argument mode must be given, which denotes the file permission the
new file will have. mode is a mask of the permission constants
listed in the description of stat.
This function may raise a system-error exception if an error
occurs.
open with flags equal to (logior
O_CREAT O_WRONLY O_TRUNC).
system-error
exception if an error occurs.
system-error exception if an error occurs.
This procedure is only available if homogenous vectors were enable on configuration time.
system-error exception if an
error occurs.
This procedure is only available if homogenous vectors were enable on configuration time.
system-error exception if an error occurs.
This procedure is only available if homogenous vectors were enable on configuration time.
system-error exception if
an error occurs.
system-error exception
if an error occurs.
This procedure is only available if supported by the underlying C library.
system-error exception if an error
occurs.
This procedure is only available if supported by the underlying C library.
system-error exception if an error occurs.
system-error exception if an error
occurs.
This procedure is only available if supported by the underlying C library.
S_I... constants listed in the
description of stat. This function may raise a
system-error exception if an error occurs.
system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library.
system-error
exception if an error occurs.
This procedure is only available if supported by the underlying C library.
If pid equals 0, then sig is sent to every process in the process group of the current process. If pid equals -1, then sig is sent to every process except for the first one, from higher numbers in the process table to lower. If pid is less than -1, then sig is sent to every process in the process group -pid. If sig is 0, then no signal is sent, but error checking is still performed.
This function may raise a system-error exception if an error
occurs.
This procedure is only available if supported by the underlying C library.
system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library.
waitpid man page. This
function may raise a system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library and under Windows.
system-error exception
if an error occurs.
system-error exception
if an error occurs.
execl, but search the path for filename.
execl, but pass the environment list env together with
the command line arguments args to the process.
system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library.
system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library.
system-error exception if an error occurs. The
returned vector contains the following fields:
sysname
nodename
release
version
machine
This procedure is only available if supported by the underlying C library and under Windows.
system-error exception if an error occurs.
tmpnam procedure generates a unique temporary filename in the
standard directory for temporary files (normally `/tmp').
This procedure is only available if supported by the underlying C library.
tmpfile procedure generates a unique temporary filename in
the standard directory for temporary files (normally `/tmp') . The
temporary file is then opened in binary read/write (w+b) mode. The file
will be automatically deleted when it is closed or the program
terminates. The return value is a port open for input and output. This
function may raise a system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library.
umask sets the umask to (logand mask #o777). The umask is
used by open(2) to set initial file permissions on a newly-created file.
Specifically, permissions in the umask are turned off from the mode
argument to open(2) (so, for example, the common umask default value of
022 results in new files being created with permissions 0666 & ~022 =
0644 = rw-r--r-- in the usual case where the mode is specified as 0666).
If mask is not given, the current umask value is returned, without
changing the umask for the process.
man strftime.
This procedure is only available if supported by the underlying C library.
man strptime for the format
specification. Returns a pair consisting of a time vector and the
number of characters of string which have been used up when
parsing. This procedure is essentialy the counterpart of
strftime.
This procedure is only available if supported by the underlying C library.
#f if not specified
gmtime.
Bug: Right now time zone offset and time zone names are not correctly
set by localtime.
gmtime.
gmtime or localtime, which split up the time value into
its various parts.
system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library and under Windows.
fcnt performs one of various operations on the file descriptor
fd. The following commands are possible:
F_DUPFD
F_GETFD
F_SETFD
F_GETFL
F_SETFL
O_APPEND and O_NONBLOCK may be set. The flags are shared
between copies (made with dup etc.) of the same file descriptor.
F_GETLK, F_SETLK, F_SETLKW
F_GETLK
F_SETLK
F_SETLKW
F_GETOWN
F_SETOWN
SIGIO and
SIGURG signals for events on file descriptor fd. Process
groups are specified using negative values.
This procedure is only available if supported by the underlying C library and (limited) under Windows.
fsync.
This procedure is only available if supported by the underlying C library.
#t if obj is a directory stream, #f otherwise.
This procedure is only available if supported by the underlying C library and under Windows.
readdir,
closedir and rewinddir. This procedure may raise a
system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library and under Windows.
This procedure is only available if supported by the underlying C library and under Windows.
system-error exception if an error occurs.
This procedure is only available if supported by the underlying C library and under Windows.
readdir, the first file from the stream will be read. The
return value is not specified.
This procedure is only available if supported by the underlying C library and under Windows.
strerror(errno) or herror(), whatever is appropriate
for the specific error.
AF_INET and the type SOCK_STREAM for normal
internet sockets. This procedure may raise a system-error
exception if an error occurs. The following socket types are also defined:
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW
SOCK_SEQPACKET
SOCK_RDM
For the defined address family constants, refer to the documentation for
bind.
close-port. The
shutdown procedure allows reception or transmission on a
connection to be shut down individually, according to the parameter
how:
The return value is unspecified.
accept to accept a connection from
the queue. The return value is unspecified.
network-error exception if an error
occurs.
The return value is a pair in which the car is a new socket port for the connection and the cdr is an object with address information about the client which initiated the connection.
If the address is not available then the cdr will be an empty vector. sock does not become part of the connection and will continue to accept new requests.
accept.
accept.
network-error and system-error exceptions.
accept.
server-socket or any
equivalent calling sequence to socket, bind and
listen. server-loop will wait for incoming connection
using accept and call proc when a connection is available.
proc must expect two parameters, the first one being an input port
connected to the accepted socket, the second an output port connected to
the socket.
socket to
the address specified by family, address, and the port
number port. This procedure returns an unspecified value.
The following address families are defined:
AF_UNIX
AF_INET
If your system supports them, the following families are also defined:
AF_ISO
AF_NS
AF_IMPLINK
select system call on the file descriptor sets
rdfd, wrdf and exfd. The timeout value is calculated
from the seconds sec and the microseconds usec. The number
of the highest file descriptor in any of the sets is returned as the
result.
Scheme is suited for programming large programs, but it is very inconvenient to implement modules with restricted exports using standard techniques. Therefore, a module system similar to Guile's has been implemented.
In Sizzle, a module is a data structure with a private environment in
which all definitions local to the module are stored and an export list
which defines which of the defined symbols are to be exported to other
modules. When a module is imported using the syntactic form
use-modules, the symbol bindings from the export list are
transferred to the environment of the importing module, thus making
visible the exports. This works for procedures as well as for variables
and constants.
export, documented below.
Options may be one or more pair of a keyword and a value. The following keywords are presently defined:
#:use-module
#:export
export syntactic form.
Sizzle support dynamic loading of shared libraries under Unix using the dl interface.
dlerror().
dlopen()'ed,
otherwise the file name libname.so is opened via
dlopen(). When the loaded object exports a symbol called
zzz_init_name(), this function is called without arguments
and should initialize the library.
This function may throw a dl-error exception if the file could
not be loaded or if the initialization function returned a value other
than RESULT_SUCCESS.
Besides the high-level procedure load-library, some low-level
procedures are provided which implement a wrapper around the `dl'
library.
dlopen() the file filename and return a dynamic library
object for that file. flags may be the bitwise or of the following
constants:
RTLD_GLOBAL
RTLD_LAZY
RTLD_NOW
%dlsym with the library lib will fail.
dl-error
exception if the dymbol could not be resolved.
%dlsym) without arguments. A dl-error
exception is thrown if the function returns a value other than
RESULT_SUCCESS.
Sizzle can handle macros defined using the primitive
define-macro. The macro interface should be compatible to
Guile's, but I have not yet verified that completely.
This is an example of a macro writeln, which prints all its
arguments using display and then advances to the next line using
newline.
(define-macro (writeln . --x) `(begin (for-each display (list ,@--x)) (newline)))
You have to be careful about the formal parameter names given with args, because they may shadow variables visible when the macro is called.
car of the list must be a macro object.
zzz: (define-macro (unless cond . body)
`(if (not ,cond) (begin ,@body)))
zzz: (expand-macro (list unless '(> x 0) '(display x)))
(if (not (> x 0)) (begin (display x)))
define-macro to the argument list list. This will cause
the transformer procedure for macro to be applied to the arguments
in list. The value returned by the macro transformer is returned.
Sizzle also has some limited support for the macros from R5RS, but be careful when using them for the following reasons: The syntax is not fully implemented, especially substituting for vector patterns does not work. Most important, because this is a major feature of R5RS macros, is the lacking of hygienic macros. Variable shadowing and free variable capturing is very likely when using these macros in Sizzle. Maybe you should not use them at all at the moment, but since they are somehow implemented and accessible, I decided to at least document their deficiencies.
For more information about macros, have a look at the Sizzle startup file `init.scm', located in the `data' subdirectory in the distribution, where some simple macros are defined. Also refer to R5RS for more information about syntax and semantics of the macro definition commands.
syntax-rules to the variables and evaluate
body. The defined syntactic forms will be visible in body
only. The return value is the return value of the last expression in
body.
syntax-rules to the variables and evaluate
body. The defined syntactic forms will be visible in the
syntax-rule statements and body only. In contrast to
let-syntax, syntax elements defined in the variable binding
section can refer to each other recursively. The return value is the
return value of the last expression in body.
syntax-rules, to name in the current environment. The
return value is unspecified.
(pattern templace), where each templace has the
form (keyword pattern ...) and each template
has the form constant, symbol, (template ...)
or #(template ...).
It is often necessary to access the runtime system for writing efficient programs, but also for debugging purposes. The procedures in this section are provided for that task.
primitive-load-path. The
file mus define a procedure called symbol, or an error will be
signalled.
Sizzle provides a mechanism to make using it more comfortable. This is some kind of self-documentation as known from programs like Emacs. The principle of this feature is that every procedure object, both primitive and user-defined can have a documentation object attached. Normally, these objects are simply strings which tell how to use the procedure, which parameters are expected and what value(s) is/are returned, as well as a short description of the functionality.
The following procedures help to make use of the self-documentation system.
#f if no wuch object is available. For procedure objects,
documentation tries to load a documentation string from the file
`docstrings.txt', which was installed with Sizzle. Not all
primitives are documented in this file yet, so #f may be returned
for them, too.
documentation to obj after calling this procedure. The
return value is unspecied.
describe can be used on the procedures to get more information
about them. The return value of this procedure is not specifed.
This section is a catch-all for all primitive procedures which do not fit into any of the other categories.
used-cons-cells
used-tagged-cells
allocated-cons-cells
allocated-tagged-cells
cons-heap-usage
tagged-heap-usage
other-usage
gc-count
gc-time
gc-percent
global-accesses
lloc-accesses
lloc object.
gloc-accesses
gloc object.
tail-calls
evaluate-calls
zzz_evaluate().
closure-calls
primitive-calls
syntactic-calls
immediate-calls
random returns always the same sequence of random
number, unless you have set the random seed using srand.
random to n. The
return value is not specified.
1+ and add1 return their argument
plus 1, 1- and sub1 return their argument minus 1. These
functions are often used in textbooks on Scheme, so I put them in.
These procedures are not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
You have to use the module (core pprint) to have access to this
procedure.
There are two types of syntactic forms. The forms labelled with Syntax are builtin syntax, the forms labelled Defined syntax are defined in the startup file `init.scm' and may be not present if the embedding application does not load this init file.
quote, with the difference that expressions with
unquote or unquote-splicing are evaluated in
obj. Also has a shorthand form: ``foo' has the same meaning
`(quasiquote foo)'.
quasiquote expression, evaluates its
argument. Also has a shorthand form: `,foo' has the same meaning
`(unquote foo)'. unquote may only be used inside of
quasiquote expression, an error is signalled if used in another
context.
quasiquote expression, evaluates its
argument. The difference between unquote and
unsuote-splicing is that the latter requires its argument to
evaluate to a list which is then inserted at the current position with
one level of nesting removed. Also has a shorthand form: `,@foo'
has the same meaning `(unquote-splicing
foo)'. unquote-splicing may only be used inside of
quasiquote expression, an error is signalled if used in another
context.
set! on variables
which have been already defined by either define or one of the
let-constructs.
define which is equivalent to
(define variable (lambda (arg1 ...) commands ... (define variable (lambda (arg1 ... . argn) commands ... (define variable (lambda arg commands ...
unbound-variable error. The return value is not specified.
define and undefine. defined? returns
#t if symbol is a defined variable and #f otherwise.
define and define-constant is that variables
created using define-constant are read-only and cannot be
modified with set!. This enables runtime optimizations because
references to constant variables can be replaced by the variable's
value, eliminating symbol lookups.
#t, then is evaluated and the result of that
evaluation is returned. Otherwise, the behaviour depends on the
presence of the else expression. If else is not provided,
the return value is unspecified, otherwise else is evaluated and
the result is returned.
(test expression1 ...)
Alternatively, a clause may be of the form
(test => expression)
and the last clause may be an else clause, which has the form
(else expression1 expression2 ...)
A cond expression is evaluated by evaluating the test
expressions of successive clauses in order until one of them
evaluates to a true values. The first clause whose test
evaluates to true is chosen and the expressions in the clause are
evaluated in order and the value of the last expression is returned as
the value of the cond expression. If the selected clause
has no expressions, the value of the test is returned. An
else clause is chosen and the following expressions are
evaluated if no other test evaluates to true.
If the selected clause has the => form, the
expression following the arrow must evaluate to a procedure to
which the result of the test is applied to yield the result of the
cond expression.
((datum1 ...) expression1 expression2 ...)
where each datum is an external representation of some object. The last clause may be of the form
(else expression1 expression2 ...)
A case expression is evaluated by first evaluating the key.
The resulting value is compared against each of the datums using
the equality predicate eqv?, and if a match is found, the
expression following the matching datum is evaluated and the
result of the last expression is returned as the result of the
case expression.
Should no clause match and an else clause is present, that
clause is chosen and the expressions following the else are
evaluated in order to compute the result of the case expression.
do is an iteration construct. First, all variables are
bound to the values of their corresponding init values. Then the
test expression is evaluated and if the value is false, the
commands are evaluated in order. After each iteration, the
variables are bound to the result of evaluating the corresponding
step expressions and the test is evaluated again. The loop
terminates as soon as the test evaluates to a true value. Then the
expressions after the test are evaluated in order and the
value of the last expression is returned as the value of the
do expression.
begin accepts one or more expressions as its arguments. All
expressions are evaluated in the order they appear in the argument list
and the result of the last expression is returned. The result is
unspecified if no command is given.
let creates a block in which all variables named in the first
argument list are redefined to the corresponding values. The
expressions in the body are executed and afterwards all variables are
rebound to their original values. The result of the last evaluated
expression is returned. If no body expressions are given, the result is
unspecified. When using let, the variables are not visible
to expressions, because the variables are bound after all the
expressions are evaluated.
let, but the expressions are evaluated in
left-to-right order where each variable is visible to the
expression on its right.
let, but the variables are visible to all
expressions, thus making possible mutual recursive procedures.
and evaluates all expressions in order, but stops
evaluation as soon as one of the expressions returns a false
value. Returns #f if any of the expressions returns #f and
returns the result of the last expression otherwise. When called without
arguments, #t is returned.
and evaluates all expressions in order, but stops
evaluation as soon as one of the expressions returns a non-false
value. Returns #f if none of the expressions returns #t
and returns the result of the first expression returning a non-false
value otherwise. When called without arguments, #f is returned.
force will evaluate expression and
return the result. Evaluation is performed in the same environment in
which the promise was created.
#f is
returned, if only called with a test argument, the value of the
test is returned, otherwise the value of the last expression in
body is returned.
This macro is not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
#f. If called without arguments, #f is
returned, if only called with a test argument, the value of the
test is returned, otherwise the value of the last expression in
body is returned.
This macro is not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
#f is returned.
This macro is not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
#f if no call to break occurs inside
of body, otherwise the value given to break is returned.
This macro is not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
while, so
it was put in this section. break is only defined inside of a
while body. When called, it aborts the innermost while
loop and lets it return val.
This macro is not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
break, this is not a syntactic form, but is closely related
to while, so it was put in this section. continue is only
defined inside of a while body. When called, it restarts the
innermost while loop, starting with the test of the while condition.
This macro is not supported when the option -n,
--no-system-init-file is passed to the interpreter, or if the system
startup file is not found.
Sizzle is not a complete implementation of Scheme as defined in the Revised 5 Report on the Algorithmic Language Scheme (R5RS), but most of the standard procedures from that report and all data types except complex and rational numbers are supported. This chapter lists all differences between Sizzle and standard Scheme.
First of all, Sizzle does only support non-hygienic macros at all, and
the high-level syntax definitions from R5RS are implemented a little bit
shaky. call-with-current-continuation only works in upward
direction properly, general continuations can be compiled in, but are
buggy and will segfault in the current state. Besides of that, Sizzle
is a quite useful language for embedding and higher-order functional
programming purposes.
The following data types are implementd in Sizzle, including most standard procedures for manipulating objects of these types.
The numerical tower is not fully implemented, not available are the number types:
These are the standard procedures defined in Sizzle.
quote, quasiquote, unquote, unquote-splicing, lambda, if, cond, case, set!, and, or, do, let, let*, letrec, begin, define
eqv?, eq?, equal?, number?, complex?, real?, rational?, integer?, exact?, inexact?, zero?, positive?, negative?, odd?, even?, max, min, +, *, -, /, abs, quotient, remainder, modulo, floor, ceiling, truncate, round, exp, log, sin, cos, tan, asin, acos, atan, atan, sqrt, expt, exact->inexact, inexact->exact, number->string, number->string, string->number, string->number, gcd, lcm, not, boolean?, pair?, cons, car, cdr, set-car!, set-cdr!, caar, cadr, ..., cdddar, cddddr, null?, list?, list, length, append, reverse, list-tail, list-ref, memq, memv, member, assq, assv, assoc, symbol?, symbol->string, string->symbol, char?, char=?, char<?, char>?, char<=?, char>=?, char-ci=?, char-ci<?, char-ci>?, char-ci<=?, char-ci>=?, char-alphabetic?, char-numeric?, char-whitespace?, char-upper-case?, char-lower-case?, char->integer, integer->char, char-upcase char, char-downcase, string?, make-string, make-string, string, string-length, string-ref, string-set!, string=?, string<?, string>?, string<=?, string>=?, string-ci=?, string-ci<?, string-ci>?, string-ci<=?, string-ci>=?, substring, string-append, string->list, list->string, string-copy, string->fill!, vector?, make-vector, make-vector, vector, vector-length, vector-ref, vector-set!, vector->list, list->vector, vector-fill!, procedure?, apply, map, for-each, eval, interaction-environment, call-with-input-file, call-with-output-file, with-input-from-file, with-output-to-file, input-port?, output-port?, current-input-port, current-output-port, open-input-file, open-output-file, close-input-port, close-output-port, read, read-char, peek-char, write-char, eof-object?, write, display, newline, delay, force, values, call-with-values, dynamic-wind, transcript-on, transcript-off, null-environment, scheme-report-environment, char-ready?
primitive-load, which works like
load as defined in R5RS. The Scheme procedure load in
Sizzle searches all directories listed in the variable
%load-path as well as the current directory if the given
filename is not absolute.
rationalize, make-rectangular, make-polar
#t (true) or #f
(false).
catch.
#\t.
(a
. b).
catch form.
if or lambda forms are examples of
syntactic forms.
Jump to: ! - % - * - + - - - . - / - 1 - < - = - > - a - b - c - d - e - f - g - h - i - k - l - m - n - o - p - q - r - s - t - u - v - w - x - z
This document was generated on 6 December 2000 using texi2html 1.56k.