4. Standard Procedures

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

R5RS procedure

(eqv? obj1 obj2)

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
    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, and are either both exact or both inexact.

  • obj1 and obj2 are both characters and are the same character according to the char=? procedure`.

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

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 :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
In fact, the value returned by STklos depends on the way code is entered and can yield #t in some cases and #f in others.

See R5RS for more details on eqv?.

R5RS procedure

(eq? obj1 obj2)

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 that:

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

  • 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

R5RS procedure

(equal? obj1 obj2)

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? always terminates even 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
(equal? '#1=(a b . #1#)
        '#2=(a b a b . #2#))    =>  #t
A rule of thumb is that objects are generally equal? if they print the same.

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 (not a number).

R5RS procedure

(number? obj)
(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 for a number then all higher type predicates are also true for 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

R5RS procedure

(exact? z)
(inexact? z)

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

R7RS procedure

(inexact z)
(exact z)

These R7RS procedures correspond to the R5RS exact→inexact and inexact→exact procedure respectively

R7RS procedure

(exact→integer? z)

Returns #t if z is both exact and an integer; otherwise returns #f.

(exact-integer? 32)   => #t
(exact-integer? 32.0) => #f
(exact-integer? 32/5) => #f

STklos procedure

(bignum? x)

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`

R5RS procedure

(= z1 z2 z3 …​)
(< 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, and #f otherwise. If any of the arguments are +nan.0, all the predicates return #f.

(= +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

R5RS procedure

(finite? z)
(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

R7RS procedure

(nan? z)

The nan? procedure returns #t on +nan.0, and on complex numbers if their real or imaginary parts or both are +nan.0. Otherwise it returns #f.

(nan? +nan.0)          =>  #t
(nan? 32)              =>  #f
(nan? +nan.0+5.0i)     =>  #t
(nan? 1+2i)            =>  #f

STklos procedure

(make-nan negative? quiet? payload)
(make-nan negative? quiet? payload float)

Returns a NaN whose sign bit is equal to negative? (#t for negative, #f for positive), whose quiet bit is equal to quiet? (#t for quiet, #f for signaling), and whose payload is the positive exact integer payload. It is an error if payload is larger than a NaN can hold.

The optional parameter float, is never used in STklos.

This function is defined in SRFI-208.

STklos procedure

(nan-negative? nan)

returns #t if the sign bit of nan is set and #f otherwise.

STklos procedure

(nan-quiet? nan)

returns #t if nan is a quiet NaN.

STklos procedure

(nan-payload nan)

returns the payload bits of nan as a positive exact integer.

STklos procedure

(nan=? nan1 nan2)

Returns #t if nan1 and nan2 have the same sign, quiet bit, and payload; and #f otherwise.

R5RS procedure

(max x1 x2 …​)
(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
If any argument is inexact, then the result will also be inexact

R7RS procedure

(floor/ n1 n2)
(floor-quotient n1 n2)
(floor-remainder n1 n2)
(truncate/ n1 n2)
(truncate-quotient n1 n2)
(truncate-remainder n1 n2)

These procedures implement number-theoretic (integer) division. It is an error if n2 is zero. The procedures ending in '/' return two integers; the other procedures return an integer. All the procedures compute a quotient q and remainder r such that n1=n2*q+r.

See R7RS for more information.

(floor/ 5 2)         => 2 1
(floor/ -5 2)        => -3 1
(floor/ 5 -2)        => -3 -1
(floor/ -5 -2)       => 2 -1
(truncate/ 5 2)      => 2 1
(truncate/ -5 2)     => -2 -1
(truncate/ 5 -2)     => -2 1
(truncate/ -5 -2)    => 2 -1
(truncate/ -5.0 -2)  => 2.0 -1.0%

R5RS procedure

(+ z1 …​)
(* 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
For any finite number z:
      (+ +inf.0 z)      =>  +inf.0
      (+ -inf.0 z)      =>  -inf.0

R5RS procedure

(- z)
(- 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.0)                => -inf.0
(- 0.0)                 => -0.0
(/ 0)                   => error (division by 0)

R5RS procedure

(abs z)

Abs returns the absolute value of its argument.

(abs -7)                =>  7
(abs -inf.0)            => +inf.0
(abs -3+4i)             => 5
(abs -3.0-4i)           => 5.0
STklos extends the R7RS abs function, by allowing its argument to be a complex number. In this case, abs returns the magnitude of its argument.

R5RS procedure

(quotient n1 n2)
(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

R5RS procedure

(gcd n1 …​)
(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

R5RS procedure

(numerator q)
(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

R5RS procedure

(floor x)
(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.

Round rounds to even for consistency with the default rounding mode specified by the IEEE floating point standard.
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

R5RS procedure

(rationalize x y)

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

R5RS procedure

(exp z)
(log z)
(log z b)
(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 log computes the logarithm of x in base b as

(/ (log x) (log b))

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.

STklos procedure

(sinh z)
(cosh z)
(tanh z)
(asinh z)
(acosh z)
(atanh z)

These procedures compute the hyperbolic trigonometric functions.

(sinh 1)     => 1.1752011936438
(sinh 0+1i)  => 0.0+0.841470984807897i
(cosh 1)     => 1.54308063481524
(cosh 0+1i)  => 0.54030230586814
(tanh 1)     => 0.761594155955765
(tanh 0+1i)  => 0.0+1.5574077246549i
(asinh 1)    => 0.881373587019543
(asinh 0+1i) => 0+1.5707963267949i
(acosh 0)    => 0+1.5707963267949i
(acosh 0+1i) => 1.23340311751122+1.5707963267949i
(atanh 1)    => error
(atanh 0+1i) => 0.0+0.785398163397448i

In general, (asinh (sinh x)) and similar compositions should be equal to x, except for inexactness due to the internal floating point number approximation for real numbers.

(sinh (asinh 0+1i)) => 0.0+1.0i
(cosh (acosh 0+1i)) => 8.65956056235493e-17+1.0i
(tanh (atanh 0+1i)) => 0.0+1.0i

These functions will always return an exact result for the following arguments:

(sinh 0.0)     => 0
(cosh 0.0)     => 1
(tanh 0.0)     => 0
(asinh 0.0)    => 0
(acosh 1.0)    => 0
(atanh 0.0)    => 0

STklos procedure

(radians→degrees r)
(degrees→radians d)

These procedures convert angles from radians into degrees and from degrees into radians.

R5RS procedure

(sqrt z)

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

R7RS procedure

(square z)

Returns the square of z. This is equivalent to (* z z).

(square 42)     => 1764
(square 2.0)    => 4.0

R7RS procedure

(exact-integer-sqrt k)

Returns two non negatives integers s and r where k=s2+r and k<(s+1)2.

(exact-integer-sqrt 4)     => 2 0
(exact-integer-sqrt 5)     => 2 1

STklos procedure

(exact-integer-log n b)

Exact-integer-log is to log what exact-integer-sqrt is to sqrt.

Returns two values: the first value is the largest integer number less than or equal to the logarithm of n in base b. The second value is the difference between n and (expt b k), where k is the first value.

Both arguments must be exact, and the resulting values are exact integers. Also, both arguments are mandatory, since it is no meaningful in this context to use base e.

(exact-integer-log 8 2)  => 3,0
(exact-integer-log 11 2) => 3,3
(exact-integer-log
         (expt 3 5)
         (expt 3 4))     => 1, 162
(exact-integer-log 16 2) => 4, 0
(exact-integer-log 19 1) => 4, 3
(exact-integer-log
         (expt 6 10000)
         (expt 6 1000)) => 10, 0
(exact-integer-log 2 1) => error
(exact-integer-log 0 5) => error
(exact-integer-log 0 0) => error

R5RS procedure

(expt z1 z2)

Returns z1 raised to the power z2.

0,(sup "z") is 1 if z = 0 and 0 otherwise.

R5RS procedure

(make-rectangular x1 x2)
(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
Magnitude is the same as abs for a real argument.

R5RS procedure

(exact→inexact z)
(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.

R5RS procedure

(number→string z)
(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.

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

R5RS procedure

(string→number string)
(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. ,(code ""#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

STklos procedure

(bit-and n1 n2 …​)
(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 ,(emph "and"), inclusive and exclusive ,(emph "or"). bit-not returns the bitwise ,(emph "not") of n. bit-shift returns the bitwise ,(emph "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

STklos procedure

(random-integer n)

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 (Source of random bits).

STklos procedure

(random-real)

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 (Source of random bits).

STklos procedure

(decode-float n)

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

STklos procedure

(encode-float significand exponent sign)

encode-float does the inverse work of decode-float: it accepts three numbers, significand, exponent and sign, and returns the floating point number represented by them.

When significand is #f, a NaN will be returned. When significand is #t, positive or negative infinity is returned, depending on the value of sign.

Otherwise, the number returned is

n = (* sign significand (expt 2 exponent))

Both significand and exponent must be within their proper ranges:

0 < significandfloat-max-significand, and

float-min-exponentexponentfloat-max-exponent.

(encode-float (#t 0  1)) => +inf.0
(encode-float (#t 0 -1)) => -inf.0
(encode-float (#f 0  1)) => +nan.0

(decode-float -0.01)
=> 5764607523034235
=> -59
=> -1
(inexact (encode-float 5764607523034235 -59 -1)) => -0.01

STklos procedure

(float-max-significand)
(float-min-exponent)
(float-max-exponent)

These procedures return the maximum significand value and the minimum and maximum values for the exponent when calling the encode-float procedure.

STklos procedure

(integer-length n)

Integer-length returns the necessary number of bits to represent n in 2’s complement, assuming a leading 1 bit when n is negative. When n is zero, the procedure returns zero. This procedure works for any type of integer (fixnums and bignums).

(integer-length -3)            => 2
(integer-length -2)            => 1
(integer-length -1)            => 0
(integer-length 0)             => 0
(integer-length 1)             => 1
(integer-length 2)             => 2
(integer-length 3)             => 2
(integer-length (expt 2 5000)) => 5001

STklos procedure

(integer-length n)

Integer-length returns the necessary number of bits to represent n in 2’s complement, assuming a leading 1 bit when n is negative. When n is zero, the procedure returns zero. This procedure works for any type of integer (fixnums and bignums).

(integer-length -3)            => 2
(integer-length -2)            => 1
(integer-length -1)            => 0
(integer-length 0)             => 0
(integer-length 1)             => 1
(integer-length 2)             => 2
(integer-length 3)             => 2
(integer-length (expt 2 5000)) => 5001

STklos procedure

(1+ x)
(1- x)

These procedures return x plus one and x minus one, respectively. Note that the value of x is not changed.

(define x 10)
(1+ x)          => 11
x               => 10
(1- x)          => 9
x               => 10

STklos procedure

(inc! place)
(inc! place val)
(dec! place)
(dec place val)

These forms increment or decrement the value contained in place by val. If ommitted, val defaults to 1. The result of both forms is undefined.

Since STklos permits generalized set!, place may be a list of the form (proc a1 a2 …​). In this case, these forms call the setter of proc.

(define x 10)
(inc! x)
x                        => 11
(dec! x 10)
x                        => 1
(define l (list 1 2 3))
(inc! (car l))
(dec! (list-ref l 1) 20)
l                        => (2 -18 3)

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.

The functions defined in this section are conform to the ones defined in SRFI-143 (Fixnums)

STklos procedure

(fixnum? obj)

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

STklos procedure

(fixnum-width)

Returns the number of bits used to represent a fixnum number.

STklos procedure

(least-fixnum)
(greatest-fixnum)

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

STklos procedure

(fxzero? obj)

fxzero? returns #t if obj is the fixnum zero and returns #f if it is a non-zero fixnum.

  (fxzero? #f)             =>  error
  (fxzero? (expt 100 100)) =>  error
  (fxzero? 0)              =>  #t
  (fxzero? 1)              =>  #f

STklos procedure

(fxpositive? obj)
(fxnegative? obj)

fxpositive? returns #t if obj is a positive fixnum and returns #f if it is a non-positive fixnum. fxnegative? can be used to test if a fixnum is negative.

  (fxpositive? #f)             =>  error
  (fxpositive? (expt 100 100)) =>  error
  (fxpositive? 0)              =>  #f
  (fxpositive? 1)              =>  #t
  (fxpositive? -1)             =>  #f
  (fxnegative? 0)              =>  #f
  (fxnegative? 1)              =>  #f
  (fxnegative? -1)             =>  #t

STklos procedure

(fxodd? obj)

fxodd? returns #t if obj is a odd fixnum and returns #f if it is an even fixnum.

  (fxodd? #f)             =>  error
  (fxodd? (expt 100 100)) =>  error
  (fxodd? 0)              =>  #f
  (fxodd? 1)              =>  #t
  (fxodd? 4)              =>  #f
  (fxeven? 0)             =>  #t
  (fxeven? 1)             =>  #f
  (fxeven? 4)             =>  #t

STklos procedure

(fx+ fx1 fx2)
(fx- fx1 fx2)
(fx* fx1 fx2)
(fxquotient fx1 fx2)
(fxremainder fx1 fx2)
(fxmodulo fx1 fx2)
(fxabs fx)
(fxneg fx)

These procedures compute (respectively) the sum, the difference, the product, the quotient and the remainder and modulo of the fixnums fx1 and fx2. The call of fx- with one parameter fx computes the opposite of fx, and is equivalent in a call of fxneg with this parameter. fxabs computes the absolute value of fx.

STklos procedure

(fxsquare fx1)
(fxsqrt fx1)

These procedures compute (respectively) the square and the square root of the fixnum fx1. fxsqrt id semantically equivalent to exact-integer-sqrt (not sqrt), so that (fxsqrt n) returns two values a, b, such that a*a+b=n.

  (fxsqrt #f)             =>  error
  (fxsqrt (expt 100 100)) =>  error
  (fxsqrt -1)             =>  error
  (fxsqrt 0)              =>  0, 0
  (fxsqrt 1)              =>  1, 0
  (fxsqrt 6)              =>  2, 2

STklos procedure

(fxmax fx1 fx2 …​)
(fxmin fx1 fx2 …​)

These procedures return the maximum or minimum of their fixnum arguments.

(fxmax 3 4)              =>  4
(fxmax 3.9 4)            =>  error
(fxmax)                  =>  error
(fxmax 2 -1 3)           =>  3

STklos procedure

(fx<? fx1 fx2 …​)
(fx⇐? fx1 fx2 …​)
(fx>? fx1 fx2 …​)
(fx>=? fx1 fx2 …​)
(fx=? fx1 fx2 …​)

These are SRFI-143 procedures that compare the fixnums fx1, fx2, and so on. fx<? and fx>? return #t if the arguments are in strictly increasing/decreasing order; fx⇐? and fx>=? do the same, but admit equal neighbors; fx=? returns #t if the arguments are all equal.

STklos procedure

(fxnot fx1)
(fxand fx …​)
(fxior fx …​)
(fxxor fx …​)

These procedures are specified in SRFI-143, and they return (respectively) the bitwise not, and, inclusive or and exclusive or of their arguments, which must be fixnums.

(fxnot 1)              => -2
(fxnot 0)              => -1
(fxand #x1010 #x1011)  => 4112  ; = #x1010
(fxior #x1010 #x1011)  => 4113  ; = #x1011
(fxxor #x1010 #x1011)  => 1     ; = #x0001

STklos procedure

(fxarithmetic-shift-right fx count)
(fxarithmetic-shift-left fx count)
(fxarithmetic-shift fx count)

These procedures are specified in SRFI-143, and they perform bitwise right-shift, left-shft and shift with arbitrary direction on fixnums. The strictly left and right shifts are more efficient.

(fxarithmetic-shift-right #b100110 3) =>   4 ; = #b100
(fxarithmetic-shift-left  #b100110 3) => 304 ; = #b100110000
(fxarithmetic-shift #b101 2)          => 20  ; = #b10100
(fxarithmetic-shift #b101 -2)         =>  1  ; =#b1

STklos procedure

(fxlength fx)

This is a SRFI-143 procedure that returns the length of the fixnum in bits (that is, the number of bits necessary to represent the number).

(fxlength #b101)          =>  3
(fxlength #b1101)         =>  4
(fxlength #b0101)         =>  3

STklos procedure

(fxif mask fx1 fx2)

This is a SRFI-143 procedure that merge the fixnum bitstrings fx1 and fx2, with bitstring mask determining from which string to take each bit. That is, if the kth bit of mask is 1, then the kth bit of the result is the kth bit of fx1, otherwise the kth bit of fx2.

(fxif 3 1 8)                            => 9
(fxif 3 8 1)                            => 0
(fxif 1 1 2)                            => 3
(fxif #b00111100 #b11110000 #b00001111) => #b00110011

STklos procedure

(fxbit-set? index fx)

This is a SRFI-143 procedure that returns #t if the index-th bit of fx.

(fxbit-set? 1 3)          => #t
(fxbit-set? 2 7)          => #t
(fxbit-set? 3 6)          => #f
(fxbit-set? 5 #b00111100) => #t

STklos procedure

(fxcopy-bit index fx value)

This is a SRFI-143 procedure that sets the index-th bit if fx to one if value is #t, and to zero if value is #f.

(fxcopy-bit 2 3 #t)          =>  7
(fxcopy-bit 2 7 #f)          =>  3
(fxcopy-bit 5 #b00111100 #f) => 28 ; = #b00011100

STklos procedure

(fxbit-count fx1)

This is a SRFI-143 procedure that returns the quantity of bits equal to one in the fixnum fx (that is, computes its Hamming weight).

(fxbit-count 8)                         => 1
(fxbit-count 3)                         => 2
(fxbit-count 7)                         => 3
(fxbit-count #b00111010)                => 4

STklos procedure

(fxfirst-set-bit fx1)

This is a SRFI-143 procedure that returns the index of the first (smallest index) 1 bit in bitstring fx. Returns -1 if fx contains no 1 bits (i.e., if fx is zero).

(fxfirst-set-bit  8)                         => 3
(fxfirst-set-bit  3)                         => 0
(fxfirst-set-bit  7)                         => 0
(fxfirst-set-bit  #b10110000)                => 4

STklos procedure

(fxbit-field fx1 start end)

This is a SRFI-143 procedure that extracts a bit field from the fixnum fx1. The bit field is the sequence of bits between start (including) and end (excluding)

(fxbit-field  #b10110000 3 5)  => 6 ; = #b110

STklos procedure

(fxbit-field-rotate fx)

This is a SRFI-143 procedure that returns fx with the field cyclically permuted by count bits towards high-order.

(fxbit-field-rotate #b101011100 -2 1 5)     => 342  = #b101010110
(fxbit-field-rotate #b101011011110 -3 2 10) => 3034 = #b101111011010
(fxbit-field-rotate #b101011011110 3 2 10)  => 2806 = #b101011110110

STklos procedure

(fxbit-field-reverse fx)

This is a SRFI-143 procedure that returns fx with the order of the bits in the field reversed.

(fxbit-field-reverse #b101011100 1 5)     => #b101001110
(fxbit-field-reverse #b101011011110 2 10) => #b101110110110

STklos procedure

(fx+/carry i j k)

Returns two values: i`j`k, and carry: it is the value of the computation

(let*-values (((s) (+ i j k))
              ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))

STklos procedure

(fx-/carry i j k)

Returns two values: i-j-k, and carry: it is the value of the computation

(let*-values (((s) (- i j k))
              ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))

STklos procedure

(fx*/carry i j k)

Returns two values: i*j+k, and carry: it is the value of the computation

(let*-values (((s) (+ (* i j) k))
              ((q r) (balanced/ s (expt 2 fx-width))))
  (values r q))

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.

R5RS procedure

(not obj)

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

R5RS procedure

(boolean? obj)

Boolean? returns #t if obj is either #t or #f and returns #f otherwise.

  (boolean? #f)         =>  #t
  (boolean? 0)          =>  #f
  (boolean? '())        =>  #f

R5RS procedure

(boolean=? boolean1 boolean2 …​)

Returns #t if all the arguments are booleans and all are #t or all are #f.

4.4. Pairs and lists

R5RS procedure

(pair? obj)

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

R5RS procedure

(cons obj1 obj2)

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)

R5RS procedure

(car pair)

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

R5RS procedure

(cdr pair)

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

R5RS procedure

(set-car! pair obj)

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

R5RS procedure

(set-cdr! pair obj)

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

R5RS procedure

(caar pair)
(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.

R5RS procedure

(null? obj)

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

STklos procedure

(pair-mutable? obj)

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

R5RS procedure

(list? obj)

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

STklos procedure

(improper-list? obj)

Returns false if and only if obj is an improper list.

(improper-list? 2)            => #f
(improper-list? '())          => #f
(improper-list? '(1 2 3))     => #f
(improper-list? '(1 2 . 3))   => #t
(improper-list? (cons 'a 'b)) => #t
(improper-list? (list 1 2))   => #f
(improper-list? #void)        => #f

R7RS procedure

(make-list k)
(make-list k fill)

Returns a newly allocated list of k elements. If a second argument is given, then each element is initialized to fill . Otherwise the initial contents of each element is unspecified.

R5RS procedure

(list obj …​)

Returns a newly allocated list of its arguments.

   (list 'a (+ 3 4) 'c)            =>  (a 7 c)
   (list)                          =>  ()

STklos procedure

(list* obj …​)

list* is like list except that the last argument to list* is used as the ,(emph "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*)              => ()

R5RS procedure

(length list)

Returns the length of list.

   (length '(a b c))               =>  3
   (length '(a (b) (c d e)))       =>  3
   (length '())                    =>  0

R5RS procedure

(append list …​)

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

STklos procedure

(append! list …​)

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 l4))  => ((1 2 3 4 5) (3 4 5) (4 5) (1 2 3 4 5))

An error is signaled if one of the given lists is a constant list.

R5RS procedure

(reverse list)

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)

STklos procedure

(reverse! list)

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

R5RS procedure

(list-tail list k)

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

STklos procedure

(last-pair list)

Returns the last pair of list.

(last-pair '(1 2 3))   => (3)
(last-pair '(1 2 . 3)) => (2 . 3)

R5RS procedure

(list-ref list k)

Returns the k`th 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

R7RS procedure

(list-set! list k obj)

The list-set! procedure stores obj in element k of list. It is an error if k is not a valid index of list.

(let ((ls (list 'one 'two 'five!)))
   (list-set! ls 2 'three)
   ls)                              => (one two three)
(list-set! '(0 1 2) 1 "oops")       => error (constant list)

R5RS / R7RS procedure

(memq obj list)
(memv obj list)
(member obj list)
(member obj list compare)

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 compare, if given, and equal? otherwise.

   (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)
   (member "B"
           ("a" "b" "c")
           string-ci=?)            => ("b" "c")
   (memv 101 '(100 101 102))       =>  (101 102)
As in R7RS, the member function accepts also a comparison function.

R5RS / R7RS procedure

(assq obj alist)
(assv obj alist)
(assoc obj alist)
(assoc obj alist compare)

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))
   (assoc 2.0 '((1 1) (2 4) (3 9)) =)
                              => (2 4)
   (assv 5 '((2 3) (5 7) (11 13)))
                              =>  (5 7)
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.
As in R7RS, the assoc function accepts also a comparison function.

R7RS procedure

(list-copy obj)

list-copy 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 list-copy on the car and cdr of obj, respectively.

STklos procedure

(filter pred list)
(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 as 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.

STklos procedure

(remove pred list)

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)

STklos procedure

(delete x list [=])
(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.

STklos procedure

(push! place val)
(pop! place)

These macros push and pop an element into/from a list, so as to use it as a stack. The result of the push! form is undefined, whereas the result of pop! is the result of the evaluation of place.

(define S (list 20 30 40))
(push! S 10)
S                         => (10 20 30 40)
(pop! S)                  => 10
S                         => (20 30 40)

Since STklos permits generalized set!, place may be a list of the form (proc a1 a2 …​). In this case, push! calls the setter of proc.

(define v (vector (list 1 2) (list 3 4)))
(push! (vector-ref v 0) 17)
(pop! (vector-ref v 1))                       => 3
v                                             => #((17 1 2) (4))

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

In addition, any character can be used within an identifier when specified via an inline hex escape . For example, the identifier Hx65;llo is the same as the identifier Hello, and, if the UTF-8 encoding is used, the identifier x3BB; is the same as the identifier λ.

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

R5RS procedure

(symbol? obj)

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

R5RS procedure

(symbol=? symbol1 symbol2 …​)

Returns #t if all the arguments are symbols and all have the same name in the sense of string=?.

R5RS procedure

(symbol→string string)

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"

R5RS procedure

(string→symbol string)

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.

   (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
The expression (eq? 'mISSISSIppi 'mississippi) returns #f if STklos is running in case-sensitive mode (default), whereas it returns #t otherwise.

STklos procedure

(string→unterned-symbol string)

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)

STklos procedure

(gensym)
(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.

name value alt. name name value alt. name

nul

000

null

soh

001

stx

002

etx

003

eot

004

enq

005

ack

006

bel

007

alarm

bs

010

backspace

ht

011

tab

nl

012

newline

vt

013

np

014

page

cr

015

return

so

016

si

017

dle

020

dc1

021

dc2

022

dc3

023

dc4

024

nak

025

syn

026

etb

027

can

030

em

031

sub

032

esc

033

escape

fs

034

gs

035

rs

036

us

037

sp

040

space

del

177

delete

STklos supports the complete Unicode character set, if UTF-8 encoding is used. Hereafter, are some examples of characters:

#A                => uppercase A
#a                => lowercase a
#x41              => the U+0041 character (uppercase A)
#x03bb            => λ

R5RS procedure

(char? obj)

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

R5RS procedure

(char=? char1 char2 …​)
(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. )

R5RS procedure

(char-ci=? char1 char2 …​)
(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.

R5RS procedure

(char-alphabetic? char)
(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.

R5RS procedure

(char→integer char)
(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

integer→char accepts an exact number between 0 and #xD7FFF or between #xE000 and #x10FFFF, if UTF8 encoding is used. Otherwise, it accepts a number between 0 and #xFF.

R5RS procedure

(char-upcase char)
(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.

STklos procedure

(char-foldcase char)

This procedure applies the Unicode simple case folding algorithm and returns the result. Note that language-sensitive folding is not used. If the argument is an uppercase letter, the result will be either a lowercase letter or the same as the argument if the lowercase letter does not exist.

R7RS procedure

(digit-value char)

This procedure returns the numeric value (0 to 9) of its argument if it is a numeric digit (that is, if char-numeric? returns #t), or #f on any other character.

(digit-value
(digit-value #3)        => 3
(digit-value #x0664)    => 4
(digit-value #x0AE6)    => 0
(digit-value #x0EA6)    => #f

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 "$backslash$". The valid escape sequences are shown in the following table.

Sequence Character inserted

a

Alarm

b

Backspace

e

Escape

n

Newline

t

Horizontal Tab

r

Carriage Return

"

doublequote U+0022

\

backslash U+005C

0abc

ASCII character with octal value abc

x<hexa value>;

ASCII character with given hexadecimal value

<intraline whitespace><newline><intraline whitespace>

None (permits to enter a string on several lines)

<other>

<other>

For instance, the string

"ab040x20;cnd
         e"

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

Notes:

  • Using octal code is limited to characters in the range 0 to #xFF. It is then not convenient to enter Unicode characters. This form is deprecated should not be used anymore.

  • A line ending which is preceded by <intraline whitespace> expands to nothing (along with any trailing <intraline whitespace>), and can be used to indent strings for improved legibility.

R5RS procedure

(string? obj)

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

R5RS procedure

(make-string k)
(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.

R5RS procedure

(string char …​)

Returns a newly allocated string composed of the arguments.

R5RS procedure

(string-length string)

Returns the number of characters in the given string.

R5RS procedure

(string-ref string k)

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

R5RS procedure

(string-set! string k char)

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

R5RS / R7RS procedure

(string=? string1 string2 …​)
(string-ci=? string1 string2 …​)

Returns #t if all the 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.

R5RS version of these functions accept only two arguments.

R5RS / R7RS procedure

(string<? string1 string2 …​)
(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.

R5RS version of these functions accept only two arguments.

R5RS procedure

(substring string start end)

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

R5RS procedure

(string-append string …​)

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

R5RS / R7RS procedure

(string→list string)
(string→list string start)
(string→list string start end)
(list→string list)

String→list returns a newly allocated list of the characters of string between start and end. 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.

The R5RS version of string→list accepts only one parameter.

R5RS / R7RS procedure

(string-copy string)
(string-copy string start)
(string-copy string start stop)

Returns a newly allocated copy of the part of the given string between start and stop.

The R5RS version of string-copy accepts only one argument.

R7RS procedure

(string-copy! to at from)
(string-copy! to at from start)
(string-copy! to at from start end)

Copies the characters of string from between start and end to string to, starting at at. The order in which characters are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary string and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances.

It is an error if at is less than zero or greater than the length of to. It is also an error if (- (string-length to) at) is less than (- end start).

STklos procedure

(string-split str)
(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")

STklos procedure

(string-position str1 str2)

Returns the (first) index where str1 is a substring of str2 if it exists; otherwise returns #f.

(string-position "ca" "abracadabra") =>  4
(string-position "ba" "abracadabra") =>  #f
This function was also called string-index. This name is deprecated since it conficts with the string-index defined in SRFI-13.

STklos procedure

(string-find? str1 str2)

Returns #t if str1 appears somewhere in str2; otherwise returns #f.

R7RS procedure

(string-fill! string char)
(string-fill! string char start)
(string-fill! string char start end)

Stores char in every element of the given string between start and end.

The R5RS version of string-fill! accepts only one argument.

STklos procedure

(string-blit! s1 s2 offset)

This function places the characters of string s2 in the string s1 starting at position offset. The result of string-blit! may modify the string s1. Note that the characters of s2 can be written after the end of s1 (in which case a new string is allocated).

(string-blit! (make-string 6 #X) "abc" 2)
              => "XXabcX"
(string-blit! (make-string 10 #X) "abc" 5)
              => "XXXXXabcXX"
(string-blit! (make-string 6 #X) "a" 10)
              => "XXXXXX0000a"

STklos procedure

(string-mutable? obj)

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

(string-mutable? "abc")                => #f
(string-mutable? (string-copy "abc"))  => #t
(string-mutable? (string #a #b #c)) => #t
(string-mutable? 12)                   => #f

The following string primitives are compatible with SRFI-13 (String Library) and their documentation comes from the SRFI document.

Notes:

  • The string SRFI is supported by STklos. The function listed below just don’t need to load the full SRFI to be used

  • The functions string-upcase, string-downcase and string-foldcase are also defined in R7RS.

R7RS procedure

(string-downcase str)
(string-downcase str start)
(string-downcase str start end)

Returns a string in which the upper case letters of string str between the start and end indices have been replaced by their lower case equivalent. If start is omited, it defaults to 0. If end is omited, it defaults to the length of str.

(string-downcase "Foo BAR")        => "foo bar"
(string-downcase "Foo BAR" 4)      => "bar"
(string-downcase "Foo BAR" 4 6)    => "ba"
In R7RS, string-downcase accepts only one argument.

STklos procedure

(string-downcase! str)
(string-downcase! str start)
(string-downcase! str start end)

This is the in-place side-effecting variant of string-downcase.

(string-downcase! (string-copy "Foo BAR") 4)    => "Foo bar"
(string-downcase! (string-copy "Foo BAR") 4 6)  => "Foo baR"

R7RS procedure

(string-upcase str)
(string-upcase str start)
(string-upcase str start end)

Returns a string in which the lower case letters of string str between the start and end indices have been replaced by their upper case equivalent. If start is omited, it defaults to 0. If end is omited, it defaults to the length of str.

In R7RS, string-upcase accepts only one argument.

STklos procedure

(string-upcase! str)
(string-upcase! str start)
(string-upcase! str start end)

This is the in-place side-effecting variant of string-upcase.

STklos procedure

(string-titlecase str)
(string-titlecase str start)
(string-titlecase str start end)

This function returns a string. For every character c in the selected range of str, if c is preceded by a cased character, it is downcased; otherwise it is titlecased. If start is omited, it defaults to 0. If end is omited, it defaults to the length of str. Note that if a start index is specified, then the character preceding s[start] has no effect on the titlecase decision for character s[start].

(string-titlecase "--capitalize tHIS sentence.")
         =>  "--Capitalize This Sentence."
(string-titlecase "see Spot run. see Nix run.")
         =>  "See Spot Run. See Nix Run."
(string-titlecase "3com makes routers.")
         =>  "3Com Makes Routers."
(string-titlecase "greasy fried chicken" 2)
         => "Easy Fried Chicken"

STklos procedure

(string-titlecase! str)
(string-titlecase! str start)
(string-titlecase! str start end)

This is the in-place side-effecting variant of string-titlecase.

STklos procedure

(string-append! string …​)

Extends string by appending each value (in order) to the end of string. A value can be a character or a string.

It is guaranteed that string-append! will return the same object that was passed to it as first argument, whose size may be larger.

This function is defined in SRFI-118.

STklos procedure

(string-replace! dst dst-start dst-end src)
(string-replace! dst dst-start dst-end src src-start)
(string-replace! dst dst-start dst-end src src-start src-end)

Replaces the characters of the variable-size string dst (between dst-start and dst-end) with the characters of the string src (between src-start and src-end). The number of characters from src may be different from the number replaced in dst, so the string may grow or contract. The special case where dst-start is equal to dst-end corresponds to insertion; the case where src-start is equal to src-end corresponds to deletion. The order in which characters are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary string and then into the destination. Returns string, appended with the characters form the concatenation of the given arguments, which can be either strings or characters.

It is guaranteed that string-replace! will return the same object that was passed to it as first argument, whose size may be larger.

This function is defined in SRFI-118.

R7RS procedure

(string-foldcase str)
(string-foldcase str start)
(string-foldcase str start end)

Returns a string in which the Unicode simple case-folding algorithm has been applied on str between the start and end indices. If start is omited, it defaults to 0. If end is omited, it defaults to the length of str.

In R7RS, string-foldcase accepts only one argument.

STklos procedure

(string-foldcase! str)
(string-foldcase! str start)
(string-foldcase! str start end)

This is the in-place side-effecting variant of string-foldcase.

4.8. Vectors

Vectors are heterogenous structures whose elements are indexed by integers. A vector typically occupies less space than a list of the same length, and the average time required to access a randomly chosen element is typically less for the vector than for the list.

The length of a vector is the number of elements that it contains. This number is a non-negative integer that is fixed when the vector is created. The valid indexes of a vector are the exact non-negative integers less than the length of the vector. The first element in a vector is indexed by zero, and the last element is indexed by one less than the length of the vector.

Vectors are written using the notation #(obj …​). For example, a vector of length 3 containing the number zero in element 0, the list (2 2 2 2) in element 1, and the string "Anna" in element 2 can be written as following:

#(0 (2 2 2 2) "Anna")
In STklos, vectors constants don’t need to be quoted.

R5RS procedure

(vector? obj)

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

R5RS procedure

(make-vector k)
(make-vector k fill)

Returns a newly allocated vector of k elements. If a second argument is given, then each element is initialized to fill. Otherwise, the initial contents of each element is unspecified.

R5RS procedure

(vector obj …​)

Returns a newly allocated vector whose elements contain the given arguments. Analogous to list.

(vector 'a 'b 'c)               =>  #(a b c)

R5RS procedure

(vector-length vector)

Returns the number of elements in vector as an exact integer.

R5RS procedure

(vector-ref vector k)

k must be a valid index of vector. Vector-ref returns the contents of element k of vector.

(vector-ref '#(1 1 2 3 5 8 13 21)
            5)                                    =>  8
(vector-ref '#(1 1 2 3 5 8 13 21)
            (let ((i (round (* 2 (acos -1)))))
              (if (inexact? i)
                  (inexact->exact i)
                  i)))                            => 13

R5RS procedure

(vector-set! vector k obj)

k must be a valid index of vector. Vector-set! stores obj in element k of vector. The value returned by vector-set! is void.

(let ((vec (vector 0 '(2 2 2 2) "Anna")))
  (vector-set! vec 1 '("Sue" "Sue"))
  vec)      =>  #(0 ("Sue" "Sue") "Anna")

(vector-set! '#(0 1 2) 1 "doe")  =>  error  ; constant vector

R5RS / R7RS procedure

(vector→list vector)
(vector→list vector start)
(vector→list vector start end)
(list→vector list)

Vector→list returns a newly allocated list of the objects contained in the elements of vector between start an end. List→vector returns a newly created vector initialized to the elements of the list list.

In both procedures, order is preserved.

(vector->list '#(dah dah didah))     =>  (dah dah didah)
(vector->list '#(dah dah didah) 1 2) =>  (dah)
(list->vector '(dididit dah))        =>  #(dididit dah)
The R5RS version of vector→list accepts only one parameter.

R7RS procedure

(vector→string string)
(vector→string string start)
(vector→string string start end)
(string→vector vector)
(string→vector vector start)
(string→vector vector start end)

The vector→string procedure returns a newly allocated string of the objects contained in the elements of vector between start and end. It is an error if any element of vector between start and end is not a character.

The string→vector procedure returns a newly created vector initialized to the elements of string between start and end.

In both procedures, order is preserved.

(string->vector "ABC")           => #(#A #B #C)
(vector->string #(#1 #2 #3))  => "123"

R5RS procedure

(vector-append vector …​)

Returns a newly allocated vector whose elements are the concatenation of the elements of the given vectors.

(vector-append #(a b c) #(d e f)) => #(a b c d e f)

R5RS / R7RS procedure

(vector-fill! vector fill)
(vector-fill! vector fill start)
(vector-fill! vector fill start end)

Stores fill in every element of vector between start and end.

The R5RS version of vector-fill! accepts only one parameter.

R5RS / R7RS procedure

(vector-copy v)
(vector-copy v start)
(vector-copy v start stop)

Return a newly allocated copy of the elements of the given vector between start and end . The elements of the new vector are the same (in the sense of eqv?) as the elements of the old.

Note that, if v is a constant vector, its copy is not constant.

(define a #(1 8 2 8))         ; a is immutable
(define b (vector-copy a))    ; b is mutable
(vector-set! b 0 3)
b                            => #(3 8 2 8)
(define c (vector-copy b 1 3))
c                            => #(8 2)

R7RS procedure

(vector-copy! to at from)
(vector-copy! to at from start)
(vector-copy! to at from start end)

STklos procedure

(vector-resize v size)
(vector-resize v size fill)

Returns a copy of v of the given size. If size is greater than the vector size of v, the contents of the newly allocated vector cells is set to the value of fill. If fill is omitted the content of the new cells is void.

STklos procedure

(vector-mutable? obj)

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

(vector-mutable? '#(1 2 a b))            => #f
(vector-mutable? (vector-copy '#(1 2)))  => #t
(vector-mutable? (vector 1 2 3))         => #t
(vector-mutable? 12)                     => #f

STklos procedure

(sort obj predicate)

Obj must be a list or a vector. Sort returns a copy of obj sorted according to predicate. Predicate must be a procedure which takes two arguments and returns a true value if the first argument is strictly ``before'' the second.

(sort '(1 2 -4 12 9 -1 2 3) <)
               => (-4 -1 1 2 2 3 9 12)
(sort '#("one" "two" "three" "four")
      (lambda (x y) (> (string-length x) (string-length y))))
               => '#("three" "four" "one" "two")

4.9. Structures

A structure type is a record data type composing a number of slots. A structure, an instance of a structure type, is a first-class value that contains a value for each field of the structure type.

Structures can be created with the define-struct high level syntax. However, STklos also offers some low-level functions to build and access the internals of a structure.

STklos syntax

(define-struct <name> <slot> …​)

Defines a structure type whose name is <name>. Once a structure type is defined, the following symbols are bound:

  • <name> denotes the structure type.

  • make-<name> is a procedure which takes 0 to n parameters (if there are n slots defined). Each parameter is assigned to the corresponding field (in the definition order).

  • <name>? is a predicate which returns #t when applied to an instance of the <name> structure type and #f otherwise

  • <name>-<slot> (one for each defined <slot>) to read the content of an instance of the <name> structure type. Writting the content of a slot can be done using a generalized set!.

(define-struct point x y)
(define p (make-point 1 2))
(point? p)    => #t
(point? 100)  => #f
(point-x p)   => 1
(point-y p)   => 2
(set! (point-x p) 10)
(point-x p)   => 10

STklos procedure

(make-struct-type name parent slots)

This form which is more general than define-struct permits to define a new structure type whose name is name. Parent is the structure type from which is the new structure type is a subtype (or #f is the new structure-type has no super type). Slots is the list of the slot names which constitute the structure tpe.

When a structure type is s subtype of a previous type, its slots are added to the ones of the super type.

STklos procedure

(struct-type? obj)

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

(let ((type (make-struct-type 'point #f '(x y))))
  (struct-type? type))         => #t

STklos procedure

(struct-type-slots structype)

Returns the slots of the structure type structype as a list.

(define point  (make-struct-type 'point #f '(x y)))
(define circle (make-struct-type 'circle point '(r)))
(struct-type-slots point)   => (x y)
(struct-type-slots circle)  => (x y r)

STklos procedure

(struct-type-parent structype)

Returns the super type of the structure type structype, if it exists or #f otherwise.

STklos procedure

(struct-type-name structype)

Returns the name associated to the structure type structype.

STklos procedure

(struct-type-change-writer! structype proc)

Change the default writer associated to structures of type structype to the proc procedure. The proc procedure must accept 2 arguments (the structure to write and the port wher the structure must be written in that order). The value returned by struct-type-change-writer! is the old writer associated to structype. To restore the standard structure writer for structype, use the special value #f.

(define point (make-struct-type 'point #f '(x y)))

(struct-type-change-writer!
  point
  (lambda (s port)
    (let ((type (struct-type s)))
      (format port "{~A" (struct-type-name type))
      ;; display the slots and their value
      (for-each (lambda (x)
       (format port " ~A=~S" x (struct-ref s x)))
     (struct-type-slots type))
      (format port "}"))))
(display (make-struct point 1 2)) |- {point x=1 y=2}

STklos procedure

(make-struct structype expr …​)

Returns a newly allocated instance of the structure type structype, whose slots are initialized to expr …​ If fewer expr than the number of instances are given to make-struct, the remaining slots are inialized with the special void value.

STklos procedure

(struct? obj)

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

(let* ((type (make-struct-type 'point #f '(x y)))
       (inst (make-struct type 1 2)))
  (struct? inst))         => #t

STklos procedure

(struct-type s)

Returns the structure type of the s structure

STklos procedure

(struct-ref s slot-name)

Returns the value associated to slot slot-name of the s structure.

(define point  (make-struct-type 'point #f '(x y)))
(define circle (make-struct-type 'circle point '(r)))
(define p (make-struct point 1 2))
(define c (make-struct circle 10 20 30))
(struct-ref p 'y) => 2
(struct-ref c 'r) => 30

STklos procedure

(struct-set! s slot-name value)

Stores value in the to slot slot-name of the s structure. The value returned by struct-set! is void.

(define point  (make-struct-type 'point #f '(x y)))
(define p (make-struct point 1 2))
(struct-ref p 'x) => 1
(struct-set! p 'x 0)
(struct-ref p 'x) => 0

STklos procedure

(struct-is-a? s structype)

Return a boolean that indicates if the structure s is of type structype. Note that if s is an instance of a subtype of S, it is considered also as an instance of type S.

(define point  (make-struct-type 'point #f '(x y)))
(define circle (make-struct-type 'circle point '(r)))
(define p (make-struct point 1 2))
(define c (make-struct circle 10 20 30))
(struct-is-a? p point)   => #t
(struct-is-a? c point)   => #t
(struct-is-a? p circle)  => #f
(struct-is-a? c circle)  => #t

STklos procedure

(struct→list s)

Returns the content of structure s as an A-list whose keys are the slots of the structure type of s.

(define point  (make-struct-type 'point #f '(x y)))
(define p (make-struct point 1 2))
(struct->list p) => ((x . 1) (y . 2))

4.10. Bytevectors

Bytevectors represent blocks of binary data. They are fixed-length sequences of bytes, where a byte is an exact integer in the range (0, 255). A bytevector is typically more space-efficient than a vector containing the same values.

The length of a bytevector is the number of elements that it contains. This number is a non-negative integer that is fixed when the bytevector is created. The valid indexes of a bytevector are the exact non-negative integers less than the length of the bytevector, starting at index zero as with vectors.

Bytevectors are written using the notation #u8(byte …​). For example, a bytevector of length 3 containing the byte 0 in element 0, the byte 10 in element 1, and the byte 5 in element 2 can be written as follows: #u8(0 10 5)

Bytevector constants are self-evaluating, so they do not need to be quoted in programs.

R7RS procedure

(bytevector? obj)

Returns #t if obj is a bytevector and returns #f otherwise.

R7RS procedure

(make-bytevector k)
(make-bytevector k byte)

Returns a newly allocated bytevector of k bytes. If If byte is given, then all elements of the bytevector are initialized to byte, otherwise the contents of each element is 0.

(make-bytevector 2 12) => #u8(12 12)
(make-bytevector 3)    => #u8(0 0 0)

R7RS procedure

(bytevector byte …​)

Returns a newly allocated bytevector containing its arguments.

(bytevector 1 3 5 1 3 5)   => #u8(1 3 5 1 3 5)
(bytevector)               => #u8()

R7RS procedure

(bytevector-length bytevector)

Returns the length of bytevector in bytes as an exact integer.

R7RS procedure

(bytevector-u8-ref bytevector k)

Returns the byte at index k of bytevector as an exact integer in the range [0..255]. It is an error if k is not a valid index of bytevector.

(bytevector-u8-ref #u8(1 1 2 3 5 8 13 21) 5)    => 8

STklos procedure

(bytevector-u8-set! bytevector k byte)

Stores byte as the k th byte of bytevector. It is an error if k is not a valid index of bytevector.

(let ((bv (bytevector 1 2 3 4)))
  (bytevector-u8-set! bv 1 3)
  bv)                             => #u8(1 3 3 4)

R7RS procedure

(bytevector-copy bytevector)
(bytevector-copy bytevector start)
(bytevector-copy bytevector start end)

Returns a newly allocated bytevector containing the bytes in bytevector between start and end.

(define a #u8(1 2 3 4 5))
(bytevector-copy a 2 4))       =>  #u8(3 4)

R7RS procedure

(bytevector-copy! to at from)
(bytevector-copy! to at from start)
(bytevector-copy! to at from start end)

Copies the bytes of bytevector from between start and end to bytevector to, starting at at. The order in which bytes are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary bytevector and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances.

It is an error if at is less than zero or greater than the length of to. It is also an error if (- (bytevector-length to) at) is less than (- end start).

(define a (bytevector 1 2 3 4 5))
(define b (bytevector 10 20 30 40 50))
(bytevector-copy! b 1 a 0 2)
b                                  =>  #u8(10 1 2 40 50

R5RS procedure

(bytevector-append bytevector …​)

Returns a newly allocated bytevector whose elements are the concatenation of the elements in the given bytevectors.

(bytevector-append #u8(0 1 2) #u8(3 4 5))
                    =>  #u8(0 1 2 3 4 5)

R7RS procedure

(utf8→string bytevector)
(utf8→string bytevector start)
(utf8→string bytevector start end)
(string→utf8 string)
(string→utf8 string start)
(string→utf8 string start end)

These procedures translate between strings and bytevectors that encode those strings using the UTF-8 encoding. The utf8→string procedure decodes the bytes of a bytevector between start and end and returns the corresponding string; the string→utf8 procedure encodes the characters of a string between start and end and returns the corresponding bytevector.

It is an error for bytevector to contain invalid UTF-8 byte sequences.

(utf8->string #u8(#x41))   => "A"
(string->utf8 "λ")         => #u8((#xce #xbb)

4.11. Control features

R5RS procedure

(procedure? obj)

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

(procedure? car)                            =>  #t
(procedure? 'car)                           =>  #f
(procedure? (lambda (x) (* x x)))           =>  #t
(procedure? '(lambda (x) (* x x)))          =>  #f
(call-with-current-continuation procedure?) =>  #t

R5RS procedure

(apply proc arg1 …​ args)

Proc must be a procedure and args must be a list. Calls proc with the elements of the list

(append (list arg1 ...) args)

as the actual arguments.

(apply + (list 3 4))              =>  7

(define compose
  (lambda (f g)
     (lambda args
       (f (apply g args)))))

((compose sqrt *) 12 75)          =>  30

R5RS procedure

(map proc list1 list2 …​)

The list`s must be lists, and `proc must be a procedure taking as many arguments as there are lists and returning a single value. If more than one list is given, then they must all be the same length. Map applies proc element-wise to the elements of the `list`s and returns a list of the results, in order. The dynamic order in which proc is applied to the elements of the lists is unspecified.

(map cadr '((a b) (d e) (g h)))   =>  (b e h)

(map (lambda (n) (expt n n))
     '(1 2 3 4 5))                =>  (1 4 27 256 3125)

(map + '(1 2 3) '(4 5 6))         =>  (5 7 9)

(let ((count 0))
  (map (lambda (ignored)
      (set! count (+ count 1))
      count)
       '(a b)))                   =>  (1 2) ,(emph "or") (2 1)

R7RS procedure

(string-map proc string1 string2 …​)

The strings must be strings, and proc must be a procedure taking as many arguments as there are strings and returning a single value. If more than one string is given and not all strings have the same length, string-map terminates when the shortest list runs out. String-map applies proc element-wise to the elements of the strings and returns a string of the results, in order. The dynamic order in which proc is applied to the elements of the strings is unspecified.

(string-map char-downcase "AbdEgH")
         => "abdegh"

(string-map
  (lambda (c)
    (integer->char (+ 1 (char->integer c))))
  "HAL")
         => "IBM"

(string-map (lambda (c k)
           (if (eqv? k #u)
               (char-upcase c)
               (char-downcase c)))
         "studlycaps"
         "ululululul")
      => "StUdLyCaPs"

R7RS procedure

(vector-map proc vector1 vector2 …​)

The vectors must be vectors, and proc must be a procedure taking as many arguments as there are vectors and returning a single value. If more than one vector is given and not all vectors have the same length, vector-map terminates when the shortest list runs out. Vector-map applies proc element-wise to the elements of the vectors and returns a vector of the results, in order. The dynamic order in which proc is applied to the elements of the vectors is unspecified.

(vector-map cadr '#((a b) (d e) (g h)))
    =>  #(b e h)

(vector-map (lambda (n) (expt n n))
         '#(1 2 3 4 5))
    => #(1 4 27 256 3125)

(vector-map + '#(1 2 3) '#(4 5 6))
    => #(5 7 9)

(let ((count 0))
  (vector-map
    (lambda (ignored)
      (set! count (+ count 1))
      count)
    '#(a b)))
    => #(1 2) or #(2 1)

R5RS procedure

(for-each proc list1 list2 …​)

The arguments to for-each are like the arguments to map, but for-each calls proc for its side effects rather than for its values. Unlike map, for-each is guaranteed to call proc on the elements of the lists in order from the first element(s) to the last, and the value returned by for-each is void.

(let ((v (make-vector 5)))
  (for-each (lambda (i)
              (vector-set! v i (* i i)))
            '(0 1 2 3 4))
  v)                                =>  #(0 1 4 9 16)

R7RS procedure

(string-for-each proc string1 string2 …​)

The arguments to string-for-each are like the arguments to string-map, but string-for-each calls proc for its side effects rather than for its values. Unlike string-map, string-for-each is guaranteed to call proc on the elements of the lists in order from the first element(s) to the last, and the value returned by string-for-each is unspecified. If more than one string is given and not all strings have the same length, string-for-each terminates when the shortest string runs out.

(let ((v (list)))
  (string-for-each (lambda (c) (set! v (cons (char->integer c) v)))
                   "abcde")
   v)
       => (101 100 99 98 97)

R7RS procedure

(vector-for-each proc vector1 vector2 …​)

The arguments to vector-for-each are like the arguments to vector-map, but vector-for-each calls proc for its side effects rather than for its values. Unlike vector-map, vector-for-each is guaranteed to call proc on the elements of the lists in order from the first element(s) to the last, and the value returned by vector-for-each is unspecified. If more than one vector is given and not all vectors have the same length, vector-for-each terminates when the shortest vector runs out.

(let ((v (make-vector 5)))
  (vector-for-each (lambda (i) (vector-set! v i (* i i)))
                '#(0 1 2 3 4))
  v)
       => #(0 1 4 9 16)

STklos procedure

(every pred list1 list2 …​)

every applies the predicate pred across the lists, returning true if the predicate returns true on every application.

If there are n list arguments list1 …​ listn, then pred must be a procedure taking n arguments and returning a boolean result.

every applies pred to the first elements of the listi parameters. If this application returns false, every immediately returns #f. Otherwise, it iterates, applying pred to the second elements of the listi parameters, then the third, and so forth. The iteration stops when a false value is produced or one of the lists runs out of values. In the latter case, every returns the true value produced by its final application of pred. The application of pred to the last element of the lists is a tail call.

If one of the listi has no elements, every simply returns #t.

Like any, every’s name does not end with a question mark — this is to indicate that it does not return a simple boolean (#t` or #f), but a general value.

STklos procedure

(any pred list1 list2 …​)

any applies the predicate across the lists, returning true if the predicate returns true on any application.

If there are n list arguments list1 …​ listn, then pred must be a procedure taking n arguments.

any applies pred to the first elements of the listi parameters. If this application returns a true value, any immediately returns that value. Otherwise, it iterates, applying pred to the second elements of the listi parameters, then the third, and so forth. The iteration stops when a true value is produced or one of the lists runs out of values; in the latter case, any returns #f. The application of pred to the last element of the lists is a tail call.

Like every, any’s name does not end with a question mark — this is to indicate that it does not return a simple boolean (#t` or #f), but a general value.

(any integer? '(a 3 b 2.7))   => #t
(any integer? '(a 3.1 b 2.7)) => #f
(any < '(3 1 4 1 5)
       '(2 7 1 8 2))          => #t

R5RS procedure

(call-with-current-continuation proc)
(call/cc proc)

Proc must be a procedure of one argument. The procedure call-with-current-continuation packages up the current continuation (see the rationale below) as an "escape procedure" and passes it as an argument to proc. The escape procedure is a Scheme procedure that, if it is later called, will abandon whatever continuation is in effect at that later time and will instead use the continuation that was in effect when the escape procedure was created. Calling the escape procedure may cause the invocation of before and after thunks installed using dynamic-wind.

The escape procedure accepts the same number of arguments as the continuation to the original call to call-with-current-continuation. Except for continuations created by the call-with-values procedure, all continuations take exactly one value.

The escape procedure that is passed to proc has unlimited extent just like any other procedure in Scheme. It may be stored in variables or data structures and may be called as many times as desired.

The following examples show only the most common ways in which call-with-current-continuation is used. If all real uses were as simple as these examples, there would be no need for a procedure with the power of call-with-current-continuation.

(call-with-current-continuation
  (lambda (exit)
    (for-each (lambda (x)
                (if (negative? x)
                    (exit x)))
              '(54 0 37 -3 245 19))
    #t))                                =>  -3

(define list-length
  (lambda (obj)
    (call-with-current-continuation
      (lambda (return)
        (letrec ((r
                  (lambda (obj)
                    (cond ((null? obj) 0)
                          ((pair? obj)
                           (+ (r (cdr obj)) 1))
                          (else (return #f))))))
          (r obj))))))

(list-length '(1 2 3 4))                =>  4
(list-length '(a b . c))                =>  #f
common use of call-with-current-continuation is for structured, non-local exits from loops or procedure bodies, but in fact call-with-current-continuation is extremely useful for implementing a wide variety of advanced control structures.

Whenever a Scheme expression is evaluated there is a continuation wanting the result of the expression. The continuation represents an entire (default) future for the computation. If the expression is evaluated at top level, for example, then the continuation might take the result, print it on the screen, prompt for the next input, evaluate it, and so on forever. Most of the time the continuation includes actions specified by user code, as in a continuation that will take the result, multiply it by the value stored in a local variable, add seven, and give the answer to the top level continuation to be printed. Normally these ubiquitous continuations are hidden behind the scenes and programmers do not think much about them. On rare occasions, however, a programmer may need to deal with continuations explicitly. Call-with-current-continuation allows Scheme programmers to do that by creating a procedure that acts just like the current continuation.

call/cc is just another name for call-with-current-continuation.

STklos procedure

(call/ec proc)

call/ec is an short name for call-with-escape-continuation. call/ec calls proc with one parameter, which is the current escape continuation (a continuation which can only be used to abort a computation and hence cannot be "re-enterered").

(list 1
      (call/ec (lambda (return) (list 'a (return 'b) 'c)))
      3)        => (1 b 3)

call/ec is cheaper than the full call/cc. It is particularily useful when all the power of call/cc is not needded.

R5RS procedure

(values obj …​)

Delivers all of its arguments to its continuation.

R5RS imposes to use multiple values in the context of a call-with-values. In STklos, if values is not used with call-with-values, only the first value is used (i.e. others values are ignored)).

R5RS procedure

(call-with-values producer consumer)

Calls its producer argument with no values and a continuation that, when passed some values, calls the consumer procedure with those values as arguments. The continuation for the call to consumer is the continuation of the call to call-with-values.

(call-with-values (lambda () (values 4 5))
                  (lambda (a b) b))                =>  5

(call-with-values * -)                             =>  -1

STklos syntax

(receive <formals> <expression> <body>)

This form is defined in SRFI-8 (Receive: Binding to multiple values). It simplifies the usage of multiple values. Specifically, <formals> can have any of three forms:

  • (<variable1> …​ <variablen>): The environment in which the receive-expression is evaluated is extended by binding <variable1>, …​, <variablen> to fresh locations.
    The <expression> is evaluated, and its values are stored into those locations. (It is an error if <expression> does not have exactly n values.)

  • <variable>: The environment in which the receive-expression is evaluated is extended by binding <variable> to a fresh location.
    The <expression> is evaluated, its values are converted into a newly allocated list, and the list is stored in the location bound to <variable>.

  • (<variable1> …​ <variablen> . <variablen+1>): The environment in which the receive-expression is evaluated is extended by binding <variable1>, …​, <variablen+1> to fresh locations. The <expression> is evaluated. Its first n values are stored into the locations bound to <variable1> …​ <variablen>. Any remaining values are converted into a newly allocated list, which is stored into the location bound to <variablen+1>. (It is an error if <expression> does not have at least n values.

In any case, the expressions in <body> are evaluated sequentially in the extended environment. The results of the last expression in the body are the values of the receive-expression.

(let ((n 123))
  (receive (q r)
     (values (quotient n 10) (modulo n 10))
     (cons q r)))
              => (12 . 3)

R5RS procedure

(dynamic-wind before thunk after)

Calls thunk without arguments, returning the result(s) of this call. Before and after are called, also without arguments, as required by the following rules (note that in the absence of calls to continuations captured using call-with-current-continuation the three arguments are called once each, in order). Before is called whenever execution enters the dynamic extent of the call to thunk and after is called whenever it exits that dynamic extent. The dynamic extent of a procedure call is the period between when the call is initiated and when it returns. In Scheme, because of call-with-current-continuation, the dynamic extent of a call may not be a single, connected time period. It is defined as follows:

  • The dynamic extent is entered when execution of the body of the called procedure begins.

  • The dynamic extent is also entered when execution is not within the dynamic extent and a continuation is invoked that was captured (using call-with-current-continuation) during the dynamic extent.

  • It is exited when the called procedure returns.

  • It is also exited when execution is within the dynamic extent and a continuation is invoked that was captured while not within the dynamic extent.

If a second call to dynamic-wind occurs within the dynamic extent of the call to thunk and then a continuation is invoked in such a way that the afters from these two invocations of dynamic-wind are both to be called, then the after associated with the second (inner) call to dynamic-wind is called first.

If a second call to dynamic-wind occurs within the dynamic extent of the call to thunk and then a continuation is invoked in such a way that the befores from these two invocations of dynamic-wind are both to be called, then the before associated with the first (outer) call to dynamic-wind is called first.

If invoking a continuation requires calling the before from one call to dynamic-wind and the after from another, then the after is called first.

The effect of using a captured continuation to enter or exit the dynamic extent of a call to before or after is undefined.

(let ((path '())
      (c #f))
  (let ((add (lambda (s)
               (set! path (cons s path)))))
    (dynamic-wind
      (lambda () (add 'connect))
      (lambda ()
        (add (call-with-current-continuation
               (lambda (c0)
                 (set! c c0)
                 'talk1))))
      (lambda () (add 'disconnect)))
    (if (< (length path) 4)
        (c 'talk2)
        (reverse path))))
                  =>  (connect talk1 disconnect
                       connect talk2 disconnect)

R5RS procedure

(eval expression environment)
(eval expression)

Evaluates expression in the specified environment and returns its value. Expression must be a valid Scheme expression represented as data. Environment may be a R5RS environment-specifier (interaction-environment, scheme-report-environment or null-environment) or a STklos module.

(eval '(* 7 3) (scheme-report-environment 5))
              => 21
(let ((f (eval '(lambda (f x) (f x x))
               (null-environment 5))))
  (f + 10))
              => 20
(define-module A
  (define x 1))
(eval '(cons x x) (find-module 'A))
              => (1 . 1)

R7RS procedure

(environment set1 …​)

This procedure returns a specifier for the environment that results by starting with an empty environment and then importing each set, considered as an import set, into it. The bindings of the environment represented by the specifier, as is the environment itself.

In STklos, - each set argument can be a list (specifying an R7RS library) or a symbol (specifying a module). - the return environment is an R7RS library (which can be passed to eval).

(eval '(* 7 3) (environment '(scheme base)))    => 21

(let ((f (eval '(lambda (f x) (f x x))
               (null-environment 5))))
  (f + 10))                                     => 20

(eval '(define foo 32)
      (environment '(scheme base)))             => errror

(let ((e (environment '(only (scheme base) + -)
                      '(only (scheme write) display))))
  (length (module-symbols e)))                  => 3

(let ((e (environment '(prefix (only (scheme base) car)
                               foo-))))
   (module-symbols e))                            => (foo-car)

R5RS procedure

(scheme-report-environment)
(scheme-report-environment version)

Returns a specifier for an environment that contains the bindings defined in the R5RS report.

In STklos, scheme-report-environment function can be called without the version number (defaults to 5).

R5RS procedure

(null-environment)
(null-environment version)

Returns a specifier for an environment that is empty except for the (syntactic) bindings for all syntactic keywords defined in the R5RS report.

In STklos, null-environment function can be called without the version number (defaults to 5).

R5RS procedure

(interaction-environment)

This procedure returns the environment in the expression are evaluated by default (the STklos module). The returned environment is mutable.

STklos procedure

(eval-from-string str)
(eval-from-string str module)
(eval-from-string-ci str)
(eval-from-string-ci str module)

Read an expression from str and evaluates it with eval. If a module is passed, the evaluation takes place in the environment of this module. Otherwise, the evaluation takes place in the environment returned by current-module. The primitive eval-from-string-ci uses the read-ci to read the form to evaluate.

(define x 10)
(define-module M
  (define x 100))
(eval-from-string "(+ x x)")                   => 20
(eval-from-string "(+ x x)" (find-module 'M))  => 200
(eval-from-string "(cons 'A 'B)")              => (A . B)
(eval-from-string-ci "(cons 'A 'B)")           => (a . b)

4.12. Input and Output

R5RS states that ports represent input and output devices. However, it defines only ports which are attached to files. In STklos, ports can also be attached to strings, to a external command input or output, or even be virtual (i.e. the behavior of the port is given by the user).

  • String ports are similar to file ports, except that characters are read from (or written to) a string rather than a file.

  • External command input or output ports are implemented with Unix pipes and are called pipe ports. A pipe port is created by specifying the command to execute prefixed with the string "| " (that is a pipe bar followed by a space). Specification of a pipe port can occur everywhere a file name is needed.

  • Virtual ports are created by supplying basic I/O functions at port creation time. These functions will be used to simulate low level accesses to a ``virtual device''. This kind of port is particularly convenient for reading or writing in a graphical window as if it was a file. Once a virtual port is created, it can be accessed as a normal port with the standard Scheme primitives.

4.12.1. Ports

R7RS procedure

(call-with-port port proc)

The call-with-port procedure calls proc with port as an argument. If proc returns, then the port is closed automatically and the values yielded by the proc are returned. If proc does not return, then the port must not be closed automatically unless it is possible to prove that the port will never again be used for a read or write operation.

It is an error if proc does not accept one argument.

R5RS procedure

(call-with-input-file string proc)
(call-with-output-file string proc)

String should be a string naming a file, and proc should be a procedure that accepts one argument. For call-with-input-file, the file should already exist. These procedures call proc with one argument: the port obtained by opening the named file for input or output. If the file cannot be opened, an error is signaled. If proc returns, then the port is closed automatically and the value(s) yielded by the proc is(are) returned. If proc does not return, then the port will not be closed automatically.

Because Scheme’s escape procedures have unlimited extent, it is possible to escape from the current continuation but later to escape back in. If implementations were permitted to close the port on any escape from the current continuation, then it would be impossible to write portable code using both call-with-current-continuation and call-with-input-file or call-with-output-file.

STklos procedure

(call-with-input-string string proc)

behaves as call-with1-input-file except that the port passed to proc is the sting port obtained from port.

(call-with-input-string "123 456"
  (lambda (x)
     (let* ((n1 (read x))
            (n2 (read x)))
        (cons n1 n2))))          => (123 . 456)

STklos procedure

(call-with-output-string proc)

Proc should be a procedure of one argument. Call-with-output-string calls proc with a freshly opened output string port. The result of this procedure is a string containing all the text that has been written on the string port.

(call-with-output-string
  (lambda (x) (write 123 x) (display "Hello" x))) => "123Hello"

R5RS procedure

(input-port? obj)
(output-port? obj)

Returns #t if obj is an input port or output port respectively, otherwise returns #f.

R7RS procedure

(textual-port? obj)
(binary-port? obj)

Returns #t if obj is a textual port or binary port respectively, otherwise returns #f.

R7RS procedure

(port? obj)

Returns #t if obj is an input port or an output port, otherwise returns #f.

STklos procedure

(input-string-port? obj)
(output-string-port? obj)

Returns #t if obj is an input string port or output string port respectively, otherwise returns #f.

STklos procedure

(input-bytevector-port? obj)
(output-bytevector-port? obj)

Returns #t if obj is an input bytevector port or output bytevector port respectively, otherwise returns #f.

STklos procedure

(input-file-port? obj)
(output-file-port? obj)

Returns #t if obj is a file input port or a file output port respectively, otherwise returns #f.

R7RS procedure

(input-port-open? port)
(output-port-open? port)

Returns #t if port is still open and capable of performing input or output, respectively, and #f otherwise.

STklos procedure

(input-virtual-port? obj)
(output-virtual-port? obj)

Returns #t if obj is a virtual input port or a virtual output port respectively, otherwise returns #f.

STklos procedure

(interactive-port? port)

Returns #t if port is connected to a terminal and #f otherwise.

R5RS procedure

(current-input-port obj)
(current-output-port obj)

Returns the current default input or output port.

STklos procedure

(current-error-port obj)

Returns the current default error port.

R5RS procedure

(with-input-from-file string thunk)
(with-output-to-file string thunk)

String should be a string naming a file, and proc should be a procedure of no arguments. For with-input-from-file, the file should already exist. The file is opened for input or output, an input or output port connected to it is made the default value returned by current-input-port or current-output-port (and is used by (read), (write obj), and so forth), and the thunk is called with no arguments. When the thunk returns, the port is closed and the previous default is restored. With-input-from-file and with-output-to-file return(s) the value(s) yielded by thunk.

The following example uses a pipe port opened for reading. It permits to read all the lines produced by an external ,(emph "ls") command (i.e. the output of the ,(emph "ls") command is ,(emph "redirected") to the Scheme pipe port).

(with-input-from-file "| ls -ls"
  (lambda ()
    (do ((l (read-line) (read-line)))
        ((eof-object? l))
      (display l)
      (newline))))

Hereafter is another example of Unix command redirection. This time, it is the standard input of the Unix command which is redirected.

(with-output-to-file "| mail root"
  (lambda ()
    (display "A simple mail from Scheme")
    (newline)))

STklos procedure

(with-error-to-file string thunk)

This procedure is similar to with-output-to-file, excepted that it uses the current error port instead of the output port.

STklos procedure

(with-input-from-string string thunk)

A string port is opened for input from string. Current-input-port is set to the port and thunk is called. When thunk returns, the previous default input port is restored. With-input-from-string returns the value(s) computed by thunk.

(with-input-from-string "123 456"
  (lambda () (read)))                       =>  123

STklos procedure

(with-output-to-string thunk)

A string port is opened for output. Current-output-port is set to it and thunk is called. When thunk returns, the previous default output port is restored. With-output-to-string returns the string containing the text written on the string port.

(with-output-to-string
   (lambda () (write 123) (write "Hello"))) => "123\"Hello\""

STklos procedure

(with-input-from-port port thunk)
(with-output-to-port port thunk)
(with-error-to-port port thunk)

Port should be a port, and proc should be a procedure of no arguments. These procedures do a job similar to the with-…​-file counterparts excepted that they use an open port instead of string specifying a file name

R5RS procedure

(open-input-file filename)

Takes a string naming an existing file and returns an input port capable of delivering characters from the file. If the file cannot be opened, an error is signalled.

if filename starts with the string "| ", this procedure returns a pipe port. Consequently, it is not possible to open a file whose name starts with those two characters.

STklos procedure

(open-input-string str)

Returns an input string port capable of delivering characters from str.

R7RS procedure

(open-input-bytevector bytevector)

Takes a bytevector and returns a binary input port that delivers bytes from the bytevector.

STklos procedure

(open-input-virtual :key (read-char #f) (ready? #f) (eof? #f) (close #f))

Returns a virtual port using the read-char procedure to read a character from the port, ready? to know if there is any data to read from the port, eof? to know if the end of file is reached on the port and finally close to close the port. All these procedure takes one parameter which is the port from which the input takes place. Open-input-virtual accepts also the special value #f for the I/O procedures with the following conventions:

  • if read-char or eof? is #f, any attempt to read the virtual port will return an eof object;

  • if ready? is #f, the file is always ready for reading;

  • if close is #f, no action is done when the port is closed.

Hereafter is a possible implementation of open-input-string using virtual ports:

(define (open-input-string str)
  (let ((index 0))
    (open-input-virtual
       :read-char (lambda (p)
                    ;; test on eof is already done by the system
                    (let ((res (string-ref str index)))
                      (set! index (+ index 1))
                      res))
       :eof? (lambda (p) (>= index (string-length str))))))

R5RS procedure

(open-output-file filename)

Takes a string naming an output file to be created and returns an output port capable of writing characters to a new file by that name. If the file cannot be opened, an error is signalled. If a file with the given name already exists, it is rewritten.

if filename starts with the string "| ", this procedure returns a pipe port. Consequently, it is not possible to open a file whose name starts with those two characters.

STklos procedure

(open-output-string)

Returns an output string port capable of receiving and collecting characters.

R7RS procedure

(open-output-bytevector)

Returns a binary output port that will accumulate bytes for retrieval by get-output-bytevector.

STklos procedure

(open-output-virtual :key (write-char #f) (write-string #f) (flush #f) (close #f))

Returns a virtual port using the write-char procedure to write a character to the port, write-string to write a string to the port, flush to (eventuelly) flush the characters on the port and finally close`to close the port. `Write-char takes two parameters: a character and the port to which the output must be done. write-string takes two parameters: a string and a port. Flush and Close take one parameter which is the port on which the action must be done. Open-output-virtual accepts also the special value #f for the I/O procedures. If a procedure is #f nothing is done on the corresponding action.

Hereafter is a (very inefficient) implementation of a variant of open-output-string using virtual ports. The value of the output string is printed when the port is closed:

(define (open-output-string)
  (let ((str ""))
    (open-output-virtual
       :write-char (lambda (c p)
                     (set! str (string-append str (string c))))
       :write-string (lambda (s p)
                       (set! str (string-append str s)))
       :close (lambda (p) (write str) (newline)))))
write-string is mainly used for writing strings and is generally more efficient than writing the string character by character. However, if write-string is not provided, strings are printed with write-char. On the other hand, if write-char is absent, characters are written by successive allocation of one character strings.

Hereafter is another example: a virtual file port where all characters are converted to upper case:

(define (open-output-uppercase-file file)
  (let ((out (open-file file "w")))
    (and out
         (open-output-virtual
             :write-string (lambda (s p)
                             (display (string-upper s) out))
             :close (lambda (p)
                      (close-port out))))))

STklos procedure

(open-file filename mode)

Opens the file whose name is filename with the specified string mode which can be:

  • "r" to open the file for reading. The stream is positioned at the beginning of the file.

  • "r+" to open the file for reading and writing. The stream is positioned at the beginning of the file.

  • "w" to truncate the file to zero length or create the file for writing. The stream is positioned at the beginning of the file.

  • "w+" to open the file for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.

  • "a" to open the file for writing. The file is created if it does not exist. The stream is positioned at the end of the file.

  • "a+" to open the file for reading and writing. The file is created if it does not exist. The stream is positioned at the end of the file.

If the file can be opened, open-file returns the textual port associated with the given file, otherwise it returns #f. Here again, the magic string "| " permits to open a pipe port. (In this case mode can only be "r" or "w".)

STklos procedure

(get-output-string port)

Returns a string containing all the text that has been written on the output string port.

 (let ((p (open-output-string)))
    (display "Hello, world" p)
    (get-output-string p))         => "Hello, world"

STklos procedure

(get-output-bytevector port)

Returns a bytevector consisting of the bytes that have been output to the port so far in the order they were output.

 (let ((p (open-output-bytevector)))
    (u8-write 65)
    (u8-write 66)
    (get-output-bytevector p))         => #u8(65 66)

R5RS procedure

(close-input-port port)
(close-output-port port)

Closes the port associated with port, rendering the port incapable of delivering or accepting characters. These routines have no effect if the port has already been closed. The value returned is void.

R7RS procedure

(close-port port)

Closes the port associated with port.

STklos procedure

(port-rewind port)

Sets the port position to the beginning of port. The value returned by port-rewind is void.

STklos procedure

(port-seek port pos)
(port-seek port pos whence)

Sets the file position for the given port to the position pos. The new position, measured in bytes, is obtained by adding pos bytes to the position specified by whence. If passed, whence must be one of :start, :current or :end. The resulting position is relative to the start of the file, the current position indicator, or end-of-file, respectively. If whence is omitted, it defaults to :start.

After using port-seek, the value returned by port-current-line may be incorrect.

STklos procedure

(port-current-line)
(port-current-line port)

Returns the current line number associated to the given input port as an integer. The port argument may be omitted, in which case it defaults to the value returned by current-input-port.

The port-seek, read-chars and read-chars! procedures generally break the line-number. After using one of these procedures, the value returned by port-current-line will be -1 (except a port-seek at the beginning of the port reinitializes the line counter).

STklos procedure

(port-current-position)
(port-current-position port)

Returns the position associated to the given port as an integer (i.e. number of characters from the beginning of the port). The port argument may be omitted, in which case it defaults to the value returned by current-input-port.

STklos procedure

(port-file-name port)

Returns the file name used to open port; port must be a file port.

STklos procedure

(port-idle-register! port thunk)
(port-idle-unregister! port thunk)
(port-idle-reset! port)

port-idle-register! allows to register thunk as an idle handler when reading on port. That means that thunk will be called continuously while waiting an input on port (and only while using a reading primitive on this port). port-idle-unregister! can be used to unregister a handler previously set by port-idle-register!. The primitive port-idle-reset! unregisters all the handlers set on port.

Hereafter is a (not too realistic) example: a message will be displayed repeatedly until a sexpr is read on the current input port.

(let ((idle (lambda () (display "Nothing to read!\n"))))
  (port-idle-register! (current-input-port) idle)
  (let ((result (read)))
    (port-idle-unregister! (current-input-port) idle)
    result))

STklos procedure

(port-closed? port)
(port-open? port)

port-closed? returns #t if port is closed and #f otherwise. On the contrary, port-open? returns #t if port is open and #f otherwise.

port-closed? was the usual STklos function to test if a port is closed. port-open? has been added to be the companion of the R7RS functions input-port-open? and output-port-open?

STklos procedure

(port-close-hook-set! port thunk)

Associate the procedure thunk to port. The thunk will be called the first time port is closed.

(let* ((tmp (temporary-file-name))
       (p   (open-output-file tmp))
       (foo #t))
  (port-close-hook-set! p
                     (lambda()
                       (remove-file tmp)
                       (set! foo #t)))
  (close-port p)
  foo)

STklos procedure

(port-close-hook port)

Returns the user close procedure associated to the given port.

 The following procedures are defined in *link:http://srfi.schemers.org/srfi-192/srfi-192.html[SRFI-192]* (_Port Positioning_)(((SRFI-192))) which is fully
  supported:((("SRFI-192")))
+++<a id='P_port-has-port-position?'></a>+++
(((port-has-port-position?)))

STklos procedure

(port-has-port-position? port)

The port-has-port-position? procedure returns #t if the port supports the port-position operation, and #f otherwise. If the port does not support the operation, port-position signals an error.

STklos procedure

(port-position port)

The port-position procedure returns an object representing the information state about the port current position as is necessary to save and restore that position. This value can be useful only as the pos argument to set-port-position!, if the latter is even supported on the port. However, if the port is binary and the object is an exact integer, then it is the position measured in bytes, and can be used to compute a new position some specified number of bytes away.

STklos procedure

(port-has-set-port-position!? port)

The port-has-set-port-position!? procedure returns #t if the port supports the set-port-position! operation, and #f otherwise.

STklos procedure

(set-port-position! port pos)

For a textual port, it is implementation-defined what happens if pos is not the return value of a call to port-position on port. However, a binary port will also accept an exact integer, in which case the port position is set to the specified number of bytes from the beginning of the port data. If this is not sufficient information to specify the port state, or the specified position is uninterpretable by the port, an error satisfying i/o-invalid-position-error? is signaled.

If set-port-position! procedure is invoked on a port that does not support the operation or if pos is not in the range of valid positions of port, set-port-position! signals an error. Otherwise, it sets the current position of the port to pos. If port is an output port, set-port-position! first flushes port (even if the port position will not change).

If port is a binary output port and the current position is set beyond the current end of the data in the underlying data sink, the object is not extended until new data is written at that position. The contents of any intervening positions are unspecified. It is also possible to set the position of a binary input port beyond the end of the data in the data source, but a read will fail unless the data has been extended by other means. File ports can always be extended in this manner within the limits of the underlying operating system. In other types of ports, if an attempt is made to set the position beyond the current end of data in the underlying object, and the object does not support extension, an error satisfying i/o-invalid-position-error? is signaled.

STklos procedure

(make-i/o-invalid-position-error pos)

Returns a condition object which satisfies i/o-invalid-position-error?. The pos argument represents a position passed to set-position!.

STklos procedure

(i/o-invalid-position-error? obj)

Returns #t if obj is an object created by make-i/o-invalid-position-error? or an object raised in the circumstances described in SRFI-192 (attempt to access an invalid position in the stream), or #f if it is not.

4.12.2. Input

R5RS procedure

(read)
(read port)

Read converts external representations of Scheme objects into the objects themselves. Read returns the next object parsable from the given input port, updating port to point to the first character past the end of the external representation of the object.

If an end of file is encountered in the input before any characters are found that can begin an object, then an end of file object is returned. The port remains open, and further attempts to read will also return an end of file object. If an end of file is encountered after the beginning of an object’s external representation, but the external representation is incomplete and therefore not parsable, an error is signalled.

The port argument may be omitted, in which case it defaults to the value returned by current-input-port. It is an error to read from a closed port.

STklos read supports the SRFI-10 #,() form that can be used to denote values that do not have a convenient printed representation. See the SRFI document for more information.

STklos procedure

(read-ci)
(read-ci port)

Read-ci result is identical to read except that symbols are always read as case insensitive.

STklos procedure

(read-with-shared-structure)
(read-with-shared-structure port)
(read/ss)
(read/ss port)

read-with-shared-structure is identical to read. It has been added to be compatible with ,(link-srfi 38). STklos always knew how to deal with recursive input data. read/ss is only a shorter name for read-with-shared-structure.

STklos procedure

(define-reader-ctor tag proc)

This procedure permits to define a new user to reader constructor procedure at run-time. It is defined in ,(link-srfi 10) document. See SRFI document for more information.

(define-reader-ctor 'rev (lambda (x y) (cons y x)))
(with-input-from-string "#,(rev 1 2)" read)
                             => (2 . 1)

R5RS procedure

(read-char)
(read-char port)

Returns the next character available from the input port, updating the port to point to the following character. If no more characters are available, an end of file object is returned. Port may be omitted, in which case it defaults to the value returned by current-input-port.

STklos procedure

(read-bytes size)
(read-bytes size port)

Returns a newly allocated string made of size characters read from port. If less than size characters are available on the input port, the returned string is smaller than size and its size is the number of available characters. Port may be omitted, in which case it defaults to the value returned by current-input-port.

This function was previously called read-chars. Usage of the old name is deprecated.

R7RS procedure

(read-bytevector k)
(read-bytevector k port)

Reads the next k bytes, or as many as are available before the end of file, from the textual input port into a newly allocated string in left-to-right order and returns the string. If no characters are available before the end of file, an end-of-file object is returned.

R7RS procedure

(read-bytevector! k)
(read-bytevector! k port)
(read-bytevector! k port start)
(read-bytevector! k port start end)

Reads the next end - start bytes, or as many as are available before the end of file, from the binary input port into bytevector in left-to-right order beginning at the start position. If end is not supplied, reads until the end of bytevector has been reached. If start is not supplied, reads beginning at position 0. Returns the number of bytes read. If no bytes are available, an end-of-file object is returned.

STklos procedure

(read-bytes! str)
(read-bytes! str port)

This function reads the characters available from port in the string str by chuncks whose size is equal to the length of str. The value returned by read-bytes! is an integer indicating the number of characters read. Port may be omitted, in which case it defaults to the value returned by current-input-port.

This function is similar to read-bytes except that it avoids to allocate a new string for each read.

(define (copy-file from to)
  (let* ((size 1024)
         (in  (open-input-file from))
         (out (open-output-file to))
         (s   (make-string size)))
    (let Loop ()
      (let ((n (read-bytes! s in)))
        (cond
          ((= n size)
             (write-chars s out)
             (Loop))
          (else
             (write-chars (substring s 0 n) out)
             (close-port out)))))))
This function was previously called read-chars!. Usage of the old name is deprecated.

STklos procedure

(read-byte)
(read-byte port)

Returns the next character available from the input port as an integer. If the end of file is reached, this function returns the end of file object.

R5RS procedure

(peek-char)
(peek-char port)

Returns the next character available from the input port, without updating the port to point to the following character. If no more characters are available, an end of file object is returned. Port may be omitted, in which case it defaults to the value returned by current-input-port.

The value returned by a call to peek-char is the same as the value that would have been returned by a call to read-char with the same port. The only difference is that the very next call to read-char or peek-char on that port will return the value returned by the preceding call to peek-char. In particular, a call to peek-char on an interactive port will hang waiting for input whenever a call to read-char would have hung.

STklos procedure

(peek-byte)
(peek-byte port)

Returns the next character available from the input port, without updating the port to point to the following character. Whereas peek-char returns a character, this function returns an integer between 0and 255.

R5RS procedure

(eof-object? obj)

Returns #t if obj is an end of file object, otherwise returns #f.

STklos procedure

(eof-object)

end of file Returns an end of file object. Note that the special notation #eof is another way to return such an end of file object.

R5RS procedure

(char-ready?)
(char-ready? port)

Returns #t if a character is ready on the input port and returns #f otherwise. If char-ready returns #t then the next read-char operation on the given port is guaranteed not to hang. If the port is at end of file then char-ready? returns #t. Port may be omitted, in which case it defaults to the value returned by current-input-port.

R7RS procedure

(read-string k)
(read-string k port)

Reads the next k characters, or as many as are available before the end of file, from the textual input port into a newly allocated string in left-to-right order and returns the string. If no characters are available before the end of file, an end-of-file object is returned.

R7RS procedure

(read-u8)
(read-u8 port)

Returns the next byte available from the binary input port, updating the port to point to the following byte. If no more bytes are available, an end-of-file object is returned.

This function is similar to the read-byte function, excepted that it can be used only on a binary port.

R7RS procedure

(peek-u8)
(peek-u8 port)

Returns the next byte available from the binary input port, but without updating the port to point to the following byte. If no more bytes are available, an end-of-file object is returned.

This function is similar to the peek-byte function, excepted that it can be used only on a binary port.

R7RS procedure

(u8-ready?)
(u8-ready? port)

Returns #t if a byte is ready on the binary input port and returns #f otherwise. If u8-ready? returns #t then the next read-u8 operation on the given port is guaranteed not to hang. If the port is at end of file then u8-ready? returns #t.

STklos procedure

(read-line)
(read-line port)

Reads the next line available from the input port port. This function returns 2 values: the first one is the string which contains the line read, and the second one is the end of line delimiter. The end of line delimiter can be an end of file object, a character or a string in case of a multiple character delimiter. If no more characters are available on port, an end of file object is returned. Port may be omitted, in which case it defaults to the value returned by current-input-port.

As said in primitive values, if read-line is not used in the context of call-with-values, the second value returned by this procedure is ignored.

STklos procedure

(read-from-string str)

Performs a read from the given str. If str is the empty string, an end of file object is returned. Read-from-string-ci uses read-ci to read.

(read-from-string "123 456") => 123
(read-from-string "")        => an eof object
(read-from-string "ABC")     => ABC
(read-from-string-ci "ABC")  => abc

STklos procedure

(port→string port)
(port→sexp-list port)
(port→string-list port)

All these procedures take a port opened for reading. Port→string reads port until the it reads an end of file object and returns all the characters read as a string. Port→sexp-list and port→string-list do the same things except that they return a list of S-expressions and a list of strings respectively. For the following example we suppose that file "foo" is formed of two lines which contains respectively the number 100 and the string "bar".

(port->sexp-list (open-input-file "foo"))   => (100 "bar")
(port->string-list (open-input-file "foo")) => ("100" ""bar"")

4.12.3. Output

R5RS procedure

(write obj)
(write obj port)

Writes a written representation of obj to the given port. Strings that appear in the written representation are enclosed in doublequotes, and within those strings backslash and doublequote characters are escaped by backslashes. Character objects are written using the ,(emph "#\") notation. Write returns an unspecified value. The port argument may be omitted, in which case it defaults to the value returned by current-output-port.

R7RS procedure

(write-shared obj)
(write-shared obj port)

Writes a written representation of obj to the given port. The main difference with the write procedure is that write* handles data structures with cycles. Circular structure written by this procedure use the "#n=")) and "#n#")) notations (see Section 1.2.4).

This function is also called write*. The name write* was the name used by STklos for write-shared before it was introduced in R7RS.

STklos procedure

(write-with-shared-structure obj)
(write-with-shared-structure obj port)
(write-with-shared-structure obj port optarg)
(write/ss obj)
(write/ss obj port)
(write/ss obj port optarg)

write-with-shared-structure has been added to be compatible with SRFI-38 (External representation of shared structures). It is is identical to write*, except that it accepts one more parameter (optarg). This parameter, which is not specified in SRFI-38, is always ignored. write/ss is only a shorter name for write-with-shared-structure.

R5RS procedure

(display obj)
(display obj port)

Writes a representation of obj to the given port. Strings that appear in the written representation are not enclosed in doublequotes, and no characters are escaped within those strings. Character objects appear in the representation as if written by write-char instead of by write. Display returns an unspecified value. The port argument may be omitted, in which case it defaults to the value returned by current-output-port.

Write is intended for producing machine-readable output and display is for producing human-readable output.
As required by R7RS does not loop forever when obj contains self-references.

STklos procedure

(display-shared obj)
(display-shared obj port)

The display-shared procedure is the same as display, except that shared structure are represented using datum labels.

STklos procedure

(display-simple obj)
(display-simple obj port)

The display-simple procedure is the same as display, except that shared structure is never represented using datum labels. This can cause display-simple not to terminate if obj contains circular structure.

R5RS procedure

(newline)
(newline port)

Writes an end of line to port. Exactly how this is done differs from one operating system to another. Returns an unspecified value. The port argument may be omitted, in which case it defaults to the value returned by current-output-port.

R7RS procedure

(write-string string)
(write-string string port)
(write-string string port start)
(write-string string port start end)

Writes the characters of string from start to end in left-to-right order to the textual output port.

R7RS procedure

(write-u8 byte)
(write-u8 byte port)

Writes the byte to the given binary output port.

R7RS procedure

(write-bytevector bytevector)
(write-bytevector bytevector port)
(write-bytevector bytevector port start)
(write-bytevector bytevector port start end)

Writes the bytes of bytevector from start to end in left-to-right order to the binary output port.

R5RS procedure

(write-char char)
(write-char char port)

Writes the character char (not an external representation of the character) to the given port and returns an unspecified value. The port argument may be omitted, in which case it defaults to the value returned by current-output-port.

STklos procedure

(write-chars str)
(write-chars str port)

Writes the characters of string str to the given port and returns an unspecified value. The port argument may be omitted, in which case it defaults to the value returned by current-output-port.

This function is generally faster than display for strings. Furthermore, this primitive does not use the buffer associated to port.

STklos procedure

(write-byte b)
(write-byte b port)

Write byte b to the port. b must be an exact integer in range between 0 and 255.

STklos procedure

(format port str obj …​)
(format str obj)

Writes the obj`s to the given `port, according to the format string str. Str is written literally, except for the following sequences:

  • ~a or ~A is replaced by the printed representation of the next obj.

  • ~s or ~S is replaced by the slashified printed representation of the next obj.

  • ~w or ~W is replaced by the printed representation of the next obj (circular structures are correctly handled and printed using write*).

  • ~d or ~D is replaced by the decimal printed representation of the next obj (which must be a number).

  • ~x or ~X is replaced by the hexadecimal printed representation of the next obj (which must be a number).

  • ~o or ~O is replaced by the octal printed representation of the next obj (which must be a number).

  • ~b or ~B is replaced by the binary printed representation of the next obj (which must be a number).

  • ~c or ~C is replaced by the printed representation of the next obj (which must be a character).

  • ~y or ~Y is replaced by the pretty-printed representation of the next obj. The standard pretty-printer is used here.

  • ~? is replaced by the result of the recursive call of format with the two next obj: the first item should be a string, and the second, a list with the arguments.

  • ~k or ~K is another name for ~?

  • ~[w[,d]]f or ~[w[,d]]F is replaced by the printed representation of next obj (which must be a number) with width w and d digits after the decimal. Eventually, d may be omitted.

  • ~~ is replaced by a single tilde character.

  • ~% is replaced by a newline

  • ~t or ~T is replaced by a tabulation character.

  • ~& is replaced by a newline character if it is known that the previous character was not a newline

  • ~_ is replaced by a space

  • ~h or ~H provides some help

Port can be a boolean or a port. If port is #t, output goes to the current output port; if port is #f, the output is returned as a string. Otherwise, the output is printed on the specified port.

   (format #f "A test.")        => "A test."
   (format #f "A ~a." "test")   => "A test."
   (format #f "A ~s." "test")   => "A "test"."
   (format "~8,2F" 1/3)         => "    0.33"
   (format "~6F" 32)            => "    32"
   (format "~1,2F" 4321)        => "4321.00"
   (format "~1,2F" (sqrt -3.9)) => "0.00+1.97i"
   (format "#d~d #x~x #o~o #b~b~%" 32 32 32 32)
                                => "#d32 #x20 #o40 #b100000n"
   (format #f "~&1~&~&2~&~&~&3~%")
                                => "n1n2n3n"
   (format "~a ~? ~a" 'a "~s" '(new) 'test)
                                => "a new test"
The second form of format is compliant with SRFI-28 (Basic Format Strings). That is, when port is omitted, the output is returned as a string as if port was given the value #f.
Since version 0.58, format is also compliant with SRFI-48 (Intermediate Format Strings).

STklos procedure

(flush-output-port)
(flush-output-port port)

Flushes the buffer associated with the given output port. The port argument may be omitted, in which case it defaults to the value returned by current-output-port

STklos procedure

(print obj …​)
(printerr obj …​)

These procedures display all their arguments followed by a newline. The procedure print uses the standard output port, whereas printerr uses the current error port

STklos procedure

(printf fmt obj …​)
(fprintf port fmt obj …​)
(eprintf fmt obj …​)

These procedures are specialized versions of format primitive. In these procedures, fmt is a string using the format conventions. printf outputs go on the current output port. fprintf outputs go on the specified port. eprintf outputs go on the current error port (note that eprintf always flushes the characters printed).

4.13. System interface

The STklos system interface offers all the functions defined in R7RS. Note, that the base implementation provides also a subset of the functions defined in SRFI-170 (POSIX API). These functions are described here.

Note, however that SRFI-170 is fully supported and accessing the other functions it defines can be done by requiring it, as the other SRFIs that STklos supports.

4.13.1. Loading code

R5RS / R7RS procedure

(load filename)
(load filename env)

Filename should be a string naming an existing file containing Scheme expressions. Load has been extended in STklos to allow loading of files containing Scheme compiled code as well as object files (aka shared objects). The loading of object files is not available on all architectures. The value returned by load is void.

The optional parameter env may be an environment specifier (as defined by R7RS) or a module. When env is specified, the loaded code is evaluated (or run) in the environment given by env. If omitted, (interaction-environment) is assumed. When env is specified as a module, it is mutable.

If the file whose name is filename cannot be located, load will try to find it in one of the directories given by "load-path" with the suffixes given by "load-suffixes".

R5RS defines only the one parameter version of load.

STklos procedure

(try-load filename)
(try-load filename env)

try-load tries to load the file named filename. As with load, try-load tries to find the file given the current load path and a set of suffixes if filename cannot be loaded. If try-load is able to find a readable file, it is loaded, and try-load returns #t. Otherwise, try-load retuns #f.

See the description of env environment in the [load] primitive.

STklos procedure

(find-path str)
(find-path str path)
(find-path str path suffixes)

In its first form, find-path returns the path name of the file that should be loaded by the procedure load given the name str. The string returned depends of the current load path and of the currently accepted suffixes.

The other forms of find-path are more general and allow to give a path list (a list of strings representing supposed directories) and a set of suffixes (given as a list of strings too) to try for finding a file. If no file is found, find-path returns #f.

For instance, on a "classical" Unix box:

(find-path "passwd" '("/bin" "/etc" "/tmp"))
            => "/etc/passwd"
(find-path "stdio" '("/usr" "/usr/include") '("c" "h" "stk"))
            => "/usr/include/stdio.h"

STklos procedure

(current-loading-file)

Returns the path of the file that is currently being loaded.

STklos procedure

(require string)
(provide string)
(require/provide string)
(provided? string)

Require loads the file whose name is string if it was not previously "provided". Provide permits to store string in the list of already provided files. Providing a file permits to avoid subsequent loads of this file. Require/provide is more or less equivalent to a require followed by a provide. Provided? returns #t if string was already provided; it returns #f otherwise.

4.13.2. File Primitives

STklos procedure

(temp-file-prefix)
(temp-file-prefix value)

This parameter object permits to change the default prefix used to build temporary file name. Its default value is built using the TMPDIR environment variable (if it is defined) and the current process ID. If a value is provided, it must be a string designating a valid prefix path.

This parameter object is also defined in SRFI-170 (POSIX API).

STklos procedure

(create-temp-file)
(create-temp-file prefix)

Creates a new temporary file and returns two values: its name and an opened file port on it. The optional argument specifies the filename prefix to use, and defaults to the result of invoking temp-file-prefix. The returned file port is opened in read/write mode. It ensures that the name cannot be reused by another process before being used in the program that calls create-temp-file. Note, that if the opened port is not used, it can be closed and collected by the GC.

(let-values (((name port) (create-temp-file)))
  (let ((msg (format "Name: ~sn" name)))
    (display msg)
    (display msg port)
    (close-port port)))     => prints the name of the temp. file on the
                               current output port and in the file itself.
This function is also defined in SRFI-170 (POSIX API).However, in SRFI-170, create-temp-file returns only the name of the temporary file.
temporary-file-name is another name for this function.

STklos procedure

(create-temp-directory)
(create-temp-directory prefix)

Creates a new temporary directory and returns its name as a string. The optional argument specifies the filename prefix to use, and defaults to the result of invoking temp-file-prefix.

STklos procedure

(rename-file string1 string2)

Renames the file whose path-name is string1 to a file whose path-name is string2. The result of rename-file is void.

This function is also defined in SRFI-170 (POSIX API).

R7RS procedure

(delete-file string)

Removes the file whose path name is given in string. The result of delete-file is void.

This function is also called remove-file for compatibility reasons. ,(index "remove-file")

STklos procedure

(copy-file string1 string2)

Copies the file whose path-name is string1 to a file whose path-name is string2. If the file string2 already exists, its content prior the call to copy-file is lost. The result of copy-file is void.

STklos procedure

(copy-port in out)
(copy-port in out max)

Copy the content of port in, which must be opened for reading, on port out, which must be opened for writing. If max is not specified, All the characters from the input port are copied on ouput port. If max is specified, it must be an integer indicating the maximum number of characters which are copied from in to out.

R7RS procedure

(file-exists? string)

Returns #t if the path name given in string denotes an existing file; returns #f otherwise.

STklos procedure

(file-is-directory? string)
(file-is-regular? string)
(file-is-readable? string)
(file-is-writable? string)
(file-is-executable? string)

Returns #t if the predicate is true for the path name given in string; returns #f otherwise (or if string denotes a file which does not exist).

STklos procedure

(file-size string)

Returns the size of the file whose path name is given in string. If string denotes a file which does not exist, file-size returns #f.

STklos procedure

(getcwd)

Returns a string containing the current working directory.

STklos procedure

(chmod str)
(chmod str option1 …​)

Change the access mode of the file whose path name is given in string. The options must be composed of either an integer or one of the following symbols read, write or execute. Giving no option to chmod is equivalent to pass it the integer 0. If the operation succeeds, chmod returns #t; otherwise it returns #f.

(chmod "~/.config/stklos/stklosrc" 'read 'execute)
(chmod "~/.config/stklos/stklosrc" #o644)

STklos procedure

(chdir dir)

Changes the current directory to the directory given in string dir.

STklos procedure

(create-directory dir)
(create-directory dir permissions)

Create a directory with name dir. If permissions is omitted, it defaults to #o775 (masked by the current umask).

This function is also defined in SRFI-170 (POSIX API). The old name make-directory is deprecated.

STklos procedure

(create-directories dir)
(create-directories dir permissions)

Create a directory with name dir. No error is signaled if dir already exists. Parent directories of dir are created as needed. If permissions is omitted, it defaults to #o775 (masked by the current umask).

This function was also called make-directories. This old name is obsolete.

STklos procedure

(ensure-directories-exist path)

Create a directory with name dir (and its parent directories if needed), if it does not exist yet.

STklos procedure

(delete-directory dir)
(remove-directory dir)

Delete the directory with name dir.

This function is also defined in SRFI-170 (POSIX API). The name remove-directory is kept for compatibility.

STklos procedure

(directory-files path)
(directory-files path dotfiles?)

Returns the list of the files in the directory path. The dotfiles? flag (default #f) causes files beginning with ,(q ".") to be included in the list. Regardless of the value of dotfiles?, the two files ,(q ".") and ,(q "..") are never returned.

This function is also defined in SRFI-170 (POSIX API).

STklos procedure

(expand-file-name path)

Expand-file-name expands the filename given in path to an absolute path.

  ;; Current directory is ~eg/stklos (i.e. /users/eg/stklos)
  (expand-file-name "..")            => "/users/eg"
  (expand-file-name "~eg/../eg/bin") => "/users/eg/bin"
  (expand-file-name "~/stklos)"      => "/users/eg/stk"

STklos procedure

(canonical-file-name path)

Expands all symbolic links in path and returns its canonicalized absolute path name. The resulting path does not have symbolic links. If path doesn’t designate a valid path name, canonical-file-name returns #f.

STklos procedure

(decompose-file-name string)

Returns an `exploded'' list of the path name components given in `string. The first element in the list denotes if the given string is an absolute path or a relative one, being "/" or "." respectively. Each component of this list is a string.

(decompose-file-name "/a/b/c.stk") => ("/" "a" "b" "c.stk")
(decompose-file-name "a/b/c.stk")  => ("." "a" "b" "c.stk")

STklos procedure

(winify-file-name fn)

On Win32 system, when compiled with the Cygwin environment, file names are internally represented in a POSIX-like internal form. Winify-file-bame permits to obtain back the Win32 name of an interned file name

(winify-file-name "/tmp")
    => "C:\cygwin\tmp"
(list (getcwd) (winify-file-name (getcwd)))
    => ("//saxo/homes/eg/Projects/STklos"
        "\\saxo\homes\eg\Projects\STklos")

STklos procedure

(posixify-file-name fn)

On Win32 system, when compiled with the Cygwin environment, file names are internally represented in a POSIX-like internal form. posixify-file-bame permits to obtain the interned file name from its external form. file name

(posixify-file-name "C:\cygwin\tmp")
       => "/tmp"

STklos procedure

(basename str)

Returns a string containing the last component of the path name given in str.

(basename "/a/b/c.stk") => "c.stk"

STklos procedure

(dirname str)

Returns a string containing all but the last component of the path name given in str.

(dirname "/a/b/c.stk") => "/a/b"

STklos procedure

(file-suffix pathname)

Returns the suffix of given pathname. If no suffix is found, file-suffix returns #f.

(file-suffix "./foo.tar.gz") => "gz"
(file-suffix "./a.b/c")      => #f
(file-suffix "./a.b/c.")     => ""
(file-suffix "~/.profile")   => #f

STklos procedure

(file-prefix pathname)

Returns the prefix of given pathname.

(file-prefix "./foo.tar.gz") => "./foo.tar"
(file-prefix "./a.b/c")      => "./a.b/c"

STklos procedure

(file-separator)

Retuns the operating system file separator as a character. This is typically #/ on Unix (or Cygwin) systems and #\ on Windows.

STklos procedure

(make-path dirname . names)

Builds a file name from the directory dirname and names. For instance, on a Unix system:

(make-path "a" "b" "c")   => "a/b/c"

STklos procedure

(glob pattern …​)

Glob performs file name `globbing'' in a fashion similar to the csh shell. `Glob returns a list of the filenames that match at least one of pattern arguments. The pattern arguments may contain the following special characters:

  • ? Matches any single character.

  • * Matches any sequence of zero or more characters.

  • [chars] Matches any single character in chars. If chars contains a sequence of the form a-b then any character between a and b (inclusive) will match.

  • x Matches the character x.

  • {a,b,…​} Matches any of the strings a, b, etc. )

As with csh, a '.' at the beginning of a file’s name or just after a '/' must be matched explicitly or with a @{@} construct. In addition, all '/' characters must be matched explicitly.

If the first character in a pattern is '~' then it refers to the home directory of the user whose name follows the '~'. If the '~' is followed immediately by '/' then the value of the environment variable HOME is used.

Glob differs from csh globbing in two ways:

  1. it does not sort its result list (use the sort procedure if you want the list sorted).

  2. glob only returns the names of files that actually exist; in csh no check for existence is made unless a pattern contains a ?, *, or [] construct.

STklos procedure

(posix-error? obj)

This procedure returns #t if obj is a condition object that describes a POSIX error, and #f otherwise.

This function is defined in SRFI-170 (POSIX API).

STklos procedure

(posix-error-name posix-error)

This procedure returns a symbol that is the name associated with the value of errno when the POSIX function reported an error. This can be used to provide programmatic recovery when a POSIX function can return more than one value of errno.

This function is defined in SRFI-170 (POSIX API).

STklos procedure

(posix-error-message posix-error)

This procedure returns a string that is an error message reflecting the value of errno when the POSIX function reported an error. This string is useful for reporting the cause of the error to the user

This function is defined in SRFI-170 (POSIX API).

STklos procedure

(posix-error-errno posix-error)

This procedure returns the value of errno (an exact integer).

STklos procedure

(posix-error-procedure posix-error)

This procedure returns the name of the Scheme procedure that raised the error.

STklos procedure

(posix-error-args posix-error)

This procedure returns the list of the Scheme procedure arguments that raised the error.

4.13.3. Environment

STklos procedure

(getenv str)
(getenv)

Looks for the environment variable named str and returns its value as a string, if it exists. Otherwise, getenv returns #f. If getenv is called without parameter, it returns the list of all the environment variables accessible from the program as an A-list.

(getenv "SHELL")
     => "/bin/zsh"
(getenv)
     => (("TERM" . "xterm") ("PATH" . "/bin:/usr/bin") ...)

STklos procedure

(setenv! var value)

Sets the environment variable var to value. Var and value must be strings. The result of setenv! is void.

STklos procedure

(unsetenv! var)

Unsets the environment variable var. Var must be a string. The result of unsetenv! is void.


STklos defines also the R7RS (and SRFI-96) standard primivitives to acess environment variables.

R7RS procedure

(get-environment-variable name)

Returns the value of the named environment variable as a string, or #f if the named environment variable is not found. The name argument is expected to be a string. This function is similar to the getenv. It has been added to be support SRFI-98 (Interface to access environment variables).

R7RS procedure

(get-environment-variables)

Returns names and values of all the environment variables as an a-list. This function is defined by SRFI-98 (Interface to access environment variables).

STklos procedure

(build-path-from-shell-variable var)
(build-path-from-shell-variable var sep)

Builds a path as a list of strings (which is the way STklos represents paths) from the environment variable var, given the separator characters given in sep (which defaults to ":", the standrad Unix path separator). If the var is not definied in the environment, build-path-from-shell-variable returns the empty list.

If the shell variable MYPATH is "/bin:/sbin:/usr/bin"`, then

(build-path-from-shell-variable "MYPATH")       => ("/bin" "/sbin" "/usr/bin")
(build-path-from-shell-variable "MYPATH" "/:")  => ("bin" "sbin" "usr" "bin")

STklos procedure

(install-path)
(install-path key)

Returns the list of the installation directories chosen when STklos was configured. Without parameter, install-path returns the path of all configured directories. When key is provided, only the corresponding path is returned. Key can be:

  • #:libdir (directory for architecture specific installed files)

  • #:datadir (directory for portable installed files)

  • #:docdir (directory for installed documentation)

  • #:htmldir (directory for installed HTML documentation)

  • #:pdfdir (directory for installed PDF documentation)

4.13.4. Time

R7RS procedure

(current-second)

Returns an inexact number representing the current time on the International Atomic Time (TAI) scale. The value 0.0 represents midnight on January 1, 1970 TAI (equivalent to ten seconds before midnight Universal Time) and the value 1.0 represents one TAI second later.

R7RS procedure

(current-jiffy)

Returns the number of jiffies as an exact integer that have elapsed since an arbitrary, implementation-defined epoch. A jiffy is an implementation-defined fraction of a second which is defined by the return value of the jiffies-per-second procedure. The starting epoch is guaranteed to be constant during a run of the program, but may vary between runs.

R7RS procedure

(jiffies-per-seconds)

Returns an exact integer representing the number of jiffies per second.

(define (time-length)
  (let ((list (make-list 100000))
        (start (current-jiffy)))
    (length list)
    (/ (- (current-jiffy) start)
       (jiffies-per-second))))

STklos procedure

(clock)

Returns an approximation of processor time, in milliseconds, used so far by the program. The value returned is a real.

STklos procedure

(exact-clock)

Returns an approximation of processor time, in microseconds, used so far by the program. The value returned is an integer.

STklos procedure

(sleep n)

Suspend the execution of the program for at ms milliseconds. Note that due to system clock resolution, the pause may be a little bit longer. If a signal arrives during the pause, the execution may be resumed.

STklos syntax

(time expr1 expr2 …​)

Evaluates the expressions expr1, expr2, …​ and returns the result of the last expression. This form also prints the time spent for this evaluation, in milliseconds, and the quantity of bytes alocated on the current error port, as well as the number of garbage collection done. This is CPU time, and not real ("wall") time.

(time (begin (make-list 200) 'finish))
    Elapsed time: 0.059 ms
    Allocations: 6408 bytes in 201 allocation calls (GC: 0)
=> finish

In the example above, the result of the expression is only the symbol finish. The two other lines are written to the standard error port.

The allocation accounting is independent for each thread, and allocations in children threads do not increase the parent thread counters, as the example below illustrates. Note that, on the other side, the number of GC calls is is a global counter.

(let ((T (make-thread (lambda () (make-list 1_000_000) (eprintf "finishn")))))
  (time (thread-start! T) ;; Launch T wich allocate 1_000_1000 cells
        (thread-sleep! 3) ;; wait for the child thread to allocate list
        (thread-join! T)
        100))
finish
    Elapsed time: 33.299 ms
    Allocations: 800408 bytes in 10 allocation calls (GC: 0)
100

The ten allocations we can see here are for theads bookeeping and are far from the million cells allocated in thread T.

4.13.5. System Information

R7RS procedure

(features)

Returns a list of the feature identifiers which cond-expand treats as true. Here is an example of what features might return:

(features) => (STklos STklos-2.10.xxx exact-complex
               ieee-float full-unicode ratios little-endian ...)

STklos procedure

(running-os)

Returns the name of the underlying Operating System which is running the program. The value returned by runnin-os is a symbol. For now, this procedure returns either unix, android, windows, or cygwin-windows.

STklos procedure

(hostname)

Return the host name of the current processor as a string.

R7RS procedure

(command-line)

Returns the command line passed to the process as a list of strings. The first string corresponds to the command name.

STklos procedure

(command-name)

Returnd the name of the running program if it is a standalone and #f otherwise. This function is defined in SRFI-193 (Command line).

STklos procedure

(command-args)
(argv)

Returns a list of the arguments given on the shell command line. The interpreter options are no included in the result. The name argv is deprecated and should not be used.

STklos procedure

(argc)

Returns the number of arguments present on the command line.

STklos procedure

(program-name)

Returns the invocation name of the current program as a string. If the file is not a script (in sense of SRFI-193), it is the name of the running STklos interpreter, otherwise it is the name of the running script. This function always returns a string whereas the command-name procedure returns #f when the program name is not a script.

STklos procedure

(script-file)

Returns the absolute path of the current script. If the calling program is not a script, #f is returned. This function is defined in SRFI-193 (Command line).

STklos procedure

(script-directory)

Returns the non-filename part of script-file as a string. As with script-file, this is an absolute pathname.

STklos procedure

(version)
(implementation-version)

Returns a string identifying the current version of the system. A version is constituted of two (or three) numbers separated by a point: the version, the release numbers and, eventually, a patch number. The patch number is used for developments version only; it is absent for stable releases.

Note that implementation-version corresponds to the SRFI-112 (Environment Inquiry) name of this function.

STklos procedure

(short-version)

Returns a string identifying the current version of the system without its eventual patch number.

STklos procedure

(machine-type)

Returns a string identifying the kind of machine which is running the program. The result string is of the form [os-name]-[os-version]-[cpu-architecture].

STklos procedure

(implementation-name)

This function is defined in SRFI-112 (Environment Inquiry); it returns the Scheme implementation (i.e. the string "STklos").

STklos procedure

(cpu-architecture)

This function is defined in SRFI-112 (Environment Inquiry); it returns the CPU architecture, real or virtual, on which this implementation is executing.

STklos procedure

(machine-name)

This function is defined in SRFI-112 (Environment Inquiry); it returns a name for the particular machine on which the implementation is running.

STklos procedure

(os-name)

This function is defined in SRFI-112 (Environment Inquiry); it returns the name for the operating system, platform, or equivalent on which the implementation is running.

STklos procedure

(os-version)

This function is defined in SRFI-112 (Environment Inquiry); it returns the version for the operating system, platform, or equivalent on which the implementation is running.

STklos procedure

(getpid)

Returns the system process number of the current program (i.e. the Unix PID as an integer).

4.13.6. Program Arguments Parsing

STklos provides a simple way to parse program arguments with the parse-arguments special form. This form is generally used into the main| function in a Scheme script. See SRFI-22 (Running Scheme Scripts on Unix) on how to use a main function in a Scheme program.

STklos procedure

(parse-arguments <args> <clause1> <clause2> …​)

The parse-arguments special form is used to parse the command line arguments of a Scheme script. The implementation of this form internally uses the GNU C getopt function. As a consequence parse-arguments accepts options which start with the '-' (short option) or '--' characters (long option).

The first argument of parse-arguments is a list of the arguments given to the program (comprising the program name in the CAR of this list). Following arguments are clauses. Clauses are described later.

By default, parse-arguments permutes the contents of (a copy) of the arguments as it scans, so that eventually all the non-options are at the end. However, if the shell environment variable POSIXLY_CORRECT is set, then option processing stops as soon as a non-option argument is encountered.

A clause must follow the syntax:

<clause>       => string | <list-clause>
<list clause>  => (<option descr> <expr> ...) | (else <expr> ...)
<option descr> => (<option name> [<keyword> value]*)
<option name>  => string
<keyword>      => :alternate | :arg | :help

A string clause is used to build the help associated to the command. A list clause must follow the syntax describes an option. The <expr>s associated to a list clauses are executed when the option is recognized. The else clauses is executed when all parameters have been parsed. The :alternate key permits to have an alternate name for an option (generally a short or long name if the option name is a short or long name). The :help is used to provide help about the the option. The :arg is used when the option admit a parameter: the symbol given after :arg will be bound to the value of the option argument when the corresponding `<expr>`s will be executed.

In an else clause the symbol other-arguments is bound to the list of the arguments which are not options.

The following example shows a rather complete usage of the parse-arguments form

#!/usr/bin/env stklos

(define (main args)
  (parse-arguments args
     "Usage: foo [options] [parameter ...]"
     "General options:"
         (("verbose" :alternate "v" :help "be more verbose")
           (printf "Seen the verbose option~%"))
         (("long" :help "a long option alone")
           (printf "Seen the long option~%"))
         (("s" :help "a short option alone")
           (printf "Seen the short option~%"))
     "File options:"
         (("input" :alternate "f" :arg file
                   :help "use <file> as input")
           (printf "Seen the input option with ~S argument~%" file))
         (("output" :alternate "o" :arg file
                    :help "use <file> as output")
           (printf "Seen the output option with ~S argument~%" file))
     "Misc:"
         (("help" :alternate "h"
                  :help "provides help for the command")
           (arg-usage (current-error-port))
           (exit 1))
     (else
         (printf "All options parsed. Remaining arguments are ~S~%"
                 other-arguments))))

The following program invocation

foo -vs --input in -o out arg1 arg2

produces the following output

Seen the verbose option
Seen the short option
Seen the input option with "in" argument
Seen the output option with "out" argument
All options parsed. Remaining arguments are ("arg1" "arg2")

Finally, the program invocation

foo --help

produces the following output

Usage: foo [options] [parameter ...]
General options:
  --verbose, -v               be more verbose
  --long                      a long option alone
  -s                          a short option alone
File options:
  --input=<file>, -f <file>   use <file> as input
  --output=<file>, -o <file>  use <file> as output
Misc:
  --help, -h                  provides help for the command

Notes:

  • Short option can be concatenated. That is,

    prog -abc

    is equivalent to the following program call

    prog -a -b -c
  • Any argument following a '--' argument is no more considered as an option, even if it starts with a '-' or '--'.

  • Option with a parameter can be written in several ways. For instance to set the output in the bar file for the previous example can be expressed as

    • --output=bar, or

    • -o bar, or

    • -obar

STklos procedure

(arg-usage port)
(arg-usage port as-sexpr)

This procedure is only bound inside a parse-arguments form. It pretty prints the help associated to the clauses of the parse-arguments form on the given port. If the argument as-sexpr is passed and is not #f, the help strings are printed on port as Sexprs. This is useful if the help strings need to be manipulated by a program.

4.13.7. Misc. System Procedures

STklos procedure

(system string)

Sends the given string to the system shell /bin/sh. The result of system is the integer status code the shell returns.

STklos procedure

(exec str)
(exec-list str)

These procedures execute the command given in str. The command given in str is passed to /bin/sh. Exec returns a string which contains all the characters that the command str has printed on it’s standard output, whereas exec-list returns a list of the lines which constitute the output of str.

(exec "echo A; echo B")                => "AnBn"
(exec-list "echo A; echo B")           => ("A" "B")

STklos procedure

(address-of obj)
(address-ref n)

Address-of returns the address of the object obj as an integer. Address-ref returns the object of which n is the address.

(address-of "abc")               =>  140053283366272
(address-of "abc")               =>  140053289472288 ;strings are not eq?

(address-of 10)                  => 41
(address-of 10)                  => 41

(address-ref (address-of "xyz")) => "xyz"

(address-ref 0)                  => error (points to nothing)

STklos procedure

(exit)
(exit ret-code)

Exits the program with the specified integer return code. If ret-code is omitted, the program terminates with a return code of 0. If program has registered exit functions with register-exit-function!, they are called (in an order which is the reverse of their call order).

The STklos exit primitive accepts also an integer value as parameter (R7RS accepts only a boolean).

STklos procedure

(emergency-exit)
(emergency-exit ret-code)

Terminates the program without running any outstanding dynamic-wind after procedures and communicates an exit value to the operating system in the same manner as exit.

The STklos emergency-exit primitive accepts also an integer value as parameter (R7RS accepts only a boolean).

STklos procedure

(die message)
(die message status)

Die prints the given message on the current error port and exits the program with the status value. If status is omitted, it defaults to 1.

STklos procedure

(get-password)

This primitive permits to enter a password (character echoing being turned off). The value returned by get-password is the entered password as a string.

STklos procedure

(register-exit-function! proc)

This function registers proc as an exit function. This function will be called when the program exits. When called, proc will be passed one parmater which is the status given to the exit function (or 0 if the programe terminates normally). The result of register-exit-function! is undefined.

(let* ((tmp (temporary-file-name))
       (out (open-output-file tmp)))
  (register-exit-function! (lambda (n)
                             (when (zero? n)
                               (delete-file tmp))))
  out)

4.14. Keywords

Keywords are symbolic constants which evaluate to themselves. By default, a keyword is a symbol whose first (or last) character is a colon (":"). Alternatively, to be compatible with other Scheme implementations, the notation #:foo is also available to denote the keyword of name foo.

Note that the four directives keyword-colon-position-xxx or the parameter object ` keyword-colon-position` permit to change the default behavior. See section~Identifiers for more information.

STklos procedure

(keyword obj)

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

(keyword? 'foo)     => #f
(keyword? ':foo)    => #t  ; depends of keyword-colon-position
(keyword? 'foo:)    => #t  ; depends of keyword-colon-position
(keyword? '#:foo)   => #t  ; always
(keyword? :foo)     => #t  ; depends of keyword-colon-position
(keyword? foo:)     => #t  ; depends of keyword-colon-position
(keyword? #:foo)    => #t  ; always

STklos procedure

(make-keyword s)

Builds a keyword from the given s. The parameter s must be a symbol or a string.

(make-keyword "test")    => #:test
(make-keyword 'test)     => #:test
(make-keyword ":hello")  => #::hello

STklos procedure

(keyword→string key)

Returns the name of key as a string. The result does not contain a colon.

STklos procedure

(string→keyword str)

This function function has been added to be compatibe with SRFI-88. It is equivalent to make-keyword, except that the parameter cannot be a symbol.

STklos procedure

(key-get list key)
(key-get list key default)

List must be a list of keywords and their respective values. key-get scans the list and returns the value associated with the given key. If key does not appear in an odd position in list, the specified default is returned, or an error is raised if no default was specified.

(key-get '(#:one 1 #:two 2) #:one)     => 1
(key-get '(#:one 1 #:two 2) #:four #f) => #f
(key-get '(#:one 1 #:two 2) #:four)    => error

STklos procedure

(key-set! list key value)

List must be a list of keywords and their respective values. key-set! sets the value associated to key in the keyword list. If the key is already present in list, the keyword list is ,(emph "physically") changed.

(let ((l (list #:one 1 #:two 2)))
  (set! l (key-set! l #:three 3))
  (cons (key-get l #:one)
        (key-get l #:three)))            => (1 . 3)

STklos procedure

(key-delete list key)
(key-delete! list key)

List must be a list of keywords and their respective values. key-delete remove the key and its associated value of the keyword list. The key can be absent of the list.

key-delete! does the same job as key-delete by physically modifying its list argument.

(key-delete '(:one 1 :two 2) :two)    => (:one 1)
(key-delete '(:one 1 :two 2) :three)  => (:one 1 :two 2)
(let ((l (list :one 1 :two 2)))
   (key-delete! l :two)
   l)                                 =>  (:one 1)

STklos procedure

(keyword-colon-position)
(keyword-colon-position value)

This parameter object indicates the convention used by the reader to denote keywords. The allowed values are:

  • none, to forbid a symbol with colon to be interpreted as a keyword,

  • before, to read symbols starting with a colon as keywords,

  • after, to read symbols ending with a colon as keywords,

  • both, to read symbols starting or ending with a colon as keywords.

Note that the notation #:key is always read as a keyword independently of the value of keyword-colon-position. Hence, we have

(list (keyword? ':a)
      (keyword? 'a:)
      (keyword? '#:a))
                 => (#f #f #t)  ; if keyword-colon-position is none
                 => (#t #f #t)  ; if keyword-colon-position is before
                 => (#f #t #t)  ; if keyword-colon-position is after
                 => (#t #t #t)  ; if keyword-colon-position is both

4.15. Hash Tables

A hash table consists of zero or more entries, each consisting of a key and a value. Given the key for an entry, the hashing function can very quickly locate the entry, and hence the corresponding value. There may be at most one entry in a hash table with a particular key, but many entries may have the same value.

STklos hash tables grow gracefully as the number of entries increases, so that there are always less than three entries per hash bucket, on average. This allows for fast lookups regardless of the number of entries in a table.

STklos hash tables procedures are identical to the ones defined in SRFI-69 (Basic Hash Tables). Note that the default comparison function is eq? whereas it is equal? in this SRFI. See SRFI’s documentation for more information.

STklos procedure

(make-hash-table)
(make-hash-table comparison)
(make-hash-table comparison hash)

Make-hash-table admits three different forms. The most general form admit two arguments. The first argument is a comparison function which determines how keys are compared; the second argument is a function which computes a hash code for an object and returns the hash code as a non negative integer. Objets with the same hash code are stored in an A-list registered in the bucket corresponding to the key.

If omitted,

Consequently,

(define h (make-hash-table))

is equivalent to

(define h (make-hash-table eq? hash-table-hash))

An interesting example is

(define h (make-hash-table string-ci=? string-length))

which defines a new hash table which uses string-ci=? for comparing keys. Here, we use the string-length as a (very simple) hashing function. Of course, a function which gives a key depending of the characters composing the string gives a better repartition and should probably enhance performance. For instance, the following call to make-hash-table should return a more efficient, even if not perfect, hash table:

(make-hash-table
   string-ci=?
   (lambda (s)
     (let ((len (string-length s)))
       (do ((h 0)  (i 0 (+ i 1)))
           ((= i len) h)
         (set! h
               (+ h (char->integer
                      (char-downcase (string-ref s i)))))))))
Hash tables with a comparison function equal to eq? or string=? are handled in an more efficient way (in fact, they don’t use the hash-table-hash function to speed up hash table retrievals).

STklos procedure

(hash-table? obj)

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

STklos procedure

(hash-table-hash obj)

Computes a hash code for an object and returns this hash code as a non-negative integer. A property of hash-table-hash is that

(equal? x y) => (equal? (hash-table-hash x) (hash-table-hash y)

as the Common Lisp sxhash function from which this procedure is modeled.

STklos procedure

(alist→hash-table alist)
(alist→hash-table alist comparison)
(alist→hash-table alist comparison hash)

Returns hash-table built from the association list alist. This function maps the car of every element in alist to the cdr of corresponding elements in alist. the comparison and hash functions are interpreted as in make-hash-table. If some key occurs multiple times in alist, the value in the first association will take precedence over later ones.

STklos procedure

(hash-table→alist hash)

Returns an association list built from the entries in hash. Each entry in hash will be represented as a pair whose car is the entry’s key and whose cdr is its value.

the order of pairs in the resulting list is unspecified.
(let ((h (make-hash-table)))
  (dotimes (i 5)
    (hash-table-set! h i (number->string i)))
  (hash-table->alist h))
       => ((3 . "3") (4 . "4") (0 . "0")
           (1 . "1") (2 . "2"))

STklos procedure

(hash-table-set! hash key value)

Enters an association between key and value in the`hash` table. The value returned by hash-table-set! is void.

STklos procedure

(hash-table-ref hash key)
(hash-table-ref hash key thunk)

Returns the value associated with key in the given hash table. If no value has been associated with key in hash, the specified thunk is called and its value is returned; otherwise an error is raised.

(define h1 (make-hash-table))
(hash-table-set! h1 'foo (list 1 2 3))
(hash-table-ref  h1 'foo)                 =>  (1 2 3)
(hash-table-ref  h1 'bar
                    (lambda () 'absent))  =>  absent
(hash-table-ref  h1 'bar)                 =>  error
(hash-table-set! h1 '(a b c) 'present)
(hash-table-ref  h1 '(a b c)
                     (lambda () 'absent)) => absent

(define h2 (make-hash-table equal?))
(hash-table-set! h2 '(a b c) 'present)
(hash-table-ref  h2 '(a b c))             => present

STklos procedure

(hash-table-ref/default hash key default)

This function is equivalent to

(hash-table-ref hash key (lambda () default))

STklos procedure

(hash-table-delete! hash key)

Deletes the entry for key in hash, if it exists. Result of hash-table-delete! is void.

(define h (make-hash-table))
(hash-table-set! h 'foo (list 1 2 3))
(hash-table-ref h 'foo)                => (1 2 3)
(hash-table-delete! h 'foo)
(hash-table-ref h 'foo
                  (lambda () 'absent)  => absent

STklos procedure

(hash-table-exists? hash key)

Returns #t if there is any association of key in hash. Returns #f otherwise.

STklos procedure

(hash-table-update! hash key update-fun thunk)
(hash-table-update!/default hash key update-fun default)

Update the value associated to key in table hash if key is already in table with the value (update-fun current-value). If no value is associated to key, a new entry in the table is first inserted before updating it (this new entry being the result of calling thunk).

Note that the expression

(hash-table-update!/default hash key update-fun default)

is equivalent to

(hash-table-update! hash key update-fun (lambda () default))
(let ((h   (make-hash-table))
      (1+  (lambda (n) (+ n 1))))
  (hash-table-update!/default h 'test 1+ 100)
  (hash-table-update!/default h 'test 1+)
  (hash-table-ref h 'test))             => 102

STklos procedure

(hash-table-for-each hash proc)
(hash-table-walk hash proc)

Proc must be a procedure taking two arguments. Hash-table-for-each calls proc on each key/value association in hash, with the key as the first argument and the value as the second. The value returned by hash-table-for-each is void.

The order of application of proc is unspecified.
hash-table-walk is another name for hash-table-for-each (this is the name used in SRFI-69 (Basic Hash Tables).
(let ((h   (make-hash-table))
      (sum 0))
  (hash-table-set! h 'foo 2)
  (hash-table-set! h 'bar 3)
  (hash-table-for-each h (lambda (key value)
                           (set! sum (+ sum value))))
  sum)           =>  5

STklos procedure

(hash-table-map hash proc)

Proc must be a procedure taking two arguments. Hash-table-map calls proc on each key/value association in hash, with the key as the first argument and the value as the second. The result of hash-table-map is a list of the values returned by proc, in an unspecified order.

The order of application of proc is unspecified.
(let ((h (make-hash-table)))
  (dotimes (i 5)
    (hash-table-set! h i (number->string i)))
  (hash-table-map h (lambda (key value)
                       (cons key value))))
             => ((3 . "3") (4 . "4") (0 . "0") (1 . "1") (2 . "2"))

STklos procedure

(hash-table-keys hash)
(hash-table-values hash)

Returns the keys or the values of hash.

STklos procedure

(hash-table-fold hash func init-value)

This procedure calls func for every association in hash with three arguments: the key of the association key, the value of the association value, and an accumulated value, val. Val is init-value for the first invocation of func, and for subsequent invocations of func, the return value of the previous invocation of func. The value final-value returned by hash-table-fold is the return value of the last invocation of func. The order in which func is called for different associations is unspecified.

For instance, the following expression

(hash-table-fold ht (lambda (k v acc) (+ acc 1)) 0)

computes the number of associations present in the ht hash table.

STklos procedure

(hash-table-copy hash)

Returns a copy of hash.

STklos procedure

(hash-table-merge! hash1 hash2)

Adds all mappings in hash2 into hash1 and returns the resulting hash table. This function may modify hash1 destructively.

STklos procedure

(hash-table-equivalence-function hash)

Returns the equivalence predicate used for keys in hash.

STklos procedure

(hash-table-hash-function hash)

Returns the hash function used for keys in hash.

STklos procedure

(hash-mutable? obj)

Returns #t if obj is an immutable hash table, #f if it is a mutable hash table, and raises an error if obj is not a hash table.

STklos procedure

(hash-immutable! obj)

If obj is a hash table, makes it immutable. Otherwise, raises an error.

STklos procedure

(hash-table-size hash)

Returns the number of entries in the hash.

STklos procedure

(hash-table-stats hash)
(hash-table-stats hash port)

Prints overall information about hash, such as the number of entries it contains, the number of buckets in its hash array, and the utilization of the buckets. Information is printed on port. If no port is given to hash-table-stats, information are printed on the current output port (see current-output-port primitive).

4.16. Dates and Times

STklos stores dates and times with a compact representation which consists is an integer which represents the number of seconds elapsed since the Epoch (00:00:00 on January 1, 1970, Coordinated Universal Time --UTC). Dates can also be represented with date structures.

R7RS procedure

(current-second)

Returns an inexact number representing the current time on the International Atomic Time (TAI) scale. The value 0.0 represents midnight on January 1, 1970 TAI (equivalent to ten seconds before midnight Universal Time) and the value 1.0 represents one TAI second later.

STklos procedure

(current-seconds)

Returns the time since the Epoch (that is 00:00:00 UTC, January 1, 1970), measured in seconds in the Coordinated Universal Time (UTC) scale.

This STklos function should not be confused with the R7RS primitive current-second which returns an inexact number and whose result is expressed using the International Atomic Time instead of UTC.

STklos procedure

(current-time)
(current-time type)

Return the current time as time object. The type can be time-utc or time-tai. If omitted, type is time-utc.

To use more time types, such as time-monotonic and time-process, please load SRFI-19.

STklos procedure

(make-time nanosecond second)
(make-time type nanosecond second)

Creates a time structure with the given nanosecond and second. If type is passed, it must be a symbol representing one of the supported time types (time-tai, time-utc, time-monotonic, time-process and time-duration).

time-monotonic, time-process and time-duration can be created, but operations on them are only available when SRFI-19 is loaded.

STklos procedure

(time-type t)
(set-time-type! t v)
(time-second t)
(set-time-second! t s)
(time-nanosecond t)
(set-time-nanosecond! t n)

These are accessors for time structures.

STklos procedure

(time? obj)

Return #t if obj is a time object, othererwise returns #f.

STklos procedure

(time→seconds time)

Convert the time object time into an inexact real number representing the number of seconds elapsed since the Epoch.

(time->seconds (current-time))  ==>  1138983411.09337

STklos procedure

(seconds→time x)

Converts into a time object the real number x representing the number of seconds elapsed since the Epoch.

(seconds->time (+ 10 (time->seconds (current-time))))
         ==>  a time object representing 10 seconds in the future

STklos procedure

(time-utc→time-tai t)
(time-utc→time-tai! t)

Converts t, which must be of type time-utc, to the type time-tai.

Time-utc→time-tai creates a new object, while time-utc→time-tai can use t to build the returned object.

STklos procedure

(time-tai→time-utc t)
(time-tai→time-utc! t)

Converts t, which must be of type time-tai, to the type time-utc.

Time-tai→time-utc creates a new object, while time-tai→time-utc can use t to build the returned object.

STklos procedure

(current-date)

Returns the current system date.

STklos procedure

(make-date :key nanosecond second minute hour day month year zone-offset)
(make-date :optional nanosecond second minute hour day month year zone-offset)

Build a date from its argument. hour, minute, second, nanosecond default to 0; day and month default to 1; year defaults to 1970.

STklos procedure

(date? obj)

Return #t if obj is a date, and otherwise returns #f.

STklos procedure

(date-nanosecond d)

Return the nanosecond of date d.

STklos procedure

(date-second d)

Return the second of date d, in the range 0 to 59.

STklos procedure

(date-minute d)

Return the minute of date d, in the range 0 to 59.

STklos procedure

(date-hour d)

Return the hour of date d, in the range 0 to 23.

STklos procedure

(date-day d)

Return the day of date d, in the range 1 to 31

STklos procedure

(date-month d)

Return the month of date d, in the range 1 to 12

STklos procedure

(date-year d)

Return the year of date d.

STklos procedure

(date-week-day d)

Return the week day of date d, in the range 0 to 6 (0 is Sunday).

STklos procedure

(date-year-day d)

Return the the number of days since January 1 of date d, in the range 1 to 366.

STklos procedure

(date-dst d)

Return an indication about daylight saving adjustment of date d:

  • 0 if no daylight saving adjustment

  • 1 if daylight saving adjustment

  • -1 if the information is not available

STklos procedure

(date-tz d)

Return the time zone of date d.

STklos procedure

(local-timezone-offset)

Returns the local timezone offset, in seconds.

For example, for GMT+2 it will be 2 * 60 * 60 = 7200

(local-timezone-offset) => 0        ;; for GMT
(local-timezone-offset) => 7200     ;; for GMT+2
(local-timezone-offset) => -10800   ;; for GMT-3

The timezone is searched for in the environment variable TZ. If this variable does not appear in the environment, the system timezone is used.

STklos procedure

(date→seconds d)

Convert the date d to the number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).

(date->seconds (make-date 0 37 53 1 26 10 2012 0))   => 1351216417.0

STklos procedure

(date→string d)
(date→string d format)

Convert the date d using the string format as a specification. Conventions for format are the same as the one of primitive seconds→string. If format is omitted, it defaults to "~c".

STklos procedure

(seconds→date n)

Convert the date n expressed as a number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) into a date. n can be an exact integer or an inexact real.

This is equivalent to converting time-UTC to date.

(seconds->date 1351216417)           => #[date 2012-10-26 1:53:37]

STklos procedure

(seconds→string format n)

Convert a date expressed in seconds using the string format as a specification. Conventions for format are given below:

  • ~~ a literal ~

  • ~a locale’s abbreviated weekday name (Sun…​Sat)

  • ~A locale’s full weekday name (Sunday…​Saturday)

  • ~b locale’s abbreviate month name (Jan…​Dec)

  • ~B locale’s full month day (January…​December)

  • ~c locale’s date and time (e.g., ,(code "Fri Jul 14 20:28:42-0400 2000"))

  • ~d day of month, zero padded (01…​31)

  • ~D date (mm/dd/yy)

  • ~e day of month, blank padded ( 1…​31)

  • ~f seconds+fractional seconds, using locale’s decimal separator (e.g. 5.2).

  • ~h same as ~b

  • ~H hour, zero padded, 24-hour clock (00…​23)

  • ~I hour, zero padded, 12-hour clock (01…​12)

  • ~j day of year, zero padded

  • ~k hour, blank padded, 24-hour clock (00…​23)

  • ~l hour, blank padded, 12-hour clock (01…​12)

  • ~m month, zero padded (01…​12)

  • ~M minute, zero padded (00…​59)

  • ~n new line

  • ~p locale’s AM or PM

  • ~r time, 12 hour clock, same as "~I:~M:~S ~p"

  • ~s number of full seconds since the epoch (in UTC)

  • ~S second, zero padded (00…​61)

  • ~t horizontal tab

  • ~T time, 24 hour clock, same as "~H:~M:~S"

  • ~U week number of year with Sunday as first day of week (00…​53)

  • ~V weekISO 8601:1988 week number of year (01…​53) (week 1 is the first week that has at least 4 days in the current year, and with Monday as the first day of the week)

  • ~w day of week (1…​7, 1 is Monday)

  • ~W week number of year with Monday as first day of week (01…​52)

  • ~x week number of year with Monday as first day of week (00…​53)

  • ~X locale’s date representation, for example: "07/31/00"

  • ~y last two digits of year (00…​99)

  • ~Y year

  • ~z time zone in RFC-822 style

  • ~Z symbol time zone

STklos procedure

(seconds→list sec)

Returns a keyword list for the date given by sec (a date based on the Epoch). The keyed values returned are

  • nanosecond : 0 to 999999

  • second : 0 to 59 (but can be up to 61 to allow for leap seconds)

  • minute : 0 to 59

  • hour : 0 to 23

  • day : 1 to 31

  • month : 1 to 12

  • year : e.g., 2002

  • week-day : 0 (Sunday) to 6 (Saturday)

  • year-day : 0 to 365 (365 in leap years)

  • dst : indication about daylight savings time (see primitive date-dst).

  • tz : the difference between Coordinated Universal Time (UTC) and local standard time in seconds.])

(seconds->list (current-second))
       => (#:nanosecond 182726 #:second 21 #:minute 35 #:hour 20 #:day 10 #:month 1
           #:year 2022 #:week-day 1 #:year-day 10 #:dst 0 #:tz -3600)

STklos procedure

(date)

Returns the current date in a string.

4.17. Boxes

Boxes are objects which contain one or several states. A box may be constructed with the box, constant-box. STklos boxes are compatible with the one defined in SRFI-111 (Boxes) or SRFI-195 (Multiple-value boxes). Boxes of SRFI-111 can contain only one value, whereas SRFI-195 boxes can contain multiple values. Furthermore, STklos defines also the notion of constant boxes which are not mutable.

The read primitive can also make single valued boxes (using the #& notation). Such boxes are mutable.

Note that two boxes are equal? iff their content are equal?.

STklos procedure

(box value …​)
(make-box value …​)

Returns a new box that contains all the given `value`s. The box is mutable.

(let ((x (box 10)))
  (list 10 x))        => (10 #&10)
The name make-box is now obsolete and kept only for compatibility.

STklos procedure

(constant-box value …​)
(make-constant-box value …​)

Returns a new box that contains all the given `value`s. The box is immutable.

The name make-constant-box is now obsolete and kept only for compatibility.

STklos procedure

(box? obj)

Returns #t if obj is a box, #f otherwise.

STklos procedure

(box-mutable? obj)

Returns #t if obj is a mutable box, #f otherwise.

STklos procedure

(set-box! box value …​)
(box-set! box value …​)

Changes box to hold value`s. It is an error if `set-box! is called with a number of values that differs from the number of values in the box being set. (In other words, set-box! does not allocate memory.) It is also an error to call set-box! on a box which is not mutable.

The name box-set! is now obsolete and kept only for compatibility.

STklos procedure

(unbox box)

Returns the values currently in box.

STklos procedure

(box-arity box)

Returns the number of values in box.

STklos procedure

(unbox-value box i)

Returns the ith value of box. It is an error if i is not an exact integer between 0 and n-1, when n is the number of values in box.

STklos procedure

(set-box-value! box i obj)

Changes the ith value of box to obj. It is an error if i is not an exact integer between 0 and n-1, when n is the number of values in box.

4.18. Processes

STklos provides access to Unix processes as first class objects. Basically, a process contains information such as the standard system process identification (aka PID on Unix Systems), the files where the standard files of the process are redirected, …​

STklos procedure

(run-process command p1 p2 …​)

run-process creates a new process and run the executable specified in command. The p correspond to the command line arguments. The following values of p have a special meaning:

  • :input permits to redirect the standard input file of the process. Redirection can come from a file or from a pipe. To redirect the standard input from a file, the name of this file must be specified after :input. Use the special keyword :pipe to redirect the standard input from a pipe.

  • :output permits to redirect the standard output file of the process. Redirection can go to a file or to a pipe. To redirect the standard output to a file, the name of this file must be specified after :output. Use the special keyword :pipe to redirect the standard output to a pipe.

  • :error permits to redirect the standard error file of the process. Redirection can go to a file or to a pipe. To redirect the standard error to a file, the name of this file must be specified after error. Use the special keyword :pipe to redirect the standard error to a pipe.

  • :wait must be followed by a boolean value. This value specifies if the process must be run asynchronously or not. By default, the process is run asynchronously (i.e. :wait is #f).

  • :host must be followed by a string. This string represents the name of the machine on which the command must be executed. This option uses the external command rsh. The shell variable PATH must be correctly set for accessing it without specifying its abolute path.

  • :fork must be followed by a boolean value. This value specifies if a fork" system call must be done before running the process. If the process is run without fork the Scheme program is lost. This feature mimics the ``exec’' primitive of the Unix shells. By default, a fork is executed before running the process (i.e. `:fork is #t). This option works on Unix implementations only.

The following example launches a process which executes the Unix command ls with the arguments -l and /bin. The lines printed by this command are stored in the file /tmp/X

(run-process "ls" "-l" "/bin" :output "/tmp/X")

STklos procedure

(process? obj)

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

STklos procedure

(process-alive? proc)

Returns #t if process proc is currently running, otherwise returns #f.

STklos procedure

(process-pid proc)

Returns an integer which represents the Unix identification (PID) of the processus.

STklos procedure

(process-input proc)
(process-output proc)
(process-error proc)

Returns the file port associated to the standard input, output or error of proc, if it is redirected in (or to) a pipe; otherwise returns #f. Note that the returned port is opened for reading when calling process-output or process-error; it is opened for writing when calling process-input.

STklos procedure

(process-wait proc)

Stops the current process (the Scheme process) until proc completion. Process-wait returns #f when proc is already terminated; it returns #t otherwise.

STklos procedure

(process-exit-status proc)

Returns the exit status of proc if it has finished its execution; returns #f otherwise.

STklos procedure

(process-send-signal proc sig)

Sends the integer signal sig to proc. Since value of sig is system dependant, use the symbolic defined signal constants to make your program independant of the running system (see Section 4.20). The result of process-send-signal is void.

STklos procedure

(process-kill proc)

Kills (brutally) process. The result of process-kill is void. This procedure is equivalent to

(process-send-signal process SIGTERM)

STklos procedure

(process-stop proc)
(process-continue proc)

Process-stop stops the execution of proc and process-continue resumes its execution. They are equivalent, respectively, to

(process-send-signal process SIGSTOP)
(process-send-signal process SIGCONT)

STklos procedure

(process-list)

Returns the list of processes which are currently running (i.e. alive).

STklos procedure

(fork)
(fork thunk)

This procedure is a wrapper around the standard Unix fork system call which permits to create a new (heavy) process. When called without parameter, this procedure returns two times (one time in the parent process and one time in the child process). The value returned to the parent process is a process object representing the child process and the value returned to the child process is always the value #f. When called with a parameter (which must be a thunk), the new process excutes thunk and terminate it execution when thunk returns. The value returned to the parent process is a process object representing the child process.

4.19. Sockets

STklos defines sockets, on systems which support them, as first class objects. Sockets permits processes to communicate even if they are on different machines. Sockets are useful for creating client-server applications.

STklos procedure

(make-client-socket hostname port-number)
(make-client-socket hostname port_number line-buffered)

make-client-socket returns a new socket object. This socket establishes a link between the running program and the application listening on port port-number of hostname. If the optional argument line-buffered has a true value, a line buffered policy is used when writing to the client socket (i.e. characters on the socket are tranmitted as soon as a "#newline character is encountered). The default value of line-buffered is #t.

STklos procedure

(make-server-socket)
(make-server-socket port-number)

make-server-socket returns a new socket object. If port-number is specified, the socket is listening on the specified port; otherwise, the communication port is chosen by the system.

STklos procedure

(socket-shutdown sock)
(socket-shutdown sock close)

Socket-shutdown shutdowns the connection associated to socket. If the socket is a server socket, socket-shutdown is called on all the client sockets connected to this server. Close indicates if the socket must be closed or not, when the connection is destroyed. Closing the socket forbids further connections on the same port with the socket-accept procedure. Omitting a value for close implies the closing of socket.

The following example shows a simple server: when there is a new connection on the port number 12345, the server displays the first line sent to it by the client, discards the others and go back waiting for further client connections.

(let ((s (make-server-socket 12345)))
   (let loop ()
      (let ((ns (socket-accept s)))
        (format #t "I've read: ~A\n"
                (read-line (socket-input ns)))
        (socket-shutdown ns #f)
        (loop))))

STklos procedure

(socket-accept socket)
(socket-accept socket line-buffered)

socket-accept waits for a client connection on the given socket. If no client is already waiting for a connection, this procedure blocks its caller; otherwise, the first connection request on the queue of pending connections is connected and socket-accept returns a new client socket to serve this request. This procedure must be called on a server socket created with make-server-socket. The result of socket-accept is undefined. Line-buffered indicates if the port should be considered as a line buffered. If line-buffered is omitted, it defaults to #t.

The following example is a simple server which waits for a connection on the port 12345 [1]

Once the connection with the distant program is established, we read a line on the input port associated to the socket, and we write the length of this line on its output port.

(let* ((server (make-server-socket 12345))
       (client (socket-accept server))
       (l      (read-line (socket-input client))))
  (format (socket-output client)
          "Length is: ~an" (string-length l))
  (socket-shutdown server))

Note that shutting down the server socket suffices here to close also the connection to client.

STklos procedure

(socket? obj)

Returns #t if socket is a socket, otherwise returns #f.

STklos procedure

(socket-server? obj)

Returns #t if socket is a server socket, otherwise returns #f.

STklos procedure

(socket-client? obj)

Returns #t if socket is a client socket, otherwise returns #f.

STklos procedure

(socket-host-name socket)

Returns a string which contains the name of the distant host attached to socket. If socket has been created with make-client-socket this procedure returns the official name of the distant machine used for connection. If socket has been created with make-server-socket, this function returns the official name of the client connected to the socket. If no client has used yet socket, this function returns #f.

STklos procedure

(socket-host-address socket)

Returns a string which contains the IP number of the distant host attached to socket. If socket has been created with make-client-socket this procedure returns the IP number of the distant machine used for connection. If socket has been created with make-server-socket, this function returns the address of the client connected to the socket. If no client has used yet socket, this function returns #f.

STklos procedure

(socket-local-address socket)

Returns a string which contains the IP number of the local host attached to socket.

STklos procedure

(socket-port-number socket)

Returns the integer number of the port used for socket.

STklos procedure

(socket-input socket)
(socket-output socket)

Returns the port associated for reading or writing with the program connected with socket. Note that this port is both textual and binary. If no connection has already been established, these functions return #f.

The following example shows how to make a client socket. Here we create a socket on port 13 of the machine kaolin.unice.fr [2]:

(let ((s (make-client-socket "kaolin.unice.fr" 13)))
  (format #t "Time is: ~A~%" (read-line (socket-input s)))
  (socket-shutdown  s))

4.20. Signals

STklos permits to associate handlers to POSIX.1 signals. When a signal handler is called, the integer value of this signal is passed to it as (the only) parameter.

The following POXIX.1 values for signal numbers are defined: SIGABRT SIGALRM, SIGFPE, SIGHUP,SIGILL, SIGINT, SIGKILL, SIGPIPE, SIGQUIT, SIGSEGV, SIGTERM, SIGUSR1, SIGUSR2, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU. Moreover, the following constants, which are often available on most systems are also defined (if supported by the running system): SIGTRAP, SIGIOT, SIGEMT, SIGBUS, SIGSYS, SIGURG, SIGCLD, SIGIO, SIGPOLL, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGLOST.

See your Unix documentation for the exact meaning of each constant or [POSIX]. Use symbolic constants rather than their numeric value if you plan to port your program on another system.

STklos procedure

(set-signal-handler! sig handler)

Replace the handler for integer signal sig with handler. The value of handler can be:

  • #t to reset the signal handler for sig to the default system handler.

  • #f to ignore the sig signal. Note that POSIX states that SIGKILL and SIGSTOP cannot be ignored or caught.

  • a one parameter procedure, which will be called when the processus receives the signal sig.

This procedure returns void.

(let ((x #f))
  (set-signal-handler! SIGUSR1
                       (lambda (i) (set! x #t)))
  (send-signal SIGUSR1)
  x)    => #t

STklos procedure

(get-signal-handler! sig)

Return the handler for integer signal sig. The value of handler can be a boolean value or a procedure. See primitive set-signal-handler! for more information.

STklos procedure

(send-signal sig)
(send-signal sig pid)

Send the integer signal sig to the process with pid process id. If the second parameter is absent, it deaults to the one of the running program.

STklos procedure

(pause)

Pauses the STklos process until the delivery of a signal whose action is either to execute a signal-catching function or to terminate the process. If the action is to terminate the process, pause will not return. If the action is to execute a signal-catching function, pause will terminate after the signal-catching function returns.

4.21. Parameter Objects

STklos parameters correspond to the ones defined in SRFI-39 (Parameters objects). See SRFI document for more information.

STklos procedure

(make-parameter init)
(make-parameter init converter)

Returns a new parameter object which is bound in the global dynamic environment to a cell containing the value returned by the call (converter init). If the conversion procedure converter is not specified the identity function is used instead.

The parameter object is a procedure which accepts zero or one argument. When it is called with no argument, the content of the cell bound to this parameter object in the current dynamic environment is returned. When it is called with one argument, the content of the cell bound to this parameter object in the current dynamic environment is set to the result of the call (converter arg), where arg is the argument passed to the parameter object, and an unspecified value is returned.

(define radix
    (make-parameter 10))

(define write-shared
   (make-parameter
      #f
      (lambda (x)
        (if (boolean? x)
            x
            (error 'write-shared "bad boolean ~S" x)))))

 (radix)           =>  10
 (radix 2)
 (radix)           =>  2
 (write-shared 0)  => error

 (define prompt
   (make-parameter
     123
     (lambda (x)
       (if (string? x)
           x
           (with-output-to-string (lambda () (write x)))))))

 (prompt)       =>  "123"
 (prompt ">")
 (prompt)       =>  ">"

STklos syntax

(define-parameter var val)
(define-parameter var val thunk)

This form is a shortcut to define a new parameter named var. It also adds a name to the created parameter object, which can be useful for debugging.

STklos syntax

(parameterize ((expr1 expr2) …​) <body>)

The expressions expr1 and expr2 are evaluated in an unspecified order. The value of the expr1 expressions must be parameter objects. For each expr1 expression and in an unspecified order, the local dynamic environment is extended with a binding of the parameter object expr1 to a new cell whose content is the result of the call (converter val), where val is the value of expr2 and converter is the conversion procedure of the parameter object. The resulting dynamic environment is then used for the evaluation of <body> (which refers to the R5RS grammar nonterminal of that name). The result(s) of the parameterize form are the result(s) of the <body>.

(radix)                                              =>  2
(parameterize ((radix 16)) (radix))                  =>  16
(radix)                                              =>  2

(define (f n) (number->string n (radix)))

(f 10)                                               =>  "1010"
(parameterize ((radix 8)) (f 10))                    =>  "12"
(parameterize ((radix 8) (prompt (f 10))) (prompt))  =>  "1010"

STklos procedure

(parameter? obj)

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

4.22. Misc

STklos procedure

(gc)

Force a garbage collection step.

STklos procedure

(void)
(void arg1 …​)

Returns the special void object. If arguments are passed to void, they are evalued and simply ignored.

STklos procedure

(void? obj)

Returns #t if obj is #void, and #f otherwise. The usual "unspecified" result in Scheme standard and in SRFIs is #void in STklos, and it is also returned by the procedure void.

(void? (void))                    => #t
(define x (if #f 'nope))
(void? x)                         => #t
(void? '())                       => #f
(void? 'something)                => #f
(void? (for-each print '(1 2 3))) => #t

R7RS procedure

(error str obj …​)
(error name str obj …​)

error is used to signal an error to the user. The second form of error takes a symbol as first parameter; it is generally used for the name of the procedure which raises the error.

R7RS permits only the fist form of call. Using a symbol as first parameter is STklos specific. Furthermore, the specification string may follow the tilde conventions of format (see primitive format); in this case this procedure builds an error message according to the specification given in str. Otherwise, this procedure is in conformance with the error procedure defined in SRFI-23 (Error reporting mechanism) and str is printed with the display procedure, whereas the obj parameters are printed with the write procedure.

Hereafter, are some calls of the error procedure using a formatted string

(error "bad integer ~A" "a")
                     |- bad integer a
(error 'vector-ref "bad integer ~S" "a")
                     |- vector-ref: bad integer "a"
(error 'foo "~A is not between ~A and ~A" "bar" 0 5)
                     |- foo: bar is not between 0 and 5

and some conform to SRFI-23

(error "bad integer" "a")
                    |- bad integer "a"
(error 'vector-ref "bad integer" "a")
                   |- vector-ref: bad integer "a"
(error "bar" "is not between" 0 "and" 5)
                   |- bar "is not between" 0 "and" 5

STklos procedure

(signal-error cond str obj …​)
(signal-error cond name str obj …​)

This procedure is similar to error, except that the type of the error can be passed as the first parameter. The type of the error must be a condition which inherits from &error-message.

Note that (error arg …​) is equivalent to

(signal-error &error-message arg ...)

R7RS syntax

(syntax-error message arg1 …​)
(syntax-error who message arg1 …​)

Syntax-error behaves similarly to error except that it signals the error as soon as syntax-error is expanded. This can be use in macros to signal errors at compile time, without interrupting the compilation process. In interactive mode, under the REPL, syntax-error yields a true error.

R7RS defines only the first form of call (with a string as first parameter). STklos permits to use a symbol as first parameter to specify the location of the syntax error. It also permits the usage of tilde conventions as the error primitive.

R7RS procedure

(read-error? obj)
(file-error? obj)

Error type predicates. Returns #t if obj is an object raised by the read procedure or by the inability to open an input or output port on a file, respectively. Otherwise, it returns #f.

R7RS procedure

(error-object? obj )

Returns #t if obj is an object created by error. Otherwise, it returns #f.

R7RS procedure

(error-object-message error-object)

Returns the message encapsulated by error-object.

R7RS procedure

(error-object-irritants error-object)

Returns the message encapsulated by error-object.

STklos procedure

(error-object-location error-object)

Returns the location encapsulated by error-object if it exists. Returns #f otherwise. The location corresponds generally to the name of the procedure which raised the error.

(guard (cnd
         (else (error-object-location cnd)))
  (error 'foo "error message"))  => foo

STklos syntax

(require-extension <clause> …​)

The syntax of require-extension is as follows:

(require-extension <clause> ...)

A clause may have the form:

  1. (srfi number …​)

  2. (identifier …​)

  3. identifier

In the first form the functionality of the indicated SRFIs are made available in the context in which the require-extension form appears. For instance,

(require-extension (srfi 1 2)) ; Make the SRFI 1 and 2 available

This form is compatible with SRFI-55 (Require-extension).

The second and third forms are STklos extensions. If the form is a list, it is equivalent to an import. That is,

(require-extension (streams primitive) (streams derived))

is equivalent to

(import (streams primitive) (streams derived))

The final form permits to use symbolic names for requiring some extensions. For instance,

(require-extension lists and-let*)

is equivalent to the requiring srfi-1 and srfi-2.

A list of available symbolic names for features is given in Chapter 13.

STklos procedure

(require-feature feature)

This primitive ensures that the feature (in sense of SRFI-0 feature) can be used. In particular, it eventually requires the loading of the files needed to used feature. The feature can be expressed as a string or a symbol, If feature is an integer n, it is equivalent to srfi-n. Consequently, to use SRFI-1 the following forms are equivalent:

(require-feature 'srfi-1)
(require-feature "srfi-1")
(require-feature 1)
(require-feature 'lists)      ;; Since this feature name is an alias for SRFI-1

See also Chapter 13 for more information.

STklos syntax

(assume obj …​)

The special form assume is defined in SRFI-145 (Assumptions). When STklos is in debug mode, this special form is an expression that evaluates to the value of obj if obj evaluates to a true value and it is an error if obj evaluates to a false value.

When STklos is not in debug mode, the call to assume is elided.

STklos procedure

(version-alist)

This function returns an association list of STklos properties as defined by SRFI-176 (Version flag).

STklos procedure

(apropos obj)
(apropos/alist obj)
(apropos/pp obj)
(apropos obj module …​)
(apropos/alist obj module …​)
(apropos/pp obj module …​)

These procedures return the symbols whose print name contains the characters of obj as a substring, in the specified modules. The given obj can be a string or symbol, and each module argument can be a symbol, a string, or the module itself.

  • If no module is provided, the current module is used.

  • If modules are given, then these modules are searched.

  • If only a single #t argument is given for a module, then all matching symbols from all loaded modules will be searched.

The apropos command returns the symbols that can be used in a given module, that is:

  • it returns the symbols defined or imported if the module is the current module.

  • it returns the symbols exported by the module, if this module it is not the current one.

The three variants of apropos are:

  • apropos returns a flat list of symbols, and no information about the modules where they are defined.

  • apropos/alist returns an association list where the key is a module name (as a symbol) and the data is a list of matched symbols which can be accessed from the given module.

  • apropos/pp does not have a return value, but prints the symbols on the screen, categorized by module.

Note that using #t will bring the same symbols in several different modules, since modules (as opposed to libraries) inherit all bindings in the STklos module.

(define-library (A)
  (export zeta-one zeta-two zeta-three)
  (begin (define zeta-one 1)
         (define zeta-two 2)
         (define theta-three 3)))
(define-library (B)
  (export zeta-two zeta-three theta-four) ; but not zed
  (begin (define zeta-two 2)
         (define zeta-three 3)
         (define theta-four 4)
         (define zed 5)))
(define-library (C)
  (export zee)
  (import (B))
  (begin (define zee -1)))

(apropos/alist 'zeta
               'A                      ; a symbol (module name)
               (find-module 'B))       ; and a module
         => ( (A (zeta-one zeta-three zeta-two))
              (B (zeta-three zeta-two)) )

(apropos/pp 'zeta
               "A"                     ; a string (module name)
               'B)                     ; a symbol (module name)
         => void
And outputs, to the current output port, the following:
Module A:
   zeta-one
   zeta-three
   zeta-two
Module B:
   zeta-three
   zeta-two

(apropos "x" (find-module 'A))         ; obj is a string
         => ()                         ; no symbol found

(apropos 'o '(B))                      ; module name can be a list
         => (theta-four zeta-two)      ; simple list returned by apropos

(apropos/alist 'a #t)
         => <all symbols with "a" in their names exported by all modules>

STklos procedure

(help obj)
(help)

When called with an argument, help tries to give some help on the given object, which could be a symbol, a procedure, a generic function or a method. Whe called called without arguments, help enters a read-help-print loop. The documentation for an object is searched in the object itself or, if absent, in STklos documentation. Inserting the documentation in an objet is very similar to Emacs docstrings: a documentation string is defined among the code. Exemples of such strings are given below

(define (foo n)
  "If the function body starts with a string, it's a docstring"
  (+ n 1))

(define-generic bar
  :documentation "Generic function docsting for bar")

(define-method bar ((x <integer>))
  "Probably less useful: as in functions, methods can have docstrings"
  (- x 1))

STklos procedure

(describe obj)

Shows a brief description of obj. If the object is structured such as a struct, class or instance, some information about its internal structure will be shown.

Using describe on simple values

(describe 10)
  10 is a fixnum integer number (#xa #o12 #b1010).

(describe 5.4)
  5.4 is a real.

(describe 2+3i)
  2+3i is a complex number.

(describe #)
  # is a character whose Unicode code point is 233.

Using describe on a class

(describe <integer>)
  <integer> is a class. It's an instance of <class>.
  Superclasses are:
      <rational>
  (No direct slot)
  Directs subclasses are:
      <fixnum>
      <bignum>
  Class Precedence List is:
      <integer>
      <rational>
      <real>
      <complex>
      <number>
      <top>
  (No direct method)

Using describe on structures

(define-struct person name email)
(define one (make-person "Some One" "one@domain.org"))

(describe person)
  #[struct-type person 139786494092352] is a structure type whose name is person.
  Parent structure type: #f
  Slots are:
       name
       email

(describe one)
  #[struct person 139786494288064] is an instance of the structure type person.
  Slots are:
       name = "Some One"
       email = "one@domain.org"

STklos procedure

(default-browser)
(default-browser str)

This parameter object denotes the name of the browser used by STklos to open URLs. The value of this parameter is set at initialization time to (in that order):

  • the value of the shell variable STKLOS_BROWSER, if it is set, or

  • the value of the shell variable BROWSER, if it is set, or

  • the string "open" on macOS, or "xdg-open" on other OS.

STklos procedure

(open-in-browser url)

Opens the URL given by the string url in the default browser, which is determined by the string contained in the parameter default-browser.

STklos procedure

(manual)
(manual entry)

Opens the STklos manual in a browser. If the symbol or the string entry is given, the manual is opened on the description of entry. NOTE: If the HTML manual file is not installed, the documentation is searched on the STklos web site, which can incur a non-negligible response time. NOTE: another name for this function is man.

STklos syntax

(trace f-name …​)

Invoking trace with one or more function names causes the functions named to be traced. Henceforth, whenever such a function is invoked, information about the call and the returned values, if any, will be printed on the current error port.

Calling trace with no argument returns the list of traced functions.

STklos syntax

(untrace f-name …​)

Invoking untrace with one or more function names causes the functions named not to be traced anymore.

Calling untrace with no argument will untrace all the functions currently traced.

STklos procedure

(pretty-print sexpr :key port width)
(pp sexpr :key port width)

This function tries to obtain a pretty-printed representation of sexpr. The pretty-printed form is written on port with lines which are no more long than width characters. If port is omitted if defaults to the current error port. As a special convention, if port is #t, output goes to the current output port and if port is #f, the output is returned as a string by pretty-print. Note that pp is another name for pretty-print.

STklos procedure

(procedure-formals proc)

Returns the formal parameters of procedure proc. Note that procedure formal parameters are kept in memory only if the compiler flag <<"compiler:keep-formals">> is set at its creation. If proc formal parameters are not available, procedure-formals returns #f.

(compiler:keep-formals #t)

(define (f x y) (+ (* 3 x) y))
(procedure-formals f)           => (x y)

STklos procedure

(procedure-source proc)

Returns the source form used to define procedure proc. Note that procedure source is kept in memory only if the compiler flag <<"compiler:keep-source">> is set at its creation. If proc source is not available, procedure-source returns #f.

(compiler:keep-source #t)

(define (f x y) (+ (* 3 x) y))
(procedure-source f)           => (lambda (x y) (+ (* 3 x) y))

STklos procedure

(ansi-color e1 e2 …​ en)

ansi-color permits to build a string which embeds ANSI codes to colorize texts on a terminal. Each expression ei must be a string, a symbol or an integer.

Strings constitute the message to be displayed.

A symbol can designate

  • a color in the set {black, red, green, yellow, blue, magenta, cyan, white} for foreground colors

  • a color in the set {bg-black, bg-red, bg-green, bg-yellow, bg-blue, bg-magenta, bg-cyan, bg-white} for background colors.

  • a qualifier such as normal, bold, italic, underline, blink, reverse or no-bold, no-italic, no-underline, no-blink, no-reverse.

Integer values can be used for terminals which are able to display 256 colors. If the number is positive, it is used as a foreground color. Otherwise, it is uses as a background color. Note that not all the terminals are able to use more than eight colors.

For instance,

(display (ansi-color "a word in "
                     'bold 'red "RED" 'normal
                     " and another in "
                     'reverse 'blue "BLUE" 'normal))

will display the words BLUE and RED in color.

STklos procedure

(disassemble proc)
(disassemble proc port)

This function prints on the given port (by default the current output port) the instructions of procedure proc. The printed code uses an ad-hoc instruction set that should be quite understandable.

(define (fact n)
  (if (< n 2)
      1
      (* n (fact (- n 1)))))

The call (disassemble fact) will produce the following output:

   000:  LOCAL-REF0-PUSH
   001:  SMALL-INT            2
   003:  JUMP-NUMGE           2  ;; ==> 007
   005:  IM-ONE
   006:  RETURN
   007:  LOCAL-REF0-PUSH
   008:  PREPARE-CALL
   009:  LOCAL-REF0
   010:  IN-SINT-ADD2         -1
   012:  PUSH-GREF-INVOKE     0 1
   015:  IN-MUL2
   016:  RETURN
The code of a procedure may be patched after the first execution of proc to optimize it.

If proc is an anonymous function, you can use the special notation #pxxx to disassemble it: *

(disassemble #p7fee1dd82f80)  ;; (address-of (lambda() 42))

      000:  SMALL-INT            42
      002:  RETURN

STklos procedure

(disassemble-expr sexpr)
(disassemble-expr sexpr show-consts)
(disassemble-expr sexpr show-consts port)

This function prints on the given port (by default the current output port) the instructions of the given sexpr. If show-consts is true, the table of the contants used in sexpr is also printed.

(disassemble-expr '(begin
                      (define x (+ y 10))
                      (cons x y))
                    #t)

will print:

000:  GLOBAL-REF           0
002:  IN-SINT-ADD2         10
004:  DEFINE-SYMBOL        1
006:  GLOBAL-REF-PUSH      1
008:  GLOBAL-REF           0
010:  IN-CONS
011:

Constants:
0: y
1: x

STklos procedure

(uri-parse str)

Parses the string str as an RFC-2396 URI and return a keyed list with the following components

  • scheme : the scheme used as a string (defaults to "file")

  • user: the user information (generally expressed as login:password)

  • host : the host as a string (defaults to "")

  • port : the port as an integer (0 if no port specified)

  • path : the path

  • query : the qury part of the URI as a string (defaults to the empty string)

  • fragment : the fragment of the URI as a string (defaults to the empty string)

(uri-parse "https://stklos.net")
   => (:scheme "https" :user "" :host "stklos.net" :port 443
        :path "/" :query "" :fragment "")

(uri-parse "https://stklos.net:8080/a/file?x=1;y=2#end")
    => (:scheme "http" :user "" :host "stklos.net" :port 8080
        :path "/a/file" :query "x=1;y=2" :fragment "end")

(uri-parse "http://foo:secret@stklos.net:2000/a/file")
    => (:scheme "http" :user "foo:secret" :host "stklos.net"
        :port 2000  :path "/a/file" :query "" :fragment "")

(uri-parse "/a/file")
   => (:scheme "file" :user "" :host "" :port 0 :path "/a/file"
       :query "" :fragment "")

(uri-parse "")
   => (:scheme "file"  :user "" :host "" :port 0 :path ""
       :query "" :fragment "")

STklos procedure

(string→html str)

This primitive is a convenience function; it returns a string where the HTML special chars are properly translated. It can easily be written in Scheme, but this version is fast.

(string->html "Just a <test>")
   => "Just a &lt;test&gt;"

STklos procedure

(md5sum obj)

Return a string contening the md5 sum of obj. The given parameter can be a string or an open input port.

STklos procedure

(md5sum-file str)

Return a string contening the md5 sum of the file whose name is str.

STklos procedure

(base64-encode in)
(base64-encode in out)

Encode in Base64 the characters from input port in to the output port out. If out is not specified, it defaults to the current output port.

(with-input-from-string "Hello"
  (lambda ()
    (with-output-to-string
      (lambda ()
        (base64-encode (current-input-port)))))) => "SGVsbG8="

STklos procedure

(base64-decode in)
(base64-decode in out)

Decode the Base64 characters from input port in to the output port out. If out is not specified, it defaults to the current output port.

(with-input-from-string "SGVsbG8="
  (lambda ()
    (with-output-to-string
      (lambda ()
        (base64-decode (current-input-port))))))  => "Hello"

STklos procedure

(base64-encode-string str)

Return a string contening the contents of str converted to Base64 encoded format.

STklos procedure

(base64-decode-string str)

Decode the contents of str expressed in Base64.


1. Documentation about hygienic macros has been stolen in the SLIB manual
1. In fact define-module on a given name defines a new module only the first time it is invoked on this name. By this way, interactively reloading a module does not define a new entity, and the other modules which use it are not altered.
2. This transcript uses the default toplevel loop which displays the name of the current module in the evaluator prompt.
1. Under Unix, you can simply connect to a listening socket with the telnet of netcat command. For the given example, this can be achieved with netcat localhost 12345
2. Port 13, if open, can be used for testing: making a connection to it permits to know the distant system’s idea of the time of day.