|
The Scheme Request for Implementation
(SRFI) process
grew out of the Scheme Workshop held in Baltimore, MD, on
September 26, 1998, where the attendees considered a number of
proposals for standardized feature sets for inclusion in Scheme
implementations. Many of the proposals received overwhelming
support in a series of straw votes. Along with this there was
concern that the next Revised Report would not be produced for
several years and this would prevent the timely implementation of
standardized approaches to several important problems and needs
in the Scheme community. Only the implemented SRFIs are (briefly) presented here. For further
information on each SRFI, please look at the official
SRFI site.
STklos supports 98 finalized SRFIS. Some of
these SRFIS are embedded and some are external. An
embedded SRFI can be directly used without any particular action,
whereas an external needs to be loaded. The following SRFIS are implemented: - SRFI-0
--
Feature-based conditional expansion construct
(embedded)
- SRFI-1
--
List Library
(external)
- SRFI-2
--
AND-LET*: an AND with local bindings, a guarded LET* special form
(external)
- SRFI-4
--
Homogeneous numeric vector datatypes
(external)
- SRFI-5
--
A compatible let form with signatures and rest arguments
(external)
- SRFI-6
--
Basic String Ports
(embedded)
- SRFI-7
--
Feature-based program configuration language
(external)
- SRFI-8
--
Receive: Binding to multiple values
(embedded)
- SRFI-9
--
Defining Record Types
(external)
- SRFI-10
--
Sharp Comma External Form
(embedded)
- SRFI-11
--
Syntax for receiving multiple values
(embedded)
- SRFI-13
--
String Library
(external)
- SRFI-14
--
Character-Set Library
(external)
- SRFI-15
--
Syntax for dynamic scoping (withdrawn)
(embedded)
- SRFI-16
--
Syntax for procedures of variable arity
(embedded)
- SRFI-17
--
Generalized set!
(external)
- SRFI-18
--
Multithreading support
(embedded)
- SRFI-22
--
Running Scheme Scripts on Unix
(embedded)
- SRFI-23
--
Error reporting mechanism
(embedded)
- SRFI-25
--
Multi-dimensional Arrays
(external)
- SRFI-26
--
Notation for Specializing Parameters without Currying
(external)
- SRFI-27
--
Source of random bits
(external)
- SRFI-28
--
Basic Format Strings
(embedded)
- SRFI-29
--
Localization
(external)
- SRFI-30
--
Nested Multi-line Comments
(embedded)
- SRFI-31
--
A special form for recursive evaluation
(embedded)
- SRFI-34
--
Exception Handling for Programs
(embedded)
- SRFI-35
--
Conditions
(external)
- SRFI-36
--
I/O Conditions
(external)
- SRFI-37
--
args-fold: a program argument processor
(external)
- SRFI-38
--
External representation of shared structures
(embedded)
- SRFI-39
--
Parameters objects
(embedded)
- SRFI-41
--
Streams
(external)
- SRFI-45
--
Primitives for Expressing Iterative Lazy Algorithms
(embedded)
- SRFI-48
--
Intermediate Format Strings
(external)
- SRFI-51
--
Handling rest list
(external)
- SRFI-54
--
Formatting
(external)
- SRFI-55
--
Require-extension
(embedded)
- SRFI-59
--
Vicinity
(external)
- SRFI-60
--
Integers as bits
(external)
- SRFI-61
--
A more general COND clause
(external)
- SRFI-62
--
S-expression comments
(embedded)
- SRFI-64
--
A Scheme API for test suites
(external)
- SRFI-66
--
Octet Vectors
(external)
- SRFI-69
--
Basic Hash Tables
(external)
- SRFI-70
--
Numbers
(embedded)
- SRFI-74
--
Octet-Addressed Binary Blocks
(external)
- SRFI-87
--
=> in case clauses
(embedded)
- SRFI-88
--
Keyword Objects
(embedded)
- SRFI-89
--
Optional Positional and Named Parameters
(external)
- SRFI-94
--
Type-Restricted Numerical Functions
(external)
- SRFI-96
--
SLIB Prerequisites
(external)
- SRFI-98
--
Interface to access environment variables
(embedded)
- SRFI-100
--
define-lambda-object
(external)
- SRFI-111
--
Boxes
(embedded)
- SRFI-112
--
Environment Inquiry
(embedded)
- SRFI-113
--
Sets and Bags
(external)
- SRFI-117
--
Queues based on lists
(external)
- SRFI-118
--
Simple adjustable-size strings
(embedded)
- SRFI-127
--
Lazy Sequences
(external)
- SRFI-128
--
Comparators (reduced)
(external)
- SRFI-129
--
Titlecase procedures
(external)
- SRFI-130
--
Cursor-based string library
(external)
- SRFI-132
--
Sort Libraries
(external)
- SRFI-133
--
Vector Library (R7RS-compatible)
(external)
- SRFI-134
--
Immutable Deques
(external)
- SRFI-135
--
Immutable Texts
(external)
- SRFI-137
--
Minimal Unique Types
(external)
- SRFI-141
--
Integer Division
(external)
- SRFI-143
--
Fixnums
(embedded)
- SRFI-144
--
Flonums
(external)
- SRFI-145
--
Assumptions
(embedded)
- SRFI-151
--
Bitwise Operations
(external)
- SRFI-156
--
Syntactic combiners for binary predicates
(external)
- SRFI-158
--
Generators and Accumulators
(external)
- SRFI-161
--
Unifiable Boxes
(external)
- SRFI-169
--
Underscores in numbers
(embedded)
- SRFI-170
--
POSIX API
(external)
- SRFI-171
--
Transducers
(external)
- SRFI-173
--
Hooks
(external)
- SRFI-174
--
POSIX Timespecs
(external)
- SRFI-175
--
ASCII character library
(external)
- SRFI-176
--
Version flag
(embedded)
- SRFI-180
--
JSON
(external)
- SRFI-185
--
Linear adjustable-length strings
(external)
- SRFI-189
--
Maybe and Either: optional container types
(external)
- SRFI-190
--
Coroutines Generators
(external)
- SRFI-192
--
Port Positioning
(embedded)
- SRFI-193
--
Command line
(embedded)
- SRFI-195
--
Multiple-value boxes
(embedded)
- SRFI-196
--
Range Objects
(external)
- SRFI-207
--
String-notated bytevectors
(external)
- SRFI-208
--
NaN procedures
(embedded)
- SRFI-214
--
Flexvectors
(external)
- SRFI-216
--
SICP Prerequisites (Portable)
(external)
- SRFI-217
--
Integer Sets
(external)
- SRFI-219
--
Define higher-order lambda
(embedded)
- SRFI-223
--
Generalized binary search procedures
(external)
Using a particular SRFI can be done with the special form
cond-expand defined in SRFI-0 which is fully supported
by STklos. This form accepts features identifiers which are of the
form srfi-n where n represents the number of the SRFI
supported by the implementation (for instance srfi-1 or
srfi-30). For instance, to use srfi-n, you can use
This forms does nothing if srfi-n is an embedded SRFI and
ensures that all the files needed by this SRFI will be properly loaded if it
is an external SRFI. STklos also offers the primitive require-feature
which ensures (eventually) the loading of files needed to use a given SRFI. This
primitive accepts several forms to ensure that the SRFI can be used.
For instance, to use SRFI-1 the following forms are possible:
(require-feature 'srfi-1)
(require-feature "srfi-1")
(require-feature 1)
(require-feature 'lists)
|
The list of the aliases defined for the supported SRFIs is given in figure
3
As said before, a embedded SRFI can be used directly without loading a
support file. (Note that using require-feature works too
and permits to ignore if the SRFI is embedded). List of embedded SRFIs:
srfi-0 srfi-6 srfi-8 srfi-10 srfi-11 srfi-15 srfi-16 srfi-18 srfi-22 srfi-23 srfi-28 srfi-30 srfi-31 srfi-34 srfi-38 srfi-39 srfi-45 srfi-55 srfi-62 srfi-70 srfi-87 srfi-88 srfi-98 srfi-111 srfi-112 srfi-118 srfi-143 srfi-145 srfi-169 srfi-176 srfi-192 srfi-193 srfi-195 srfi-208 srfi-219
.
An external SRFI needs to load at least one external file. This can be
done with require or require-feature. As with embedded SRFIS, using require-feature permits to ignore if the SRFI is external. List of external SRFIs:
srfi-1 srfi-2 srfi-4 srfi-5 srfi-7 srfi-9 srfi-13 srfi-14 srfi-17 srfi-25 srfi-26 srfi-27 srfi-29 srfi-35 srfi-36 srfi-37 srfi-41 srfi-48 srfi-51 srfi-54 srfi-59 srfi-60 srfi-61 srfi-64 srfi-66 srfi-69 srfi-74 srfi-89 srfi-94 srfi-96 srfi-100 srfi-113 srfi-117 srfi-127 srfi-128 srfi-129 srfi-130 srfi-132 srfi-133 srfi-134 srfi-135 srfi-137 srfi-141 srfi-144 srfi-151 srfi-156 srfi-158 srfi-161 srfi-170 srfi-171 srfi-173 srfi-174 srfi-175 srfi-180 srfi-185 srfi-189 srfi-190 srfi-196 srfi-207 srfi-214 srfi-216 srfi-217 srfi-223 .
For some SRFIs, STklos accepts that uses them with a name. This names
are given the table 3.
Symbol | require SRFI(s) |
lists | srfi-1 |
and-let* | srfi-2 |
hvectors | srfi-4 |
program | srfi-7 |
records | srfi-9 |
case-lambda | srfi-16 |
error | srfi-23 |
random | srfi-27 |
args-fold | srfi-37 |
parameters | srfi-39 |
streams | srfi-41 |
rest-list | srfi-51 |
formatting | srfi-54 |
testing | srfi-64 |
hash-tables | srfi-69 |
boxes | srfi-111 |
sets-bags | srfi-113 |
queues-as-lists | srfi-117 |
adjustable-strings | srfi-118 |
lazy-sequences | srfi-127 |
comparators-reduced | srfi-128 |
titlecase | srfi-129 |
sort | srfi-132 |
vector | srfi-133 |
immutable-deques | srfi-134 |
immutable-texts | srfi-135 |
integer-division | srfi-141 |
bitwise-ops | srfi-151 |
posix | srfi-170 |
transducers | srfi-171 |
hooks | srfi-173 |
posix-timespecs | srfi-174 |
ascii | srfi-175 |
json | srfi-180 |
maybe-either | srfi-189 |
conditions | srfi-35 srfi-36 |
generators | srfi-158 srfi-190 |
Fig. 3: Feature identifiers
Previous section described the general way to use the SRFIS implemented in
STklos. This section concentrates on information not given above.
srfi-0 -- Feature-based conditional expansion construct
SRFI-0 defines the cond-expand
special form. It is fully supported by STklos. STklos
defines several features identifiers which are of the form
srfi-n where n represents the number of the
SRFI supported by the implementation (for instance
srfi-1 or srfi-30). STklos cond-expand accepts also some
feature identifiers which are the same that the ones
defined in figure 3 Furthermore, the feature identifier stklos and STklos
are defined for applications which need to know on which Scheme implementation
they are running on.
srfi-10 -- Sharp Comma External Form
SRFI-10 is fully supported. This SRFI extends the
STklos reader with the "#, " notation which is fully described in
this document (see define-reader-ctor).
srfi-16 -- Syntax for procedures of variable arity
SRFI-16 is fully supported. Note case-lambda is now defined in R7RS.
srfi-17 -- Generalized set!
SRFI-17 is fully supported. See the documentation of procedures set!
and setter . However, requiring explicitly srfi-17 permits
to define the setters for the (numerous) cXXXXr list procedures.
srfi-22 -- Running Scheme Scripts on Unix
SRFI-22 describes basic prerequisites for
running Scheme programs as Unix scripts in a uniform
way. Specifically, it describes: - the syntax of Unix scripts written in Scheme,
- a uniform convention for calling the Scheme script interpreter,
and
- a method for accessing the Unix command line arguments from
within the Scheme script.
SRFI-22 recommends to invoke the Scheme script interpreter from the
script via a /usr/bin/env trampoline, like this:
#!/usr/bin/env <executable>
|
where <executable> can recover several specified names.
STklos uses only the name stklos-script for
<executable> . Here is an example of the classical echo
command (without option) in Scheme:
#!/usr/bin/env stklos-script
(define (main arguments)
(for-each (lambda (x) (display x) (display #space))
(cdr arguments))
(newline)
0)
|
srfi-23 -- Error reporting mechanism
SRFI-23 is fully supported. Note that the STklos error is more
general than the one defined in SRFI-23.
srfi-25 -- Multi-dimensional Arrays
SRFI-25 is fully supported.
STklos implements the arrays as defined in the SRFI document. All the forms
defined in the SRFI are implemented in STklos, but some other
functions, not present in the SRFI, are documented here.
(shape? obj) | STklos procedure |
Checks if obj is an array shape. SRFI-25 dictates that a
shape is an ordinary array, with rank two and shape (0 r 0 2) ,
where r is the rank of the array that the shape describes.
So, any array of shape (0 r 0 2 is a shape, for any non-negative
integer r . |
(shared-array? array) | STklos procedure |
Will return #t when the array has its data shared with other
arrays, and #f otherwise. |
(shape-for-each shape proc [index-object]) | STklos procedure |
This procedure will apply proc to all valid sequences of
indices in shape , in row-major order.
If index-object is not provided, then proc must accept
as many arguments as the number of dimensions that the shape
describes.
(shape-for-each (shape 1 3 10 12)
(lambda (x y)
(format #t "[~a ~a]~%" x y)))
[1 10]
[1 11]
[2 10]
[2 11]
|
If index-object is provided, it is used as a place to store the
indices, so proc must accept either a vector or an array (this is to
avoid pushing and popping too many values when calling proc ).
index-object , when present, must be aither a vector or array.
(let ((vec (make-vector 2 #f)))
(shape-for-each (shape 1 3 10 12)
(lambda (o)
(format #t "[~a ~a]~%"
(vector-ref o 0)
(vector-ref o 1)))
vec))
[1 10]
[1 11]
[2 10]
[2 11]
(let ((arr (make-array (shape 0 2))))
(shape-for-each (shape 1 3 10 12)
(lambda (o)
(format #t "[~a ~a]~%"
(array-ref o 0)
(array-ref o 1)))
arr))
[1 10]
[1 11]
[2 10]
[2 11]
|
|
(share-nths a d n) | STklos procedure |
Share-nths takes every n th slice along dimension d into a shared array.
This preserves the origin.
(define a (array (shape 0 4 0 4)
-1 -2 -3 -4
-5 -6 -7 -8
-9 -10 -11 -12
-13 -14 -15 -16))
(share-nths a 0 2)
⇒ #,(<array> (0 2 0 4) -1 -2 -3 -4
-9 -10 -11 -12)
(share-nths a 1 2)
⇒ #,(<array> (0 4 0 2) -1 -3 -5 -7
-9 -11 -13 -15)
|
|
(share-column arr k) | STklos procedure |
Shares whatever the second index is about. The result has one dimension less.
(define a (array (shape 0 2 0 2 0 2) -1 -2 -3 -4 -5 -6 -7 -8))
(share-column a 1) ⇒ #,(<array> (0 2 0 2) -3 -4 -7 -8)
(share-column a 0) ⇒ #,(<array> (0 2 0 2) -1 -2 -5 -6)
|
|
(share-row arr k) | STklos procedure |
Shares whatever the first index is about. The result has one dimension less.
(define a (array (shape 0 2 0 2 0 2) -1 -2 -3 -4 -5 -6 -7 -8))
(share-row a 0) ⇒ #,(<array> (0 2 0 2) -1 -2 -3 -4)
(share-row a 1) ⇒ #,(<array> (0 2 0 2) -5 -6 -7 -8)
|
|
(share-array/origin arr k ...) | STklos procedure |
(share-array/origin arr index)
change the origin of arr to k ..., with index a vector or zero-based
one-dimensional array that contains k ...
(define a (array (shape 0 2 0 2 ) -1 -2 -3 -4))
(share-array/origin a 1 1) ⇒ #,(<array> (1 3 1 3) -1 -2 -3 -4)
|
|
(array-copy+share array) | STklos procedure |
Returns a copy of array .
If array does not have its own internal data, but was built using
share-array, then the new array will be similar -- it will be a copy of
array, sharing the elements in the same way. |
(array-size array) | STklos procedure |
Returns the number of elements in array . |
(array-shape array) | STklos procedure |
Returns the shape of array . |
(array->list array) | STklos procedure |
Returns a list that contains a copy of the elements of array ,
in row-major order.
This is not recursive, and will not flatten the array. |
(array->vector array) | STklos procedure |
Returns a vector that contains a copy of the elements of array ,
in row-major order. The new vector does not share elements with
the original array (it is a fresh copy).
This is not recursive, and will not flatten the array. |
(array-length array dim) | STklos procedure |
Returns the length of dimension dim in array array . |
(array-map [shape] proc arr0 arr1 ...) | STklos procedure |
This procedure is similar to map for lists:
it will run proc on an element of each of the
arr0 , arr1 , ... arguments, storing the result in
the equivalent position of a newly created array.
The shapes of the arrays must be the same.
The procedure will create a new array with shape shape
(or arr0 's shape, if shape was not specified). |
(array-map! array [shape] proc arr0 arr1 ...) | STklos procedure |
For each valid index idx , applies proc to the corresponding
position in arr0 , arr1 , ... and then sets the same
place in array to the result.
If shape is specified, it should specify a subarray of
array , and only that section will be mapped. |
(array-append dim arr1 arr2 ...) | STklos procedure |
Appends arrays arr1 , arr2 , ... along the specified dimension dim .
The arrays must have equally many dimensions and all other dimensions
equally long.
(define a (array (shape 0 2 0 3) 11 22 33 44 55 66))
(define b (array (shape 0 3 0 3) -11 -22 -33 -44 -55 -66 -77 -88 -99))
(define c (array (shape 0 1 0 3) 'a 'b 'c))
(array-append 0 a b c) ⇒ #,(<array> (0 6 0 3)
11 22 33
44 55 66
-11 -22 -33
-44 -55 -66
-77 -88 -99
a b c)
|
|
(array-share-count array) | STklos procedure |
Returns the number of arrays that were built sharing array 's
elements through (share-array array shape proc) , and that were not
yet garbage collected.
Note that it may take a long time for an object to be garbage
collected automatically. It is possible to force a garbage
collection pass by calling (gc) , but even that does not guarantee that
a specific object will be collected. |
(array-copy array) | STklos procedure |
Returns a copy of array .
The new copy will have no data shared with any other array, even if the
argument array did. |
(array-for-each-index arr proc [index-object]) | STklos procedure |
Will loop through all valid indices of array , applying proc
to those indices.
If index-object is not provided, then proc must accept
as many arguments as the number of dimensions that the shape
describes.
If index-object is provided, it is used as a place to store the
indices, so proc must accept a vector or an array (this is to avoid
pushing and popping too many values when calling proc).
index-object , when present, must be aither a vector or array.
See the documentation of shape-for-each for more information
on index-object . |
(tabulate-array shape proc) | STklos procedure |
(tabulate-array shape proc idx)
Returns a new array of shape shape , populated according
to proc . Each valid index in shape is passed to proc ,
and the result is place in the according array position.
idx is an object that may be used to store the indices, and
it may be either a vector or an array. If it is not present, or
if it is #f , then an index vector will be created internally.
|
(array-retabulate! arr shp proc [index-object]) | STklos procedure |
Sets the elements of arr in shape to the value of proc at that
index, using index-object if provided. This is similar to
tabulate-array! , except that the array is given by the user.
(define arr (array (shape 0 2 0 2) 'a 'b 'c 'd))
(array-retabulate! arr (shape 0 2 0 2) (lambda (x y) (+ 1 x y)))
arr ⇒ #,(<array> (0 2 0 2) 1 2 2 3)
|
|
(transpose arr k ...) | STklos procedure |
Shares arr with permuted dimensions. Each dimension from 0
inclusive to rank exclusive must appear once in k ...
This is a generalized transpose. It can permute the dimensions any which
way. The permutation is provided by a permutation matrix: a square matrix
of zeros and ones, with exactly one one in each row and column, or a
permutation of the rows of an identity matrix; the size of the matrix
must match the number of dimensions of the array.
The default permutation is `( 0 1 , 1 0 ) of course, but any permutation
array can be specified, and the shape array of the original array is then
multiplied with it, and index column vectors of the new array with its
inverse, from left, to permute the rows appropriately.
(transpose (array (shape 0 4 0 4)
-1 -2 -3 -4
-5 -6 -7 -8
-9 -10 -11 -12
-13 -14 -15 -16))
⇒ #,(<array> (0 4 0 4)
-1 -5 -9 -13
-2 -6 -10 -14
-3 -7 -11 -15
-4 -8 -12 -16)
(transpose (array (shape 0 3 0 3 0 2)
-1 -2
-3 -4
-5 -6
-7 -8
-9 -10
-11 -12
-13 -14
-15 -16
-17 -18))
⇒ #,(<array> (0 2 0 3 0 3)
-1 -7 -13
-3 -9 -15
-5 -11 -17
-2 -8 -14
-4 -10 -16
-6 -12 -18)
|
|
srfi-28 -- Basic Format Strings
SRFI-28 is fully supported. Note that STklos format is more general
than the one defined this SRFI.
srfi-36 -- I/O Conditions
SRFI-36 is fully supported.
See section Predefined Conditions for the predefined conditions
and when it is required to load this file.
srfi-55 -- Require-extension
SRFI-55 is fully supported. Furthermore, STklos also accepts the symbols
defined in figure 3 in a
require-extension clause.
srfi-69 -- Basic Hash Tables
SRFI-69 is fully supported. Note that the default comparison function in STklos is eq? whereas it
is equal? for the SRFI. Furthermore the hash functions
defined in the SRFI are not defined by default in STklos. To have
a fully compliant SRFI-69 behaviour, you need use a require-feature
in your code.
srfi-88 -- Keyword Objects
SRFI-88 is fully supported. The only difference between the keywords defined in the SRFI document and the
STklos keywords is on the zero-length keyword: in STklos, the keyword
: is equivalent to the keyword ||:, whereas the srfi considers
that : is not a keyword but a symbol. |