### 7.4 Standards Support ¶

#### 7.4.1 RnRS ¶

The `r2rs`, `r3rs`, `r4rs`, and `r5rs` features attempt to provide procedures and macros to bring a Scheme implementation to the desired version of Scheme.

Feature: r2rs ¶

  Requires features implementing procedures and optional procedures specified by Revised^2 Report on the Algorithmic Language Scheme; namely `rev3-procedures` and `rev2-procedures`.

Feature: r3rs ¶

  Requires features implementing procedures and optional procedures specified by Revised^3 Report on the Algorithmic Language Scheme; namely `rev3-procedures`.

  Note: SLIB already mandates the `r3rs` procedures which can be portably implemented in `r4rs` implementations.

Feature: r4rs ¶

  Requires features implementing procedures and optional procedures specified by Revised^4 Report on the Algorithmic Language Scheme; namely `rev4-optional-procedures`.

Feature: r5rs ¶

  Requires features implementing procedures and optional procedures specified by Revised^5 Report on the Algorithmic Language Scheme; namely `values`, `macro`, and `eval`.

#### 7.4.2 With-File ¶

`(require 'with-file)`

Function: with-input-from-file file thunk ¶
Function: with-output-to-file file thunk ¶

  Description found in R4RS.

#### 7.4.3 Transcripts ¶

`(require 'transcript)`

Function: transcript-on filename ¶
Function: transcript-off filename ¶

  Redefines `read-char`, `read`, `write-char`, `write`, `display`, and `newline`.

#### 7.4.4 Rev2 Procedures ¶

`(require 'rev2-procedures)`

The procedures below were specified in the Revised^2 Report on Scheme. N.B.: The symbols `1+` and `-1+` are not R4RS syntax. Scheme->C, for instance, chokes on this module.

Procedure: substring-move-left! string1 start1 end1 string2 start2 ¶
Procedure: substring-move-right! string1 start1 end1 string2 start2 ¶

  string1 and string2 must be a strings, and start1, start2 and end1 must be exact integers satisfying

      0 <= start1 <= end1 <= (string-length string1)
      0 <= start2 <= end1 - start1 + start2 <= (string-length string2)

  `substring-move-left!` and `substring-move-right!` store characters of string1 beginning with index start1 (inclusive) and ending with index end1 (exclusive) into string2 beginning with index start2 (inclusive).

  `substring-move-left!` stores characters in time order of increasing indices. `substring-move-right!` stores characters in time order of increasing indeces.

Procedure: substring-fill! string start end char ¶

  Fills the elements start–end of string with the character char.

Function: string-null? str ¶

  ≡ `(= 0 (string-length str))`

Procedure: append! pair1 … ¶

  Destructively appends its arguments. Equivalent to `nconc`.

Function: 1+ n ¶

  Adds 1 to n.

Function: -1+ n ¶

  Subtracts 1 from n.

Function: <? ¶
Function: <=? ¶
Function: =? ¶
Function: >? ¶
Function: >=? ¶

  These are equivalent to the procedures of the same name but without the trailing ‘`?`’.

#### 7.4.5 Rev4 Optional Procedures ¶

`(require 'rev4-optional-procedures)`

For the specification of these optional procedures, See Standard procedures in Revised(4) Scheme.

Function: list-tail l p ¶

Function: string-copy ¶

Procedure: string-fill! s obj ¶

Procedure: vector-fill! s obj ¶

#### 7.4.6 Multi-argument / and - ¶

`(require 'multiarg/and-)`

For the specification of these optional forms, See Numerical operations in Revised(4) Scheme.

Function: / dividend divisor1 … ¶

Function: - minuend subtrahend1 … ¶

#### 7.4.7 Multi-argument Apply ¶

`(require 'multiarg-apply)`

For the specification of this optional form, See Control features in Revised(4) Scheme.

Function: apply proc arg1 … ¶

#### 7.4.8 Rationalize ¶

`(require 'rationalize)`

Function: rationalize x e ¶

  Computes the correct result for exact arguments (provided the implementation supports exact rational numbers of unlimited precision); and produces a reasonable answer for inexact arguments when inexact arithmetic is implemented using floating-point.

`Rationalize` has limited use in implementations lacking exact (non-integer) rational numbers. The following procedures return a list of the numerator and denominator.

Function: find-ratio x e ¶

  `find-ratio` returns the list of the simplest numerator and denominator whose quotient differs from x by no more than e.

      (find-ratio 3/97 .0001)             ⇒ (3 97)
      (find-ratio 3/97 .001)              ⇒ (1 32)

Function: find-ratio-between x y ¶

  `find-ratio-between` returns the list of the simplest numerator and denominator between x and y.

      (find-ratio-between 2/7 3/5)        ⇒ (1 2)
      (find-ratio-between -3/5 -2/7)      ⇒ (-1 2)

#### 7.4.9 Promises ¶

`(require 'promise)`

Function: make-promise proc ¶

Function: force promise ¶

`(require 'delay)` provides `force` and `delay`:

Macro: delay obj ¶

  Change occurrences of `(delay expression)` to

      (make-promise (lambda () expression))

(see Control features in Revised(4) Scheme).

#### 7.4.10 Dynamic-Wind ¶

`(require 'dynamic-wind)`

This facility is a generalization of Common LISP `unwind-protect`, designed to take into account the fact that continuations produced by `call-with-current-continuation` may be reentered.

Procedure: dynamic-wind thunk1 thunk2 thunk3 ¶

  The arguments thunk1, thunk2, and thunk3 must all be procedures of no arguments (thunks).

  `dynamic-wind` calls thunk1, thunk2, and then thunk3. The value returned by thunk2 is returned as the result of `dynamic-wind`. thunk3 is also called just before control leaves the dynamic context of thunk2 by calling a continuation created outside that context. Furthermore, thunk1 is called before reentering the dynamic context of thunk2 by calling a continuation created inside that context. (Control is inside the context of thunk2 if thunk2 is on the current return stack).

  Warning: There is no provision for dealing with errors or interrupts. If an error or interrupt occurs while using `dynamic-wind`, the dynamic environment will be that in effect at the time of the error or interrupt.

#### 7.4.11 Eval ¶

`(require 'eval)`

Function: eval expression environment-specifier ¶

  Evaluates expression in the specified environment and returns its value. Expression must be a valid Scheme expression represented as data, and environment-specifier must be a value returned by one of the three procedures described below. Implementations may extend `eval` to allow non-expression programs (definitions) as the first argument and to allow other values as environments, with the restriction that `eval` is not allowed to create new bindings in the environments associated with `null-environment` or `scheme-report-environment`.

      (eval '(* 7 3) (scheme-report-environment 5))
                                                         ⇒  21

      (let ((f (eval '(lambda (f x) (f x x))
                     (null-environment))))
        (f + 10))
                                                         ⇒  20

Function: scheme-report-environment version ¶
Function: null-environment version ¶
Function: null-environment ¶

  Version must be an exact non-negative integer n corresponding to a version of one of the Revised^n Reports on Scheme. `Scheme-report-environment` returns a specifier for an environment that contains the set of bindings specified in the corresponding report that the implementation supports. `Null-environment` returns a specifier for an environment that contains only the (syntactic) bindings for all the syntactic keywords defined in the given version of the report.

  Not all versions may be available in all implementations at all times. However, an implementation that conforms to version n of the Revised^n Reports on Scheme must accept version n. An error is signalled if the specified version is not available.

  The effect of assigning (through the use of `eval`) a variable bound in a `scheme-report-environment` (for example `car`) is unspecified. Thus the environments specified by `scheme-report-environment` may be immutable.

Function: interaction-environment ¶

  This optional procedure returns a specifier for the environment that contains implementation-defined bindings, typically a superset of those listed in the report. The intent is that this procedure will return the environment in which the implementation would evaluate expressions dynamically typed by the user.

Here are some more `eval` examples:

    (require 'eval)
    ⇒ #<unspecified>
    (define car 'volvo)
    ⇒ #<unspecified>
    car
    ⇒ volvo
    (eval 'car (interaction-environment))
    ⇒ volvo
    (eval 'car (scheme-report-environment 5))
    ⇒ #<primitive-procedure car>
    (eval '(eval 'car (interaction-environment))
          (scheme-report-environment 5))
    ⇒ volvo
    (eval '(eval '(set! car 'buick) (interaction-environment))
          (scheme-report-environment 5))
    ⇒ #<unspecified>
    car
    ⇒ buick
    (eval 'car (scheme-report-environment 5))
    ⇒ #<primitive-procedure car>
    (eval '(eval 'car (interaction-environment))
          (scheme-report-environment 5))
    ⇒ buick

#### 7.4.12 Values ¶

`(require 'values)`

Function: values obj … ¶

  `values` takes any number of arguments, and passes (returns) them to its continuation.

Function: call-with-values thunk proc ¶

  thunk must be a procedure of no arguments, and proc must be a procedure. `call-with-values` calls thunk with a continuation that, when passed some values, calls proc with those values as arguments.

  Except for continuations created by the `call-with-values` procedure, all continuations take exactly one value, as now; the effect of passing no value or more than one value to continuations that were not created by the `call-with-values` procedure is unspecified.

#### 7.4.13 SRFI ¶

`(require 'srfi)`

Implements Scheme Request For Implementation (SRFI) as described at http://srfi.schemers.org/

Macro: cond-expand <clause1> <clause2> … ¶

  Syntax: Each <clause> should be of the form

      (<feature> <expression1> ...)

  where <feature> is a boolean expression composed of symbols and ‘and’, ‘or’, and ‘not’ of boolean expressions. The last <clause> may be an “else clause,” which has the form

      (else <expression1> <expression2> ...).

  The first clause whose feature expression is satisfied is expanded. If no feature expression is satisfied and there is no else clause, an error is signaled.

  SLIB `cond-expand` is an extension of SRFI-0, http://srfi.schemers.org/srfi-0/srfi-0.html.

- SRFI-2 Guarded LET* special form
- SRFI-8 Binding to multiple values
- SRFI-9 Define-Record-Type
- SRFI-11 Binding to multiple values
- SRFI-23 `(define error slib:error)`
- SRFI-28 Format (version 3.1)
- SRFI-39 Parameter Objects
- SRFI-47 Arrays
- SRFI-59 Vicinity
- SRFI-60 Bit-Twiddling
- SRFI-61 Guarded COND Clause
- SRFI-63 Arrays
- SRFI-94 Irrational Integer Functions and Irrational Real Functions
- SRFI-95 Sorting
- SRFI-96 Universal SLIB Procedures

#### 7.4.13.1 SRFI-1 ¶

`(require 'srfi-1)`

Implements the SRFI-1 list-processing library as described at http://srfi.schemers.org/srfi-1/srfi-1.html

#### Constructors ¶

Function: xcons d a ¶

  `(define (xcons d a) (cons a d))`.

Function: list-tabulate len proc ¶

  Returns a list of length len. Element i is `(proc i)` for 0 <= i < len.

Function: cons* obj1 obj2 ¶

Function: list-copy flist ¶

Function: iota count start step ¶
Function: iota count start ¶
Function: iota count ¶

  Returns a list of count numbers: (start, start+step, …, start+(count-1)*step).

Function: circular-list obj1 obj2 … ¶

  Returns a circular list of obj1, obj2, ….

#### Predicates ¶

Function: proper-list? obj ¶

Function: circular-list? x ¶

Function: dotted-list? obj ¶

Function: null-list? obj ¶

Function: not-pair? obj ¶

Function: list= =pred list … ¶

#### Selectors ¶

Function: first pair ¶

Function: second pair ¶

Function: third pair ¶

Function: fourth pair ¶

Function: fifth pair ¶
Function: sixth pair ¶
Function: seventh pair ¶
Function: eighth pair ¶
Function: ninth pair ¶
Function: tenth pair ¶

Function: car+cdr pair ¶

Function: drop lst k ¶
Function: take lst k ¶
Function: take! lst k ¶

Function: take-right lst k ¶

Function: drop-right lst k ¶

Procedure: drop-right! lst k ¶

Function: split-at lst k ¶
Function: split-at! lst k ¶

Function: last lst k … ¶

#### Miscellaneous ¶

Function: length+ clist ¶

Function: concatenate lists ¶
Function: concatenate! lists ¶

Procedure: reverse! lst ¶

Function: append-reverse rev-head tail ¶
Function: append-reverse! rev-head tail ¶

Function: zip list1 list2 … ¶

Function: unzip1 lst ¶
Function: unzip2 lst ¶
Function: unzip3 lst ¶
Function: unzip4 lst ¶
Function: unzip5 lst ¶

Function: count pred list1 list2 … ¶

#### Fold and Unfold ¶

Function: fold kons knil clist1 clist2 … ¶

Function: fold-right kons knil clist1 clist2 … ¶

Function: pair-fold kons knil clist1 clist2 … ¶

Function: pair-fold-right kons knil clist1 clist2 … ¶

Function: reduce arg … ¶

Procedure: map! f clist1 clist2 … ¶

Function: pair-for-each f clist1 clist2 … ¶

#### Filtering and Partitioning ¶

Function: filter pred list ¶

Procedure: filter! pred list ¶

Function: partition pred list ¶

Function: remove pred list ¶

Procedure: partition! pred list ¶

Procedure: remove! pred list ¶

#### Searching ¶

Function: find pred clist ¶

Function: find-tail pred clist ¶

Function: span pred list ¶

Procedure: span! pred list ¶

Function: break pred list ¶

Procedure: break! pred list ¶

Function: any pred clist1 clist2 … ¶

Function: list-index pred clist1 clist2 … ¶

Function: member obj list = ¶
Function: member obj list ¶

#### Deleting ¶

Function: delete-duplicates x list = ¶
Function: delete-duplicates x list ¶

Procedure: delete-duplicates! x list = ¶
Procedure: delete-duplicates! x list ¶

#### Association lists ¶

Function: assoc obj alist pred ¶
Function: assoc obj alist ¶

Function: alist-cons key datum alist ¶

Function: alist-copy alist ¶

Function: alist-delete key alist = ¶
Function: alist-delete key alist ¶

Procedure: alist-delete! key alist = ¶
Procedure: alist-delete! key alist ¶

#### Set operations ¶

Function: lset<= = list1 … ¶

  Determine if a transitive subset relation exists between the lists list1 …, using = to determine equality of list members.

Function: lset= = list1 list2 … ¶

Function: lset-adjoin list elt1 … ¶

Function: lset-union = list1 … ¶

Function: lset-intersection = list1 list2 … ¶

Function: lset-difference = list1 list2 … ¶

Function: lset-xor = list1 … ¶

Function: lset-diff+intersection = list1 list2 … ¶

These are linear-update variants. They are allowed, but not required, to use the cons cells in their first list parameter to construct their answer. `lset-union!` is permitted to recycle cons cells from any of its list arguments.

Procedure: lset-intersection! = list1 list2 … ¶

Procedure: lset-difference! = list1 list2 … ¶

Procedure: lset-union! = list1 … ¶

Procedure: lset-xor! = list1 … ¶

Procedure: lset-diff+intersection! = list1 list2 … ¶