sunterlib/s48/sequences
Rolf-Thomas Happe c294d73444 some more start&ends 2003-02-15 02:48:52 +00:00
..
README doc w/o examples and proof-reading 2003-02-15 02:39:50 +00:00
baseqs.scm s48/krims/README 2003-02-14 00:47:58 +00:00
composeqs.scm s48/krims/README 2003-02-14 00:47:58 +00:00
genseqs.scm some more start&ends 2003-02-15 02:48:52 +00:00
interfaces.scm some more start&ends 2003-02-15 02:48:52 +00:00
packages.scm some more start&ends 2003-02-15 02:48:52 +00:00
specseqs.scm some more start&ends 2003-02-15 02:48:52 +00:00
uniseqs.scm some more start&ends 2003-02-15 02:48:52 +00:00

README

sunterlib/s48/sequences -- Finite Sequences

A sequence library in various structures dealing with
* abstract sequences defined by their behaviour
* general sequences or a union type of built-in and abstract sequences
* vectors in particular
  [ for list and string libraries ,open srfi-1 resp. srfi-13 ]

The library comes in three structures:
* BEHAVED-SEQUENCES -- basic procedures for abstract sequences
* SEQUENCE-LIB      -- B.S. + procedures for general sequences
* VECTOR-LIB        -- procedures for vectors

The VECTOR-LIB exports some SCHEME bindings such as VECTOR-REF, but
consists mainly of generic sequence code compiled with the basic
sequence operation names bound to the corresponding vector procedures.
The library is neither complete nor tweaked.  (The idea to recycle parts
of the srfi-13 code came too late.)  It contains the folllowing procedures
(in the categories of srfi-13):

VECTOR-LIB            SEQUENCE-LIB             BEHAVED-SEQUENCES, also SL
* Predicates or so
vector?               sequence?                behaved-sequence?
                                               sequence-type?
[ versions with 1 sequence and optional start & end parameters ]
vector-every          sequence-every
vector-any            sequence-any
[ versions with >1 sequence but no optional start & end parameters ]
vectors-every         sequences-every
vectors-any           sequences-any

* Constructors
make-vector           make-another-sequence    make-behaved-sequence/type
vector                                         behaved-sequence/type
                                               make-sequence-type
                                               make-behaved-sequence-record

* List & Sequence Conversion
list->vector                                   list->behaved-sequence/type
vector->list          sequence->list

* Selection
vector-length         sequence-length          behaved-sequence-length
vector-ref            sequence-ref             behaved-sequence-ref
                                               behaved-sequence:type
vector-copy           sequence-copy
subvector             subsequence

* Modification
vector-set!           sequence-set!            behaved-sequence-set!
sequence-fill!        vector-fill!             behaved-sequence-fill!

* Reverse & Append
vector-append         sequence-append

* Fold, Unfold & Map
[ versions with 1 sequence and optional start & end parameters ]
vector-map            sequence-map
vector-for-each       sequence-for-each
vector-fold           sequence-fold
vector-fold-right     sequence-fold-right
[ versions with >1 sequence but no start & end parameters ]
vectors-map           sequences-map
vectors-for-each      sequences-for-each
vectors-fold          sequences-fold
vectors-fold-right    sequences-fold-right

NOTE -- Some procedures take several sequence arguments and create a 
new sequence with the concrete type of the first one: SEQUENCE-APPEND
and the SEQUENCES-procedures in the Map etc. category.  Problem:  the 
target sequence may accept only elemens of a particular type (think
of strings and characters).  Solution:  Provide a vector, say, as first 
arg sequence:
             (sequence-append "aber" '(1) '#(3 3)) breaks, but
             (sequence-append '#() "aber" '(1) '#(3 3)) succeeds.

I concede, that's not totally satisfying.  A shallow aftertaste of cat 
pee remains in my mouth.  

                                  *

Prelude

For our purposes, (each valid state of) a sequence with length n maps a 
bounded segment of integers [0:n) into a set of Scheme values, typically
Anything or Character.  Any kind Se of sequences with elements in T 
supports the following basic operations: 

  maker :     make n [x] ==> s
    n in [0:oo),  optional x : T,  s : Se
    The fresh sequence s represents a sequence of length n (mapping to x)
  predicate : x ==> b 
    x : Anything, b : Boolean
    the type predicate `x in Se'
  getter :    ref s k ==> s[k]
    s in Se,  k in [0:n) with n = length s,  s[k] in T
  setter :    set! s k x ==> unspec
    s in Se,  x in T,  k in [0:n) with n = length s
    effect: s[k] = x, s[other] as before
  meter :     length s ==> n
    s in ST, n in [0:oo) length of sequence


This sequence facility supports the following kinds of sequences:

  Vector
  Behaved-Sequence := a record type (record packages data + behaviour)
  Sequence := Vector | Byte-Vector | String | Proper-List | Behaved-Sequence

Behaved-Sequences carry a SEQUENCE-TYPE record that contains MAKER, 
PREDICATE, etc. procedures with the properties sketched above. 
They are the official backdoor where user-defined sequence types enter 
the general sequence lib.  There are Examples.

[ Wouldn't ABSEQUENCE have been much more beautiful than BEHAVED-SEQUENCE? ]

                                    *

The Procedures

Optional [START END] (abbreviating [START [END]]) arguments default to 0 
resp. the sequence length.

* Predicates

(vector? x) ==> b
(sequence? x) ==> b
(behaved-sequence? x) ==> b
(sequence-type? x) ==> b

Synopsis:  The obvious type predicates.  Note that behaved-sequences
are sequences and carry a sequence-type with them.  Sequence-types
are not sequences but package the behaviour of concrete sequence types.

                                    *

(vector-every foo? s [start end]) ==> x
(sequence-every foo? s [start end]) ==> x

Synopsis:  Return the value x of (and (foo? s[start]) ... (foo? s[end-1])).

                                    *

(vector-any foo? s [start end]) ==> x
(sequence-any foo? s [start end]) ==> x

Synopsis:  Return the value x of (or (foo? s[start]) ... (foo? s[end-1])).

                                   *

(vectors-every foo? s0 ...) ==> b
(sequences-every foo? s [start end]) ==> b

Synopsis:  Return the value x of (and[0<=i<n] (foo? s0[i] ...)) with
n := min.k sequence-length sk.

                                   *

(vectors-any foo? s0 ...) ==> b
(sequences-any foo? s [start end]) ==> b

Synopsis:  Return the value x of (or[0<=i<n] (foo? s0[i] ...)) with
n := min.k sequence-length sk.

                                  *

Constructors

(make-vector len [fill]) ==> v
(make-behaved-sequence/type st len [fill]) ==> bs

Synopsis:  Make a fresh vector V (behaved-sequence BS with sequence-type 
ST) of length LEN (and all elements = FILL).

                                  *

(vector x0 ...) ==> v
(behaved-sequence/type st x0 ...) ==> bs

Synopsis:  Make a fresh vector V (behaved-sequence BS with sequence-type
ST) of minimal length with the elements V[0] = X0, ... (BS[0] = X0, ...).

                                  *

(make-sequence-type maker predicate getter setter meter) ==> st

Synopsis: Package the concrete sequence behaviour (basic procedures
described in the prelude) in the sequence-type record ST.

(make-behaved-sequence-record st data) ==> bs
Synopsis:  Package the sequence-type ST and the concrete sequence DATA
in the behaved-sequence record BS.

                                  *

List & Sequence Conversion

(list->vector xs [start end]) ==> v
(list->behaved-sequence/type st xs [start end]) ==> bs

Synopsis:  Make a new vector V (behaved-sequence BS with sequence-type ST)
representing the sequence xs[start],..,xs[end-1].

                                 *

(vector->list v [start end]) ==> xs
(sequence->list s [start end]) ==> xs

Synopsis:  Return xs = (list v[start] ... v[end-1]) etc.

                                 *

(vector-length v) ==> n
(sequence-length s) ==> n
(behaved-sequence-length bs) ==> n

Synopsis:  Return length N of sequence represented by V : Vector, S :
Sequence, BS : Behaved-Sequence.  You knew that, didn't you?
                  
                                 *

(vector-ref v k) ==> v[k]
(sequence-ref s k) ==> s[k]
(behaved-sequence-ref bs k) ==> bs[k]

                                 *

(behaved-sequence:type bs) ==> st

Synopsis:  Return sequence-type ST for concrete sequence packaged in 
behaved-sequence BS.

                                 *

(vector-copy v0 [start end]) ==> v1
(sequence-copy s0 [start end]) ==> s1

Synopsis:  Copy v0[start],..,v0[end-1] into a new vector v1 of minimal 
length.  Resp. represent s0[start],...,s0[end-1] as a new sequence S1 of
the same type.

                                 *

(subvector v0 start end) ==> v1
(subsequence s0 start end) ==> s1

Synopsis:  Like xxx-copy with obligatory source index bounds.

                                *

Modification

(vector-set! v i x) ==> unspec
(sequence-set! s i x) ==> unspec
(behaved-sequence-set! bs i x) ==> unspec

Synopsis:  Set v[i] := x etc.

                                *

(vector-fill! v x [start end]) ==> unspec
(sequence-fill! s x [start end]]) ==> unspec
(behaved-sequence-fill! bs x [start end]) ==> unspec

Synopsis:  Set v[i] := x for all i in [start:end) etc.

                                *                              

Reverse & Append

(vector-append v0 ...) ==> v
(sequence-append s0 s1 ...) ==> s

Synoposis:  Make a new vector V (sequence S of type(S0)) representing
you know what.  See the NOTE above.  

                                *

Fold, Unfold & Map

(vector-map f v [start end]) ==> fv
(vectors-map f v0 ...) ==> fv*
(sequence-map f s [start end]) ==> fs
(sequences-map f s0 s1 ...) ==> fs*

Synopsis:  Make new vector FV (FV*, sequence FS of type(S), FS* of type(S0))
representing the sequence f(v[start]),...,f(v[end-1]), resp. the 
sequence (f(v0[i],...) : 0<=i<n) with n = min.k sequence-length sk, etc.
See the NOTE above.

                                *

(vector-for-each proc v [start end]) ==> unspec
(vectors-for-each f v0 ...) ==> unspec
(sequence-for-each proc s [start end]) ==> unspec
(sequences-for-each proc v0 ...) ==> unspec

Synopsis:  Call (proc v[i]) for all i in [start:end) in some order, resp.
call (proc v0[i] ...) for all i in [0:n) in some order with 
n = min.k sequence-length vk, etc.  

                                *

(vector-fold kons nil v [start end]) ==> w
(vectors-fold kons nil v0 ...) ==> w
(sequence-fold kons nil s0 [start end]) ==> s
(sequences-fold kons nil s0 ...) ==> s

Synopsis:  Let  y o x := (kons x y)  resp.
                y o (x0 ...) := (kons x0 ... y),
 
and let o be left-associative (so that we can spare us the brackets).  
Compute
        w = nil o v[start] o ... o v[end-1],  resp.
        w = nil o (v0[0] ...) o ... o (v0[n-1] ...)
with
        n := min.k sequence-length vk;

etc., and see the NOTE above.

                               *

(vector-fold-right kons nil v [start end]) ==> w
(vectors-fold-right kons nil v0 ...) ==> w
(sequence-fold-right kons nil s0 [start end]) ==> s
(sequences-fold-right kons nil s0 ...) ==> s

Synopsis:  Let  x o y := (kons x y)       resp.
         (x0 ...) o y := (kons x0 ... y),
 
and let o be right-associative (so that we can spare us the brackets).  
Compute
        w = v[start] o ... o v[end-1] o nil,        resp.
        w = (v0[0] ...) o ... o (v0[n-1] ...) o nil
with
        n := min.k sequence-length vk;

etc., and see the NOTE above.

                                 *

Examples: forthcoming

                                 *

Sela (for now).

                                oOo