STklos Reference Manual
14. SRFIs

Contents

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.

14.1 Supported SRFIs

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)

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 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 figure 3

14.2.1 Embedded SRFIs

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 .

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-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 .

14.2.3 SRFI features

For some SRFIs, STklos accepts that uses them with a name. This names are given the table 3.


Symbolrequire SRFI(s)
listssrfi-1
and-let*srfi-2
hvectorssrfi-4
programsrfi-7
recordssrfi-9
case-lambdasrfi-16
errorsrfi-23
randomsrfi-27
args-foldsrfi-37
parameterssrfi-39
streamssrfi-41
rest-listsrfi-51
formattingsrfi-54
testingsrfi-64
hash-tablessrfi-69
boxessrfi-111
sets-bagssrfi-113
queues-as-listssrfi-117
adjustable-stringssrfi-118
lazy-sequencessrfi-127
comparators-reducedsrfi-128
titlecasesrfi-129
sortsrfi-132
vectorsrfi-133
immutable-dequessrfi-134
immutable-textssrfi-135
integer-divisionsrfi-141
bitwise-opssrfi-151
posixsrfi-170
transducerssrfi-171
hookssrfi-173
posix-timespecssrfi-174
asciisrfi-175
jsonsrfi-180
maybe-eithersrfi-189
conditionssrfi-35 srfi-36
generatorssrfi-158 srfi-190
Fig. 3: Feature identifiers

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 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 nth 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-27 -- Source of random bits

SRFI-27 is fully supported. Using primitives random-integer or random-real automatically loadthis 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 Predefined Conditions 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 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.

srfi-145 -- Assumptions

SRFI-145 is fully supported. See the assume special form

srfi-169 -- Underscores in numbers

SRFI-169 is fully supported. See accept-srfi-169-numbers to eventually forbid the usage of underscores in numbers.


This Html page has been produced by Skribe.
Last update Wed Nov 24 17:57:15 2021