14. SRFIs
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.
14.1. Supported SRFIs
STklos supports 104 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 before use.
The following SRFIS are implemented:
- SRFI-0 — Feature-based conditional expansion construct
- SRFI-1 — List Library
- SRFI-2 — AND-LET*: an AND with local bindings, a guarded LET* special form
- SRFI-4 — Homogeneous numeric vector datatypes
- SRFI-5 — A compatible let form with signatures and rest arguments
- SRFI-6 — Basic String Ports
- SRFI-7 — Feature-based program configuration language
- SRFI-8 — Receive: Binding to multiple values
- SRFI-9 — Defining Record Types
- SRFI-10 — Sharp Comma External Form
- SRFI-11 — Syntax for receiving multiple values
- SRFI-13 — String Library
- SRFI-14 — Character-Set Library
- SRFI-15 — Syntax for dynamic scoping (withdrawn)
- SRFI-16 — Syntax for procedures of variable arity
- SRFI-17 — Generalized set!
- SRFI-18 — Multithreading support
- SRFI-22 — Running Scheme Scripts on Unix
- SRFI-23 — Error reporting mechanism
- SRFI-25 — Multi-dimensional Arrays
- SRFI-26 — Notation for Specializing Parameters without Currying
- SRFI-27 — Source of random bits
- SRFI-28 — Basic Format Strings
- SRFI-29 — Localization
- SRFI-30 — Nested Multi-line Comments
- SRFI-31 — A special form for recursive evaluation
- SRFI-34 — Exception Handling for Programs
- SRFI-35 — Conditions
- SRFI-36 — I/O Conditions
- SRFI-37 — args-fold: a program argument processor
- SRFI-38 — External representation of shared structures
- SRFI-39 — Parameters objects
- SRFI-41 — Streams
- SRFI-45 — Primitives for Expressing Iterative Lazy Algorithms
- SRFI-48 — Intermediate Format Strings
- SRFI-51 — Handling rest list
- SRFI-54 — Formatting
- SRFI-55 — Require-extension
- SRFI-59 — Vicinity
- SRFI-60 — Integers as bits
- SRFI-61 — A more general COND clause
- SRFI-62 — S-expression comments
- SRFI-64 — A Scheme API for test suites
- SRFI-66 — Octet Vectors
- SRFI-69 — Basic Hash Tables
- SRFI-70 — Numbers
- SRFI-74 — Octet-Addressed Binary Blocks
- SRFI-87 — ⇒ in case clauses
- SRFI-88 — Keyword Objects
- SRFI-89 — Optional Positional and Named Parameters
- SRFI-94 — Type-Restricted Numerical Functions
- SRFI-96 — SLIB Prerequisites
- SRFI-98 — Interface to access environment variables
- SRFI-100 — define-lambda-object
- SRFI-111 — Boxes
- SRFI-112 — Environment Inquiry
- SRFI-113 — Sets and Bags
- SRFI-117 — Queues based on lists
- SRFI-118 — Simple adjustable-size strings
- SRFI-127 — Lazy Sequences
- SRFI-128 — Comparators (reduced)
- SRFI-129 — Titlecase procedures
- SRFI-130 — Cursor-based string library
- SRFI-132 — Sort Libraries
- SRFI-133 — Vector Library (R7RS-compatible)
- SRFI-134 — Immutable Deques
- SRFI-135 — Immutable Texts
- SRFI-137 — Minimal Unique Types
- SRFI-138 — Compiling Scheme programs to executables
- SRFI-141 — Integer Division
- SRFI-143 — Fixnums
- SRFI-144 — Flonums
- SRFI-145 — Assumptions
- SRFI-151 — Bitwise Operations
- SRFI-154 — First-class dynamic extents
- SRFI-156 — Syntactic combiners for binary predicates
- SRFI-158 — Generators and Accumulators
- SRFI-161 — Unifiable Boxes
- SRFI-169 — Underscores in numbers
- SRFI-170 — POSIX API
- SRFI-171 — Transducers
- SRFI-173 — Hooks
- SRFI-174 — POSIX Timespecs
- SRFI-175 — ASCII character library
- SRFI-176 — Version flag
- SRFI-180 — JSON
- SRFI-185 — Linear adjustable-length strings
- SRFI-189 — Maybe and Either: optional container types
- SRFI-190 — Coroutines Generators
- SRFI-192 — Port Positioning
- SRFI-193 — Command line
- SRFI-195 — Multiple-value boxes
- SRFI-196 — Range Objects
- SRFI-207 — String-notated bytevectors
- SRFI-208 — NaN procedures
- SRFI-214 — Flexvectors
- SRFI-215 — Central Log Exchange
- SRFI-216 — SICP Prerequisites (Portable)
- SRFI-217 — Integer Sets
- SRFI-219 — Define higher-order lambda
- SRFI-223 — Generalized binary search procedures
- SRFI-224 — Integer Mappings
- SRFI-229 — Tagged Procedures
- SRFI-230 — Atomic Operations
14.2. Using a SRFI
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
(cond-expand
(srfi-n))
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 (List Library), the following forms are possible:
(require-feature 'srfi-1)
(require-feature "srfi-1")
(require-feature 1)
(require-feature 'lists) ;; Since this feature name is an alias for SRFI-1
The list of the aliases defined for the supported SRFIs is given in Table 2.
14.2.1. Embedded SRFIs
As said before, an 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-138
srfi-143
srfi-145
srfi-169
srfi-176
srfi-192
srfi-193
srfi-195
srfi-208
srfi-219
14.2.2. External SRFIs
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-154
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-215
srfi-216
srfi-217
srfi-223
srfi-224
srfi-229
srfi-230
14.2.3. SRFI features
For some SRFIs, STklos accepts that uses them with a name. This names are given Table 2.
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 |
14.3. Misc. Information
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 Table 2, such as
case_lambda or generators.
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 primitive define-reader-ctor
).
srfi-16 — Syntax for procedures of variable arity
SRFI-16 is fully supported. Note that 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 (Running Scheme Scripts on Unix) 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
STklos implements the arrays of SRFI-25. All the forms defined in the SRFI are implemented in STklos, but some other functions, not present in the SRFI, are documented here.
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
.
STklos procedure
Will return #t
when the array has its data shared with other
arrays, and #f
otherwise.
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]
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)
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)
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)
STklos procedure
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)
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.
STklos procedure
Returns the number of elements in array
.
STklos procedure
Returns the shape of 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.
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.
STklos procedure
Returns the length of dimension dim
in array array
.
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).
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.
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)
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.
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.
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
.
STklos procedure
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.
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)
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-27 — Source of random bits
SRFI-27 is fully supported. Using primitives
random-integer
or random-real
automatically load this SRFI.
srfi-28 — Basic Format Strings
SRFI-28 is fully supported. Note that STklos format
is more general than the one defined this SRFI.
srfi-35 — Conditions
SRFI-35 is fully supported. See Section 7.3 for the predefined conditions and when it is required to load this file.
srfi-36 — I/O Conditions
SRFI-36 is fully supported. See Section 7.3 Conditions) for the predefined conditions and when it is required to load this file.
srfi-55 — Require-extension
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: For STklos, :
is equivalent to the keyword #:||
,
whereas the SRFI considers that :
is not a keyword but a symbol.
To obtain the symbol : in STklos, you must use |:| .
|
srfi-138 — Compiling Scheme programs to executables
SRFI-138 is fully supported. The stklos-compile
program conforms to SRFI 138, accepting all the required command line
options.
The -D x flag of stklos-compile
will define a feature named x
for
use with cond-expand
in the compiled code only. It will not include
x
in the features list of the runtime.
srfi-145 — Assumptions
SRFI-145 is fully supported. See the
assume
special form.
srfi-169 — Underscores in numbers
SRFI-169 is fully supported. See parameter accept-srfi-169-numbers
to eventually forbid the usage of
underscores in numbers.