STklos Reference Manual
4. Standard Procedures


Contents

4.1 Equivalence predicates

A predicate is a procedure that always returns a boolean value (#t or #f). An equivalence predicate is the computational analogue of a mathematical equivalence relation (it is symmetric, reflexive, and transitive). Of the equivalence predicates described in this section, eq? is the finest or most discriminating, and equal? is the coarsest. Eqv? is slightly less discriminating than eq?.


(eqv? obj1 obj2)R5RS procedure

The eqv? procedure defines a useful equivalence relation on objects. Briefly, it returns #t if obj1 and obj2 should normally be regarded as the same object. This relation is left slightly open to interpretation, but the following partial specification of eqv? holds for all implementations of Scheme. The eqv? procedure returns #t if:
  • obj1 and obj2 are both #t or both #f.
  • obj1 and obj2 are both symbols and
    (string=? (symbol->string obj1)
              (symbol->string obj2))
                         ⇒  #t
    
    Note: This assumes that neither obj1 nor obj2 is an "uninterned symbol".
  • obj1 and obj2 are both keywords and
    (string=? (keyword->string obj1)
              (keyword->string obj2))
                         ⇒  #t
    
  • obj1 and obj2 are both numbers, are numerically equal (see -), and are either both exact or both inexact.
  • obj1 and obj2 are both characters and are the same character according to the char=? procedure (see char--).
  • both obj1 and obj2 are the empty list.
  • obj1 and obj2 are pairs, vectors, or strings that denote the same locations in the store.
  • obj1 and obj2 are procedures whose location tags are equal.
Note: STklos extends R5RS eqv? to take into account the keyword type.

Here are some examples:
(eqv? 'a 'a)                     ⇒  #t
(eqv? 'a 'b)                     ⇒  #f
(eqv? 2 2)                       ⇒  #t
(eqv? :foo :foo)                 ⇒  #t
(eqv? :foo :bar)                 ⇒  #f
(eqv? '() '())                   ⇒  #t
(eqv? 100000000 100000000)       ⇒  #t
(eqv? (cons 1 2) (cons 1 2))     ⇒  #f
(eqv? (lambda () 1)
      (lambda () 2))             ⇒  #f
(eqv? #f 'nil)                   ⇒  #f
(let ((p (lambda (x) x)))
  (eqv? p p))                    ⇒  #t
The following examples illustrate cases in which the above rules do not fully specify the behavior of eqv?. All that can be said about such cases is that the value returned by eqv? must be a boolean.
(eqv? "" "")             ⇒  unspecified
(eqv? '#() '#())         ⇒  unspecified
(eqv? (lambda (x) x)
      (lambda (x) x))    ⇒  unspecified
(eqv? (lambda (x) x)
      (lambda (y) y))    ⇒  unspecified
Note: In fact, the value returned by STklos depends of the way code is entered and can yield #t in some cases and #f in others.

See R5RS for more details on eqv?.

(eq? obj1 obj2)R5RS procedure

Eq? is similar to eqv? except that in some cases it is capable of discerning distinctions finer than those detectable by eqv?.

Eq? and eqv? are guaranteed to have the same behavior on symbols, keywords, booleans, the empty list, pairs, procedures, and non-empty strings and vectors. Eq?'s behavior on numbers and characters is implementation-dependent, but it will always return either true or false, and will return true only when eqv? would also return true. Eq? may also behave differently from eqv? on empty vectors and empty strings.

Note: STklos extends R5RS eq? to take into account the keyword type.

Note: In STklos, comparison of character returns #t for identical characters and #f otherwise.
 
(eq? 'a 'a)                     ⇒  #t
(eq? '(a) '(a))                 ⇒  unspecified
(eq? (list 'a) (list 'a))       ⇒  #f
(eq? "a" "a")                   ⇒  unspecified
(eq? "" "")                     ⇒  unspecified
(eq? :foo :foo)                 ⇒  #t
(eq? :foo :bar)                 ⇒  #f
(eq? '() '())                   ⇒  #t
(eq? 2 2)                       ⇒  unspecified
(eq? #\A #\A)                   ⇒  #t (unspecified in R5RS)
(eq? car car)                   ⇒  #t
(let ((n (+ 2 3)))
  (eq? n n))                    ⇒  #t (unspecified in R5RS)
(let ((x '(a)))
  (eq? x x))                    ⇒  #t
(let ((x '#()))
  (eq? x x))                    ⇒  #t
(let ((p (lambda (x) x)))
  (eq? p p))                    ⇒  #t
(eq? :foo :foo)                 ⇒  #t
(eq? :bar bar:)                 ⇒  #t
(eq? :bar :foo)                 ⇒  #f

(equal? obj1 obj2)R5RS procedure

Equal? recursively compares the contents of pairs, vectors, and strings, applying eqv? on other objects such as numbers and symbols. A rule of thumb is that objects are generally equal? if they print the same. Equal? may fail to terminate if its arguments are circular data structures.
(equal? 'a 'a)                  ⇒  #t
(equal? '(a) '(a))              ⇒  #t
(equal? '(a (b) c)
        '(a (b) c))             ⇒  #t
(equal? "abc" "abc")            ⇒  #t
(equal? 2 2)                    ⇒  #t
(equal? (make-vector 5 'a)
        (make-vector 5 'a))     ⇒  #t

4.2 Numbers

R5RS description of numbers is quite long and will not be given here. STklos support the full number tower as described in R5RS; see this document for a complete description.

STklos extends the number syntax of R5RS with the following inexact numerical constants: +inf.0 (infinity), -inf.0 (negative infinity), +nan.0 (not a number), and -nan.0 (same as +nan.0).


(number? obj)R5RS procedure
(complex? obj)
(real? obj)
(rational? obj)
(integer? obj)

These numerical type predicates can be applied to any kind of argument, including non-numbers. They return #t if the object is of the named type, and otherwise they return #f. In general, if a type predicate is true of a number then all higher type predicates are also true of that number. Consequently, if a type predicate is false of a number, then all lower type predicates are also false of that number. If z is an inexact complex number, then (real? z) is true if and only if (zero? (imag-part z)) is true. If x is an inexact real number, then (integer? x) is true if and only if (and (finite? x) (= x (round x)))
  (complex? 3+4i)         ⇒  #t
  (complex? 3)            ⇒  #t
  (real? 3)               ⇒  #t
  (real? -2.5+0.0i)       ⇒  #t
  (real? #e1e10)          ⇒  #t
  (rational? 6/10)        ⇒  #t
  (rational? 6/3)         ⇒  #t
  (integer? 3+0i)         ⇒  #t
  (integer? 3.0)          ⇒  #t
  (integer? 3.2)          ⇒  #f
  (integer? 8/4)          ⇒  #t
  (integer? "no")         ⇒  #f
  (complex? +inf.0)       ⇒  #t
  (real? -inf.0)          ⇒  #t
  (rational? +inf.0)      ⇒  #f
  (integer? -inf.0)       ⇒  #f

(exact? z)R5RS procedure
(inexact? z)

These numerical predicates provide tests for the exactness of a quantity. For any Scheme number, precisely one of these predicates is true.

(bignum? x)STklos procedure

This predicates returns #t if x is an integer number too large to be represented with a native integer.
(bignum? (expt 2 300))     ⇒ #t   (very likely)
(bignum? 12)               ⇒ #f
(bignum? "no")             ⇒ #f

(= z1 z2 z3 ...)R5RS procedure
(< x1 x2 x3 ...)
(> x1 x2 x3 ...)
(<= x1 x2 x3 ...)
(>= x1 x2 x3 ...)

These procedures return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing.
(= +inf.0 +inf.0)           ⇒  #t
(= -inf.0 +inf.0)           ⇒  #f
(= -inf.0 -inf.0)           ⇒  #t


For any finite real number x:

(< -inf.0 x +inf.0) ⇒ #t (> +inf.0 x -inf.0) ⇒ #t

(finite? z)R5RS procedure
(infinite? z)
(zero? z)
(positive? x)
(negative? x)
(odd? n)
(even? n)

These numerical predicates test a number for a particular property, returning #t or #f.
(positive? +inf.0)          =⇒  #t
(negative? -inf.0)          =⇒  #t
(finite? -inf.0)            =⇒  #f
(infinite? +inf.0)          =⇒  #t

(max x1 x2 ...)R5RS procedure
(min x1 x2 ...)

These procedures return the maximum or minimum of their arguments.
(max 3 4)              ⇒  4    ; exact
(max 3.9 4)            ⇒  4.0  ; inexact
For any real number x:
(max +inf.0 x)         ⇒  +inf.0
(min -inf.0 x)         ⇒  -inf.0


Note: If any argument is inexact, then the result will also be inexact

(+ z1 ...)R5RS procedure
(* z1 ...)

These procedures return the sum or product of their arguments.
(+ 3 4)                 ⇒  7
(+ 3)                   ⇒  3
(+)                     ⇒  0
(+ +inf.0 +inf.0)       ⇒  +inf.0
(+ +inf.0 -inf.0)       ⇒  +nan.0
(* 4)                   ⇒  4
(*)                     ⇒  1
(* 5 +inf.0)            ⇒  +inf.0
(* -5 +inf.0)           ⇒  -inf.0
(* +inf.0 +inf.0)       ⇒  +inf.0
(* +inf.0 -inf.0)       ⇒  -inf.0
(* 0 +inf.0)            ⇒  +nan.0
Note: For any finite number z:
(+ +inf.0 z)            ⇒  +inf.0
(+ -inf.0 z)            ⇒  -inf.0

(- z)R5RS procedure
(- z1 z2)
(/ z)
(/ z1 z2 ...)

With two or more arguments, these procedures return the difference or quotient of their arguments, associating to the left. With one argument, however, they return the additive or multiplicative inverse of their argument.
(- 3 4)                 ⇒  -1
(- 3 4 5)               ⇒  -6
(- 3)                   ⇒  -3
(- +inf.0 +inf.0)       ⇒ +nan.0
(/ 3 4 5)               ⇒  3/20
(/ 3)                   ⇒  1/3
(/ 0.0)                 ⇒ +inf.0
(/ 0)                   ⇒ error (division by 0)

(abs x)R5RS procedure

Abs returns the absolute value of its argument.
(abs -7)                ⇒  7
(abs -inf.0)            ⇒ +inf.0

(quotient n1 n2)R5RS procedure
(remainder n1 n2)
(modulo n1 n2)

These procedures implement number-theoretic (integer) division. n2 should be non-zero. All three procedures return integers.

If n1/n2 is an integer:
(quotient n1 n2)   ⇒ n1/n2
(remainder n1 n2)  ⇒ 0
(modulo n1 n2)     ⇒ 0
If n1/n2 is not an integer:
(quotient n1 n2)   ⇒ nq
(remainder n1 n2)  ⇒ nr
(modulo n1 n2)     ⇒ nm
where nq is n1/n2 rounded towards zero, 0 < abs(nr) < abs(n2), 0 < abs(nm) < abs(n2), nr and nm differ from n1 by a multiple of n2, nr has the same sign as n1, and nm has the same sign as n2.

From this we can conclude that for integers n1 and n2 with n2 not equal to 0,
 (= n1 (+ (* n2 (quotient n1 n2))
          (remainder n1 n2)))   ⇒  #t
provided all numbers involved in that computation are exact.
(modulo 13 4)           ⇒  1
(remainder 13 4)        ⇒  1

(modulo -13 4)          ⇒  3
(remainder -13 4)       ⇒  -1

(modulo 13 -4)          ⇒  -3
(remainder 13 -4)       ⇒  1

(modulo -13 -4)         ⇒  -1
(remainder -13 -4)      ⇒  -1

(remainder -13 -4.0)    ⇒  -1.0  ; inexact

(gcd n1 ...)R5RS procedure
(lcm n1 ...)

These procedures return the greatest common divisor or least common multiple of their arguments. The result is always non-negative.
(gcd 32 -36)            ⇒  4
(gcd)                   ⇒  0
(lcm 32 -36)            ⇒  288
(lcm 32.0 -36)          ⇒  288.0  ; inexact
(lcm)                   ⇒  1

(numerator q)R5RS procedure
(denominator q)

These procedures return the numerator or denominator of their argument; the result is computed as if the argument was represented as a fraction in lowest terms. The denominator is always positive. The denominator of 0 is defined to be 1.
(numerator (/ 6 4))  ⇒  3
(denominator (/ 6 4))  ⇒  2
(denominator
(exact->inexact (/ 6 4))) ⇒ 2.0

(floor x)R5RS procedure
(ceiling x)
(truncate x)
(round x)

These procedures return integers. Floor returns the largest integer not larger than x. Ceiling returns the smallest integer not smaller than x. Truncate returns the integer closest to x whose absolute value is not larger than the absolute value of x. Round returns the closest integer to x, rounding to even when x is halfway between two integers.

Rationale: Round rounds to even for consistency with the default rounding mode specified by the IEEE floating point standard.

Note: If the argument to one of these procedures is inexact, then the result will also be inexact. If an exact value is needed, the result should be passed to the inexact->exact procedure.
(floor -4.3)          ⇒  -5.0
(ceiling -4.3)        ⇒  -4.0
(truncate -4.3)       ⇒  -4.0
(round -4.3)          ⇒  -4.0

(floor 3.5)           ⇒  3.0
(ceiling 3.5)         ⇒  4.0
(truncate 3.5)        ⇒  3.0
(round 3.5)           ⇒  4.0  ; inexact

(round 7/2)           ⇒  4    ; exact
(round 7)             ⇒  7

(rationalize x y)R5RS procedure

Rationalize returns the simplest rational number differing from x by no more than y. A rational number r1 is simpler than another rational number r2 if r1 = p1/q1 and r2 = p2/q2 (in lowest terms) and abs(p1) <= abs(p2) and abs(q1) <= abs(q2). Thus 3/5 is simpler than 4/7. Although not all rationals are comparable in this ordering (consider 2/7 and 3/5) any interval contains a rational number that is simpler than every other rational number in that interval (the simpler 2/5 lies between 2/7 and 3/5). Note that 0 = 0/1 is the simplest rational of all.
(rationalize
   (inexact->exact .3) 1/10)  ⇒ 1/3    ; exact
(rationalize .3 1/10)         ⇒ #i1/3  ; inexact

(exp z)R5RS procedure
(log z)
(sin z)
(cos z)
(tan z)
(asin z)
(acos z)
(atan z)
(atan y x)

These procedures compute the usual transcendental functions. Log computes the natural logarithm of z (not the base ten logarithm). Asin, acos, and atan compute arcsine, arccosine, and arctangent, respectively. The two-argument variant of atan computes
(angle (make-rectangular x y))
When it is possible these procedures produce a real result from a real argument.

(sqrt z)R5RS procedure

Returns the principal square root of z. The result will have either positive real part, or zero real part and non-negative imaginary part.

(expt z1 z2)R5RS procedure

Returns z1 raised to the power z2.

Note: 0z is 1 if z = 0 and 0 otherwise.

(make-rectangular x1 x2)R5RS procedure
(make-polar x3 x)
(real-part z)
(imag-part z)
(magnitude z)
(angle z)

If x1, x2, x3, and x4 are real numbers and z is a complex number such that

z = x1 + x2.i = x3 . ei.x4

Then
(make-rectangular x1 x2)       ⇒ z
(make-polar x3 x4)             ⇒ z
(real-part z)                  ⇒ x1
(imag-part z)                  ⇒ x2
(magnitude z)                  ⇒ abs(x3)
(angle z)                      ⇒ xa
where -π < xa <= π with xa = x4 + 2πn for some integer n.
 
(angle +inf.0)                 ⇒ 0.0
(angle -inf.0)                 ⇒ 3.14159265358979


Note: Magnitude is the same as abs for a real argument.

(exact->inexact z)R5RS procedure
(inexact->exact z)

Exact->inexact returns an inexact representation of z. The value returned is the inexact number that is numerically closest to the argument. Inexact->exact returns an exact representation of z. The value returned is the exact number that is numerically closest to the argument.

(number->string z)R5RS procedure
(number->string z radix)

Radix must be an exact integer, either 2, 8, 10, or 16. If omitted, radix defaults to 10. The procedure number->string takes a number and a radix and returns as a string an external representation of the given number in the given radix such that
(let ((number number)
      (radix radix))
  (eqv? number
       (string->number (number->string number radix) radix)))
is true. It is an error if no possible result makes this expression true.

If z is inexact, the radix is 10, and the above expression can be satisfied by a result that contains a decimal point, then the result contains a decimal point and is expressed using the minimum number of digits (exclusive of exponent and trailing zeroes) needed to make the above expression true; otherwise the format of the result is unspecified.

The result returned by number->string never contains an explicit radix prefix.

Note: The error case can occur only when z is not a complex number or is a complex number with a non-rational real or imaginary part.

Rationale: If z is an inexact number represented using flonums, and the radix is 10, then the above expression is normally satisfied by a result containing a decimal point. The unspecified case allows for infinities, NaNs, and non-flonum representations.

(string->number string)R5RS procedure
(string->number string radix)

Returns a number of the maximally precise representation expressed by the given string. Radix must be an exact integer, either 2, 8, 10, or 16. If supplied, radix is a default radix that may be overridden by an explicit radix prefix in string (e.g. "#o177"). If radix is not supplied, then the default radix is 10. If string is not a syntactically valid notation for a number, then string->number returns #f.
(string->number "100")        ⇒  100
(string->number "100" 16)     ⇒  256
(string->number "1e2")        ⇒  100.0
(string->number "15##")       ⇒  1500.0
(string->number "+inf.0")     ⇒  +inf.0
(string->number "-inf.0")     ⇒  -inf.0  

(bit-and n1 n2 ...)STklos procedure
(bit-or n1 n2 ...)
(bit-xor n1 n2 ...)
(bit-not n)
(bit-shift n m)

These procedures allow the manipulation of integers as bit fields. The integers can be of arbitrary length. Bit-and, bit-or and bit-xor respectively compute the bitwise and, inclusive and exclusive or. bit-not eturns the bitwise not of n. bit-shift returns the bitwise shift of n. The integer n is shifted left by m bits; If m is negative, n is shifted right by -m bits.
(bit-or 5 3)       ⇒ 7
(bit-xor 5 3)      ⇒ 6
(bit-and 5 3)      ⇒ 1 
(bit-not 5)        ⇒ -6
(bit-or 1 2 4 8)   ⇒ 15
(bit-shift 5 3)    ⇒ 40
(bit-shift 5 -1)   ⇒ 2

(random-integer n)STklos procedure

Return an integer in the range [0, ..., n[. Subsequent results of this procedure appear to be independent uniformly distributed over the range [0, ..., n[. The argument n must be a positive integer, otherwise an error is signaled. This function is equivalent to the eponym function of SRFI-27 (see SRFI-27 (Source of random bits) definition for more details).

(random-real)STklos procedure

Return a real number r such that 0 < r < 1. Subsequent results of this procedure appear to be independent uniformly distributed. This function is equivalent to the eponym function of SRFI-27 (see SRFI-27 (Source of random bits) definition for more details).

(decode-float n)STklos procedure

decode-float returns three exact integers: significand, exponent and sign (where -1 <= sign <= 1). The values returned by decode-float satisfy:
n = (* sign significand (expt 2 exponent))
Here is an example of decode-float usage.
(receive l (decode-float -1.234) l)
                    ⇒ (5557441940175192 -52 -1)
(exact->inexact (* -1 
                    5557441940175192 
                    (expt 2 -52))
                    ⇒ -1.234

4.2.1 Fixnums

STklos defines small integers as fixnums. Operations on fixnums are generally faster than operations which accept general numbers. Fixnums operations, as described below, may produce results which are incorrect if some temporary computation falls outside the range of fixnum. These functions should be used only when speed really matters.


(fixnum? obj)STklos procedure

Returns #t if obj is an exact integer within the fixnum range, #f otherwise.

(fixnum-width)STklos procedure

Returns the number of bits used to represent a fixnum number

(least-fixnum)STklos procedure
(greatest-fixnum)

These procedures return the minimum value and the maximum value of the fixnum range.

(fx+ fx1 fx2)STklos procedure
(fx- fx1 fx2)
(fx* fx1 fx2)
(fxdiv fx1 fx2)
(fxrem fx1 fx2)
(fxmod fx1 fx2)
(fx- fx)

These procedures compute (respectively) the sum, the difference, the product, the quotient and the remainder and modulp of the fixnums fx1 and fx2. The call of fx- with one parameter fx computes the opposite of fx.

(fx< fx1 fx2)STklos procedure
(fx<= fx1 fx2)
(fx> fx1 fx2)
(fx>= fx1 fx2)
(fx= fx1 fx2)

These procedures compare the fixnums fx1 and fx2 and retun #t if the comparison is true and #f otherwise.

4.3 Booleans

Of all the standard Scheme values, only #f counts as false in conditional expressions. Except for #f, all standard Scheme values, including #t, pairs, the empty list, symbols, numbers, strings, vectors, and procedures, count as true.

Boolean constants evaluate to themselves, so they do not need to be quoted in programs.


(not obj)R5RS procedure

Not returns #t if obj is false, and returns #f otherwise.
  (not #t)         ⇒  #f
  (not 3)          ⇒  #f
  (not (list 3))   ⇒  #f
  (not #f)         ⇒  #t
  (not '())        ⇒  #f
  (not (list))     ⇒  #f
  (not 'nil)       ⇒  #f

(boolean? obj)R5RS procedure

Boolean? returns #t if obj is either #t or #f and returns #f otherwise.
  (boolean? #f)         ⇒  #t
  (boolean? 0)          ⇒  #f
  (boolean? '())        ⇒  #f

4.4 Pairs and lists


(pair? obj)R5RS procedure

Pair? returns #t if obj is a pair, and otherwise returns #f.

(cons obj1 obj2)R5RS procedure

Returns a newly allocated pair whose car is obj1 and whose cdr is obj2. The pair is guaranteed to be different (in the sense of eqv?) from every existing object.
    (cons 'a '())           ⇒  (a)
    (cons '(a) '(b c d))    ⇒  ((a) b c d)
    (cons "a" '(b c))       ⇒  ("a" b c)
    (cons 'a 3)             ⇒  (a . 3)
    (cons '(a b) 'c)        ⇒  ((a b) . c)

(car pair)R5RS procedure

Returns the contents of the car field of pair. Note that it is an error to take the car of the empty list.
    (car '(a b c))          ⇒  a
    (car '((a) b c d))      ⇒  (a)
    (car '(1 . 2))          ⇒  1
    (car '())               ⇒  error

(cdr pair)R5RS procedure

Returns the contents of the cdr field of pair. Note that it is an error to take the cdr of the empty list.
    (cdr '((a) b c d))      ⇒  (b c d)
    (cdr '(1 . 2))          ⇒  2
    (cdr '())               ⇒  error

(set-car! pair obj)R5RS procedure

Stores obj in the car field of pair. The value returned by set-car! is void.
   (define (f) (list 'not-a-constant-list))
   (define (g) '(constant-list))
   (set-car! (f) 3)
   (set-car! (g) 3)             ⇒  error

(set-cdr! pair obj)R5RS procedure

Stores obj in the cdr field of pair. The value returned by set-cdr! is void.

(caar pair)R5RS procedure
(cadr pair)
...
(cdddar pair)
(cddddr pair)

These procedures are compositions of car and cdr, where for example caddr could be defined by
   (define caddr (lambda (x) (car (cdr (cdr x)))))
Arbitrary compositions, up to four deep, are provided. There are twenty-eight of these procedures in all.

(null? obj)R5RS procedure

Returns #t if obj is the empty list, otherwise returns #f.

(pair-mutable? obj)STklos procedure

Returns #t if obj is a mutable pair, otherwise returns #f.
(pair-mutable? '(1 . 2))    ⇒ #f
(pair-mutable? (cons 1 2))  ⇒ #t
(pair-mutable? 12)          ⇒ #f

(list? obj)R5RS procedure

Returns #t if obj is a list, otherwise returns #f. By definition, all lists have finite length and are terminated by the empty list.
   (list? '(a b c))     ⇒  #t
   (list? '())          ⇒  #t
   (list? '(a . b))     ⇒  #f
   (let ((x (list 'a)))
     (set-cdr! x x)
     (list? x))         ⇒  #f

(list obj ...)R5RS procedure

Returns a newly allocated list of its arguments.
   (list 'a (+ 3 4) 'c)            ⇒  (a 7 c)
   (list)                          ⇒  ()

(list* obj ...)STklos procedure

list* is like list except that the last argument to list* is used as the cdr of the last pair constructed.
   (list* 1 2 3)        ⇒ (1 2 . 3)
   (list* 1 2 3 '(4 5)) ⇒ (1 2 3 4 5)
   (list*)              ⇒ ()

(length list)R5RS procedure

Returns the length of list.
   (length '(a b c))               ⇒  3
   (length '(a (b) (c d e)))       ⇒  3
   (length '())                    ⇒  0

(append list ...)R5RS procedure

Returns a list consisting of the elements of the first list followed by the elements of the other lists.
   (append '(x) '(y))              ⇒  (x y)
   (append '(a) '(b c d))          ⇒  (a b c d)
   (append '(a (b)) '((c)))        ⇒  (a (b) (c))
The resulting list is always newly allocated, except that it shares structure with the last list argument. The last argument may actually be any object; an improper list results if the last argument is not a proper list.
   (append '(a b) '(c . d))        ⇒  (a b c . d)
   (append '() 'a)                 ⇒  a

(append! list ...)STklos procedure

Returns a list consisting of the elements of the first list followed by the elements of the other lists. Contrarily to append, the parameter lists (except the last one) are physically modified: their last pair is changed to the value of the next list in the append! formal parameter list.
(let* ((l1 (list 1 2))
       (l2 (list 3))
       (l3 (list 4 5))
       (l4 (append! l1 l2 l3)))
  (list l1 l2 l3))  ⇒ ((1 2 3 4 5) (3 4 5) (4 5))
An error is signaled if one of the given lists is a constant list.

(reverse list)R5RS procedure

Returns a newly allocated list consisting of the elements of list in reverse order.
   (reverse '(a b c))              ⇒  (c b a)
   (reverse '(a (b c) d (e (f))))  ⇒  ((e (f)) d (b c) a)

(reverse! list)STklos procedure

Returns a list consisting of the elements of list in reverse order. Contrarily to reverse, the returned value is not newly allocated but computed "in place".
(let ((l '(a b c)))
  (list (reverse! l) l))        ⇒  ((c b a) (a))
(reverse! '(a constant list))   ⇒  error

(list-tail list k)R5RS procedure

Returns the sublist of list obtained by omitting the first k elements. It is an error if list has fewer than k elements. List-tail could be defined by
   (define list-tail
      (lambda (x k)
         (if (zero? k)
            x
            (list-tail (cdr x) (- k 1)))))

(last-pair list)STklos procedure

Returns the last pair of list.
(last-pair '(1 2 3))   ⇒ (3)
(last-pair '(1 2 . 3)) ⇒ (2 . 3)

(list-ref list k)R5RS procedure

Returns the kth element of list. (This is the same as the car of (list-tail list k).) It is an error if list has fewer than k elements.
   (list-ref '(a b c d) 2)                 ⇒  c
   (list-ref '(a b c d)
             (inexact->exact (round 1.8))) ⇒  c

(memq obj list)R5RS procedure
(memv obj list)
(member obj list)

These procedures return the first sublist of list whose car is obj, where the sublists of list are the non-empty lists returned by (list-tail list k) for k less than the length of list. If obj does not occur in list, then #f (not the empty list) is returned. Memq uses eq? to compare obj with the elements of list, while memv uses eqv? and member uses equal?.
   (memq 'a '(a b c))              ⇒  (a b c)
   (memq 'b '(a b c))              ⇒  (b c)
   (memq 'a '(b c d))              ⇒  #f
   (memq (list 'a) '(b (a) c))     ⇒  #f
   (member (list 'a)
           '(b (a) c))             ⇒  ((a) c)
   (memv 101 '(100 101 102))       ⇒  (101 102)

(assq obj alist)R5RS procedure
(assv obj alist)
(assoc obj alist)

Alist (for "association list") must be a list of pairs. These procedures find the first pair in alist whose car field is obj, and returns that pair. If no pair in alist has obj as its car, then #f (not the empty list) is returned. Assq uses eq? to compare obj with the car fields of the pairs in alist, while assv uses eqv? and assoc uses equal?.
   (define e '((a 1) (b 2) (c 3)))
   (assq 'a e)                ⇒  (a 1)
   (assq 'b e)                ⇒  (b 2)
   (assq 'd e)                ⇒  #f
   (assq (list 'a) '(((a)) ((b)) ((c))))
                              ⇒  #f
   (assoc (list 'a) '(((a)) ((b)) ((c))))
                              ⇒  ((a))
   (assv 5 '((2 3) (5 7) (11 13)))
                              ⇒  (5 7)
Rationale: Although they are ordinarily used as predicates, memq, memv, member, assq, assv, and assoc do not have question marks in their names because they return useful values rather than just #t or #f.

(copy-tree obj)STklos procedure

Copy-tree recursively copies trees of pairs. If obj is not a pair, it is returned; otherwise the result is a new pair whose car and cdr are obtained by calling copy-tree on the car and cdr of obj, respectively.

(filter pred list)STklos procedure
(filter! pred list)

Filter returns all the elements of list that satisfy predicate pred. The list is not disordered: elements that appear in the result list occur in the same order as they occur in the argument list. Filter! does the same job than filter by physically modifying its list argument
(filter even? '(0 7 8 8 43 -4)) ⇒ (0 8 8 -4)
(let* ((l1 (list 0 7 8 8 43 -4))
       (l2 (filter! even? l1)))
   (list l1 l2))                ⇒ ((0 8 8 -4) (0 8 8 -4))
An error is signaled if list is a constant list.

(remove pred list)STklos procedure

Remove returns list without the elements that satisfy predicate pred:

The list is not disordered -- elements that appear in the result list occur in the same order as they occur in the argument list. Remove! does the same job than remove by physically modifying its list argument
(remove even? '(0 7 8 8 43 -4)) ⇒ (7 43)

(delete x list [=])STklos procedure
(delete! x list [=])

Delete uses the comparison procedure =, which defaults to equal?, to find all elements of list that are equal to x, and deletes them from list. The dynamic order in which the various applications of = are made is not specified.

The list is not disordered -- elements that appear in the result list occur in the same order as they occur in the argument list.

The comparison procedure is used in this way: (= x ei). That is, x is always the first argument, and a list element is always the second argument. The comparison procedure will be used to compare each element of list exactly once; the order in which it is applied to the various ei is not specified. Thus, one can reliably remove all the numbers greater than five from a list with
(delete 5 list <) 
delete! is the linear-update variant of delete. It is allowed, but not required, to alter the cons cells in its argument list to construct the result.

4.5 Symbols

The STklos reader can read symbols whose names contain special characters or letters in the non standard case. When a symbol is read, the parts enclosed in bars "|" will be entered verbatim into the symbol's name. The "|" characters are not part of the symbol; they only serve to delimit the sequence of characters that must be entered "as is". In order to maintain read-write invariance, symbols containing such sequences of special characters will be written between a pair of "|".

'|a|                  ⇒  a
(string->symbol "a")  ⇒  |A|
(symbol->string '|A|) ⇒  "A"
'|a  b|               ⇒  |a  b|
'a|B|c                ⇒  |aBc|
(write '|FoO|)        -| |FoO| 
(display '|FoO|)      -| FoO

(symbol? obj)R5RS procedure

Returns #t if obj is a symbol, otherwise returns #f.
   (symbol? 'foo)          ⇒  #t
   (symbol? (car '(a b)))  ⇒  #t
   (symbol? "bar")         ⇒  #f
   (symbol? 'nil)          ⇒  #t
   (symbol? '())           ⇒  #f
   (symbol? #f)            ⇒  #f
   (symbol? :key)          ⇒  #f

(symbol->string string)R5RS procedure

Returns the name of symbol as a string. If the symbol was part of an object returned as the value of a literal expression or by a call to the read procedure, and its name contains alphabetic characters, then the string returned will contain characters in the implementation's preferred standard case -- STklos prefers lower case. If the symbol was returned by string->symbol, the case of characters in the string returned will be the same as the case in the string that was passed to string->symbol. It is an error to apply mutation procedures like string-set! to strings returned by this procedure.
   (symbol->string 'flying-fish)  ⇒  "flying-fish"
   (symbol->string 'Martin)       ⇒  "martin"
   (symbol->string (string->symbol "Malvina"))
                                  ⇒  "Malvina"

(string->symbol string)R5RS procedure

Returns the symbol whose name is string. This procedure can create symbols with names containing special characters or letters in the non-standard case, but it is usually a bad idea to create such symbols because in some implementations of Scheme they cannot be read as themselves.
   (eq? 'mISSISSIppi 'mississippi)     ⇒  #t
   (string->symbol "mISSISSIppi")      ⇒  |mISSISSIppi|
   (eq? 'bitBlt (string->symbol "bitBlt"))
                                       ⇒  #f
   (eq? 'JollyWog
        (string->symbol
          (symbol->string 'JollyWog))) ⇒  #t
   (string=? "K. Harper, M.D."
             (symbol->string
               (string->symbol "K. Harper, M.D.")))
                                       ⇒  #t

(string->unterned-symbol string)STklos procedure

Returns the symbol whose print name is made from the characters of string. This symbol is guaranteed to be unique (i.e. not eq? to any other symbol):
(let ((ua (string->uninterned-symbol "a")))
  (list (eq? 'a ua)
        (eqv? 'a ua)
        (eq? ua (string->uninterned-symbol "a"))
        (eqv? ua (string->uninterned-symbol "a"))))
          ⇒ (#f #t #f #t)

(gensym)STklos procedure
(gensym prefix)

Creates a new symbol. The print name of the generated symbol consists of a prefix (which defaults to "G") followed by the decimal representation of a number. If prefix is specified, it must be either a string or a symbol.
(gensym)        ⇒ |G100|
(gensym "foo-") ⇒ foo-101
(gensym 'foo-)  ⇒ foo-102

4.6 Characters

The following table gives the list of allowed character names with their ASCII eqivalent expressed in octal. Some chracaters have an alternate name which is also shown in this table.

namevaluealt. namenamevaluealt. name
nul000nullsoh001
stx002etx003
eot004enq005
ack006bel007bell
bs010backspaceht011tab
nl012newlinevt013
np014pagecr015return
so016si017
dle020dc1021
dc2022dc3023
dc4024nak025
syn026etb027
can030em031
sub032esc033escape
fs034gs035
rs036us037
sp040spacedel177delete

(char? obj)R5RS procedure

Returns #t if obj is a character, otherwise returns #f.

(char=? char1 char2)R5RS procedure
(char<? char1 char2)
(char>? char1 char2)
(char<=? char1 char2)
(char>=? char1 char2)

These procedures impose a total ordering on the set of characters. It is guaranteed that under this ordering:
  • The upper case characters are in order.
  • The lower case characters are in order.
  • The digits are in order.
  • Either all the digits precede all the upper case letters, or vice versa.
  • Either all the digits precede all the lower case letters, or vice versa.

(char-ci=? char1 char2)R5RS procedure
(char-ci<? char1 char2)
(char-ci>? char1 char2)
(char-ci<=? char1 char2)
(char-ci>=? char1 char2)

These procedures are similar to char=? et cetera, but they treat upper case and lower case letters as the same. For example, (char-ci=? #A #a) returns #t.

(char-alphabetic? char)R5RS procedure
(char-numeric? char)
(char-whitespace? char)
(char-upper-case? letter)
(char-lower-case? letter)

These procedures return #t if their arguments are alphabetic, numeric, whitespace, upper case, or lower case characters, respectively, otherwise they return #f. The following remarks, which are specific to the ASCII character set, are intended only as a guide: The alphabetic characters are the 52 upper and lower case letters. The numeric characters are the ten decimal digits. The whitespace characters are space, tab, line feed, form feed, and carriage return.

(char->integer char)R5RS procedure
(integer->char n)

Given a character, char->integer returns an exact integer representation of the character. Given an exact integer that is the image of a character under char->integer, integer->char returns that character. These procedures implement order-preserving isomorphisms between the set of characters under the char<=? ordering and some subset of the integers under the <= ordering. That is, if
   (char<=? a b) ⇒ #t  and  (<= x y) ⇒ #t
and x and y are in the domain of integer->char, then
   (<= (char->integer a)
       (char->integer b))         ⇒  #t

  (char<=? (integer->char x)
           (integer->char y))     ⇒  #t

(char-upcase char)R5RS procedure
(char-downcase char)

These procedures return a character char2 such that (char-ci=? char char2). In addition, if char is alphabetic, then the result of char-upcase is upper case and the result of char-downcase is lower case.

4.7 Strings

STklos string constants allow the insertion of arbitrary characters by encoding them as escape sequences. An escape sequence is introduced by a backslash "\". The valid escape sequences are shown in the following table.

SequenceCharacter inserted
\bBackspace
\e Escape
\n Newline
\t Horizontal Tab
\n Carriage Return
\0abc ASCII character with octal value abc
\xab ASCII character with hexadecimal value ab
\<newline> None (permits to enter a string on several lines)
\<other> <other>

For instance, the string

"ab040c\nd
e"

is the string consisting of the characters #\a, #\b, #\space, #\c, #\newline, #\d and #\e.


(string? obj)R5RS procedure

Returns #t if obj is a string, otherwise returns #f.

(make-string k)R5RS procedure
(make-string k char)

Make-string returns a newly allocated string of length k. If char is given, then all elements of the string are initialized to char, otherwise the contents of the string are unspecified.

(string char ...)R5RS procedure

Returns a newly allocated string composed of the arguments.

(string-length string)R5RS procedure

Returns the number of characters in the given string.

(string-ref string k)R5RS procedure

String-ref returns character k of string using zero-origin indexing (k must be a valid index of string).

(string-set! string k char)R5RS procedure

String-set! stores char in element k of string and returns void (k must be a valid index of string).
(define (f) (make-string 3 #*))
(define (g) "***")
(string-set! (f) 0 #?)  ⇒  void
(string-set! (g) 0 #?)  ⇒  error
(string-set! (symbol->string 'immutable) 0 #?)  
                         ⇒  error

(string=? string1 string2)R5RS procedure
(string-ci=? string1 string2)

Returns #t if the two strings are the same length and contain the same characters in the same positions, otherwise returns #f. String-ci=? treats upper and lower case letters as though they were the same character, but string=? treats upper and lower case as distinct characters.

(string<? string1 string2)R5RS procedure
(string>? string1 string2)
(string<=? string1 string2)
(string>=? string1 string2)
(string-ci<? string1 string2)
(string-ci>? string1 string2)
(string-ci<=? string1 string2)
(string-ci>=? string1 string2)

These procedures are the lexicographic extensions to strings of the corresponding orderings on characters. For example, string<? is the lexicographic ordering on strings induced by the ordering char<? on characters. If two strings differ in length but are the same up to the length of the shorter string, the shorter string is considered to be lexicographically less than the longer string.

(substring string start end)R5RS procedure

String must be a string, and start and end must be exact integers satisfying
0 <= start <= end <= (string-length string).
Substring returns a newly allocated string formed from the characters of string beginning with index start (inclusive) and ending with index end (exclusive).

(string-append string ...)R5RS procedure

Returns a newly allocated string whose characters form the concatenation of the given strings.

(string->list string)R5RS procedure
(list->string list)

String->list returns a newly allocated list of the characters that make up the given string. List->string returns a newly allocated string formed from the characters in the list list, which must be a list of characters. String->list and list->string are inverses so far as equal? is concerned.

(string-copy string)R5RS procedure

Returns a newly allocated copy of the given string.

(string-split str)STklos procedure
(string-split str delimiters)

parses string and returns a list of tokens ended by a character of the delimiters string. If delimiters is omitted, it defaults to a string containing a space, a tabulation and a newline characters.
(string-split "/usr/local/bin" "/") 
                       ⇒ ("usr" "local" "bin")
(string-split "once   upon a time") 
                       ⇒ ("once" "upon" "a" "time")

(string-index str1 str2)STklos procedure

Returns the (first) index where str1 is a substring of str2 if it exists; otherwise returns #f.
(string-index "ca" "abracadabra") ⇒  4
(string-index "ba" "abracadabra") ⇒  #f

(string-find? str1 str2)