STklos Reference Manual

14. SRFIs

Contents
| *Top*
1 | Introduction
2 | Expressions
3 | Program structure
4 | Standard Procedures
5 | Regular Expressions
6 | Pattern Matching
7 | Exceptions and Conditions
8 | STklos Object System
9 | Threads, Mutexes and Condition Variables
10 | Customizations
11 | The ScmPkg Package System
12 | Foreign Function Interface
13 | Using the SLIB package

14

SRFIs

14.1 | Supported SRFIs
14.2 | Using a SRFI
14.3 | Misc. Information

15 | Index
| Bibliography

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.

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

### 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 `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-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