535 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			535 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
sunterlib/scsh/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 ]
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
Package Dependencies
 | 
						|
 | 
						|
SEQUENCES' structures depend on structures from this other sunterlib
 | 
						|
project:
 | 
						|
            krims
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
 | 
						|
The library comes in three structures:
 | 
						|
* ABSEQUENCES  -- basic procedures for abstract sequences, contained in
 | 
						|
* SEQUENCE-LIB -- procedures for general (and abstract) sequences
 | 
						|
* VECTOR-LIB   -- procedures for vectors
 | 
						|
 | 
						|
The VECTOR-LIB exports some SCHEME bindings such as VECTOR-REF, redefines
 | 
						|
some SCHEME procedures such as VECTOR-FILL! (to accept optional [start:end)
 | 
						|
parameters) and 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 nor tested
 | 
						|
sytematically.  (The idea to recycle parts of the srfi-13 code came
 | 
						|
too late.)  It contains the following procedures, arranged in
 | 
						|
columns=structures and `* categories' from SRFI-13 and -1, followed
 | 
						|
by the list of name clashes with standard modules.
 | 
						|
 | 
						|
 | 
						|
VECTOR-LIB            SEQUENCE-LIB             ABSEQUENCES, also S.L.
 | 
						|
* Predicates or so
 | 
						|
vector?               sequence?                absequence?
 | 
						|
                                               sequence-behavior?
 | 
						|
vector-null?          sequence-null?
 | 
						|
vector-every          sequence-every
 | 
						|
vector-any            sequence-any
 | 
						|
vectors-every         sequences-every
 | 
						|
vectors-any           sequences-any
 | 
						|
vector=               sequence=
 | 
						|
vectors=              sequences=
 | 
						|
 | 
						|
* Constructors
 | 
						|
make-vector           make-another-sequence    make-absequence/behavior
 | 
						|
vector
 | 
						|
vector-tabulate
 | 
						|
                                               absequence/behavior
 | 
						|
                                               make-sequence-behavior
 | 
						|
                                               make-absequence-record
 | 
						|
 | 
						|
* List & Sequence Conversion
 | 
						|
list->vector                                   list->absequence/behavior
 | 
						|
vector->list          sequence->list
 | 
						|
 | 
						|
* Selection
 | 
						|
vector-length         sequence-length          absequence-length
 | 
						|
vector-ref            sequence-ref             absequence-ref
 | 
						|
                                               absequence:behavior
 | 
						|
vector-copy           sequence-copy
 | 
						|
                      sequence-copy/maker
 | 
						|
vector-copy!          sequence-copy!
 | 
						|
subvector             subsequence
 | 
						|
 | 
						|
* Modification
 | 
						|
vector-set!           sequence-set!            absequence-set!
 | 
						|
sequence-fill!        vector-fill!             absequence-fill!
 | 
						|
sequence-tabulate!    vector-tabulate!
 | 
						|
 | 
						|
* Reverse & Append
 | 
						|
vector-append         sequence-append
 | 
						|
 | 
						|
* Fold, Unfold & Map
 | 
						|
vector-map            sequence-map
 | 
						|
                      sequence-map/maker
 | 
						|
vector-map-into!      sequence-map-into!
 | 
						|
vector-for-each       sequence-for-each
 | 
						|
vector-fold           sequence-fold
 | 
						|
vector-fold-right     sequence-fold-right
 | 
						|
vectors-map           sequences-map
 | 
						|
                      sequences-map/maker
 | 
						|
vectors-map-into!     sequences-map-into!
 | 
						|
vectors-for-each      sequences-for-each
 | 
						|
vectors-fold          sequences-fold
 | 
						|
vectors-fold-right    sequences-fold-right
 | 
						|
 | 
						|
* Name clashes with scheme
 | 
						|
vector-fill!
 | 
						|
list->vector
 | 
						|
 | 
						|
When using both SCHEME and VECTOR-LIB, you should choose the binding
 | 
						|
explicitly, like so:
 | 
						|
 | 
						|
    (open (modify scheme (hide vector-fill!
 | 
						|
                               list->vector))
 | 
						|
          vector-lib)
 | 
						|
 | 
						|
                                  *
 | 
						|
 | 
						|
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 or objects,
 | 
						|
typically Anything or Character.  Any kind Sq of sequences with elements
 | 
						|
in T supports the following basic operations, whatever the names, with the
 | 
						|
obvious jobs:
 | 
						|
                 maker :     (make-sq n [e]) --> s
 | 
						|
                 predicate : (sq? x) --> b
 | 
						|
                 getter :    (sq-ref s k) --> s[k]
 | 
						|
                 setter :    (sq-set! s k x) --> unspec
 | 
						|
                 meter :     (sq-length s) --> n
 | 
						|
 | 
						|
 | 
						|
The following kinds of sequences are supported by this facility:
 | 
						|
 | 
						|
  Vector
 | 
						|
  Absequence := a record type (record packages data + behaviour)
 | 
						|
  Sequence := Vector | Byte-Vector | String | Proper-List | Absequence
 | 
						|
 | 
						|
Absequences carry a SEQUENCE-BEHAVIOR record that contains MAKER,
 | 
						|
PREDICATE, etc. procedures.  They are the official backdoor where
 | 
						|
user-defined sequence types enter the general sequence lib.  There are
 | 
						|
Examples.  [ The Examples demonstrate how one might introduce hidden
 | 
						|
aliasing, i.e. shared subsequences, and break some banged procedures ... ]
 | 
						|
 | 
						|
                                    *
 | 
						|
 | 
						|
The Procedures
 | 
						|
 | 
						|
Optional [START END] (abbreviating [START [END]]) parameters default to 0
 | 
						|
resp. the sequence length.  An optional MAKER parameter defaults to
 | 
						|
the maker of the actual type of the (first) sequence argument.
 | 
						|
Sequence arguments of vector and absequence procedures must be vectors
 | 
						|
resp. absequences, notwithstanding the generic parameter name S used below.
 | 
						|
Sequence arguments of general sequence procedures may have different
 | 
						|
actual sequence types, e.g. (SEQUENCES-EVERY CHAR=? "abc" '#(#\a)) is
 | 
						|
ok since both String and Vector <= Sequence.
 | 
						|
 | 
						|
Equivalences
 | 
						|
  as far as the specs go, that is: the equivalences don't extend to
 | 
						|
unspecified behaviour but I didn't bother to spell this out in detail.
 | 
						|
The stated equivalences may have to suffer from exceptions as the
 | 
						|
library grows, but please report deviations anyway.
 | 
						|
 | 
						|
* (sequences-foo x ...) = (sequence-foo x ...) and
 | 
						|
  (vectors-foo x ...) = (vector-foo x ...)
 | 
						|
  if the arg.list is admissible for both procedures.
 | 
						|
  [ SEQUENCES-procedures don't support optional [start:end)
 | 
						|
  parameters;  SEQUENCE-procedures don't support an arbitrary number
 | 
						|
  of sequence arguments.  Same for vectors. ]
 | 
						|
 | 
						|
* if all sequence arguments to a general sequence procedure are
 | 
						|
  vectors the result is that of the corresponding vector procedure.
 | 
						|
  E.g. ``sequence-map = vector-map'' on vectors.
 | 
						|
 | 
						|
* if all sequence arguments to a general sequence procedure are lists
 | 
						|
  (strings) and there is a corresponding list (string) procedure in
 | 
						|
  the respective srfi, the result complies with the srfi spec.
 | 
						|
  E.g. ``sequences-fold = fold'' on lists,
 | 
						|
       ``sequence-fold = string-fold'' on strings.
 | 
						|
  Attention:
 | 
						|
    SEQUENCE= vs. STRING= -- parameter lists don't match (ELT=)
 | 
						|
    SEQUENCE-TABULATE! (and VECTOR-TABULATE) --
 | 
						|
      parameter list is patterned after (STRING-TABULATE proc len), not
 | 
						|
                                  after   (LIST-TABULATE len proc).
 | 
						|
 | 
						|
* Predicates
 | 
						|
 | 
						|
(vector? x) --> b0
 | 
						|
(sequence? x) --> b1
 | 
						|
(absequence? x) --> b2
 | 
						|
(sequence-behavior? x) --> b
 | 
						|
 | 
						|
Synopsis:  The obvious type predicates.  Note that by the type
 | 
						|
inclusions the boolean B0 ==> B1 and B2 ==> B1.
 | 
						|
 | 
						|
                                    *
 | 
						|
 | 
						|
(vector-null? s) --> b
 | 
						|
(sequence-null? s) --> b
 | 
						|
 | 
						|
Synopsis:  Return B := boolean(s.length = 0).
 | 
						|
 | 
						|
                                    *
 | 
						|
 | 
						|
(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 s1 ...) --> b
 | 
						|
(sequences-every foo? s0 s1 ...) --> b
 | 
						|
 | 
						|
Synopsis:  Return the value x of (and[0<=i<n] (foo? s0[i] s1[i] ...)) with
 | 
						|
n := min.k sequence-length sk.
 | 
						|
 | 
						|
                                   *
 | 
						|
 | 
						|
(vectors-any foo? s0 s1 ...) --> b
 | 
						|
(sequences-any foo? s0 s1 ...) --> b
 | 
						|
 | 
						|
Synopsis:  Return the value x of (or[0<=i<n] (foo? s0[i] s1[i] ...)) with
 | 
						|
n := min.k sequence-length sk.
 | 
						|
 | 
						|
                                  *
 | 
						|
 | 
						|
(vector= elt= s0 s1 [start0 end0 start1 end1]) --> b
 | 
						|
(sequence= elt= s0 s1 [start0 end0 start1 end1]) --> b
 | 
						|
 | 
						|
Synopsis:  Return boolean(S0 and S1 represent the same sequence), i.e.
 | 
						|
B = (and (elt= s0[start0] s1[start1]) ...)
 | 
						|
[ deviates from STRING= in SRFI-13 due to ELT= parameter ]
 | 
						|
 | 
						|
                                  *
 | 
						|
 | 
						|
(vectors= elt= s0 ...) --> b
 | 
						|
(sequences= elt= s0 ...) --> b
 | 
						|
 | 
						|
Synopsis:  Return B = boolean(S0, ... represent the same sequence), i.e.
 | 
						|
B = #t given <2 sequence args, and
 | 
						|
  = (and[k=0,...) (sequence= elt= s(k) s(k+1))) otherwise.
 | 
						|
 | 
						|
                                  *
 | 
						|
 | 
						|
Constructors
 | 
						|
 | 
						|
(make-vector len [fill]) --> s
 | 
						|
(make-absequence/behavior sb len [fill]) --> s
 | 
						|
 | 
						|
Synopsis:  Make a fresh vector resp. absequence S (with sequence-behavior
 | 
						|
SB) of length LEN (and all elements = FILL).
 | 
						|
 | 
						|
                                  *
 | 
						|
 | 
						|
(vector x0 ...) --> s
 | 
						|
(absequence/behavior sb x0 ...) --> s
 | 
						|
 | 
						|
Synopsis:  Make a fresh vector (absequence with sequence-behavior SB)
 | 
						|
of minimal length with the elements S[0] = X0, ...
 | 
						|
 | 
						|
                                  *
 | 
						|
 | 
						|
(vector-tabulate proc len) --> s
 | 
						|
 | 
						|
Synopsis:  Make vector s[0:len) with s[i] := (proc i).
 | 
						|
[ after (string-tabulate proc len) rather than (list-tabulate len proc) ]
 | 
						|
 | 
						|
                                  *
 | 
						|
 | 
						|
(make-sequence-behavior maker predicate getter setter meter) --> sb
 | 
						|
 | 
						|
Synopsis: Package the concrete sequence behaviour (basic procedures
 | 
						|
listed in the prelude) in the sequence-behavior record SB.
 | 
						|
 | 
						|
(make-absequence-record sb data) --> abs
 | 
						|
Synopsis:  Package the sequence-behavior SB and the concrete sequence DATA
 | 
						|
in the absequence record ABS.
 | 
						|
 | 
						|
                                  *
 | 
						|
 | 
						|
List & Sequence Conversion
 | 
						|
 | 
						|
(list->vector xs [start end]) --> s
 | 
						|
(list->absequence/behavior sb xs [start end]) --> s
 | 
						|
 | 
						|
Synopsis:  Make a new vector (absequence with sequence-behavior SB) S
 | 
						|
representing the sequence xs[start],..,xs[end-1].
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
(vector->list s [start end]) --> xs
 | 
						|
(sequence->list s [start end]) --> xs
 | 
						|
 | 
						|
Synopsis:  Return xs = (list s[start] ... s[end-1]).
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
(vector-length s) --> n
 | 
						|
(sequence-length s) --> n
 | 
						|
(absequence-length s) --> n
 | 
						|
 | 
						|
Synopsis:  Return length N of vector / sequence / absequence S.
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
(vector-ref v k) --> v[k]
 | 
						|
(sequence-ref s k) --> s[k]
 | 
						|
(absequence-ref abs k) --> abs[k]
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
(absequence:behavior abs) --> sb
 | 
						|
 | 
						|
Synopsis:  Return sequence-behavior SB for the concrete sequence
 | 
						|
packaged in absequence ABS.
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
(vector-copy s0 [start end]) --> s1
 | 
						|
(sequence-copy s0 [start end]) --> s1
 | 
						|
(sequence-copy/maker maker s0 [start end]) -- s1
 | 
						|
 | 
						|
Synopsis:  Make new vector resp. sequence (with MAKER)
 | 
						|
S1 = < s0[start+i] : i in [0:end-start) >.
 | 
						|
[ MAKER intentionally not made third optional arg. ]
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
(vector-copy! s1 start1 s0 [start0 end0]) --> unspec
 | 
						|
(sequence-copy! s1 start1 s0 [start0 end0]) --> unspec
 | 
						|
 | 
						|
Synopsis:  Set s1[start1 + i] := s0[start0 + i] for 0 <= i < end0 - start0.
 | 
						|
Assignment is parallel -- if there's no hidden aliasing (s1[j] and s0[k]
 | 
						|
referring to the same location although j ~= k).
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
(subvector s0 start end) --> s1
 | 
						|
(subsequence s0 start end) --> s1
 | 
						|
 | 
						|
Synopsis:  s1 := (sequence-copy s0 start end)
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
Modification
 | 
						|
 | 
						|
(vector-set! s i x) --> unspec
 | 
						|
(sequence-set! s i x) --> unspec
 | 
						|
(absequence-set! s i x) --> unspec
 | 
						|
 | 
						|
Synopsis:  Set s[i] := x.
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
(vector-fill! s x [start end]) --> unspec
 | 
						|
(sequence-fill! s x [start end]]) --> unspec
 | 
						|
(absequence-fill! s x [start end]) --> unspec
 | 
						|
 | 
						|
Synopsis:  Set s[i] := x for all i in [start:end) etc.
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
(vector-tabulate! s start proc len) --> s
 | 
						|
(sequence-tabulate! s start proc len) --> s
 | 
						|
 | 
						|
Synopsis:  Set s[start+i] := (proc i) for all i in [0:len), return s.
 | 
						|
[ Destructive-update analogue to STRING-TABULATE, exceptionally with a
 | 
						|
  useful return value. ]
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
 | 
						|
Reverse & Append
 | 
						|
 | 
						|
(vector-append s0 ...) --> s
 | 
						|
(sequence-append s0 ...) --> s
 | 
						|
 | 
						|
Synoposis:  Make a new vector resp. sequence S = `s0 o ...'.  If there
 | 
						|
is no argument, make S a vector, otherwise type(S) = type(S0).  [ You
 | 
						|
can force the result type by choosing a suitable empty sequence S0.
 | 
						|
E.g. (sequence-append (vector) "sloty" '(5 5)) works.
 | 
						|
Of course, VECTOR-APPEND always produces vectors from vectors. ]
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
Fold, Unfold & Map
 | 
						|
 | 
						|
(vector-map f s [start end]) --> fs
 | 
						|
(vectors-map f s0 ...) --> fs
 | 
						|
(sequence-map f s [start end]) --> fs
 | 
						|
(sequence-map/maker maker f s [start end]) --> fs
 | 
						|
(sequences-map f s0 s1 ...) --> fs
 | 
						|
(sequences-map/maker maker f s0 s1 ...) --> fs
 | 
						|
 | 
						|
Synopsis:  Make new vector / sequence FS representing the sequence
 | 
						|
f(s[start]),...,f(s[end-1])  resp.
 | 
						|
(f(s0[i],...) : 0<=i<n)      with n = min.k sequence-length sk.
 | 
						|
Use the MAKER, if supplied, otherwise the maker of the first sequence
 | 
						|
arg's concrete type.  [ MAKER intentionally not made third optional
 | 
						|
arg. ]
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
(vector-map-into! s1 proc s0 [start1 end1 start0]) --> s1
 | 
						|
(sequence-map-into! s1 proc s0 [start1 end1 start0]) --> s1
 | 
						|
 | 
						|
Synopsis:  Set s1[start1 + i] := (proc s0[start0 + i])
 | 
						|
for 0 <= i < end1 - start1, return s1.
 | 
						|
Assignment is parallel -- if there's no hidden aliasing.
 | 
						|
 | 
						|
Attention:  differing from CL's MAP-INTO, these procs expect
 | 
						|
end1 - start1 <= s0.length - start0, i.e. the destination S1 drives the
 | 
						|
loop, as with MAP! in SRFI-1.  Differing from SEQUENCE-COPY!, two optionals
 | 
						|
relate to the destination S1 and one to the source S0 instead of one to the
 | 
						|
destination and two to the source.  (Why?  Because of the different loop
 | 
						|
termination criteria: dest length vs. src length.)
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
(vectors-map-into! s1 proc s00 ...) --> s1
 | 
						|
(sequences-map-into! s1 proc s00 ...) --> s1
 | 
						|
 | 
						|
Synopsis:  Set s1[i] := (proc s00[i] ...) for i in [0:s1.length), return s1.
 | 
						|
 | 
						|
Attention: differing from CL's MAP-INTO, these procs expect the sequences
 | 
						|
S00, ... to be no less long than the destination S1, like MAP! in SRFI-1.
 | 
						|
Doesn't cope with absequent aliasing problems.
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
(vector-for-each proc s [start end]) --> unspec
 | 
						|
(vectors-for-each f s0 s1 ...) --> unspec
 | 
						|
(sequence-for-each proc s [start end]) --> unspec
 | 
						|
(sequences-for-each proc s0 s1 ...) --> unspec
 | 
						|
 | 
						|
Synopsis:  Call (proc v[i]) for all i in [start:end) in some order, resp.
 | 
						|
call (proc v0[i] v1[i] ...) for all i in [0:n) in some order with
 | 
						|
n = min.k sequence-length sk.
 | 
						|
 | 
						|
                                *
 | 
						|
 | 
						|
(vector-fold kons nil s [start end]) --> sq
 | 
						|
(vectors-fold kons nil s0 s1 ...) --> sq
 | 
						|
(sequence-fold kons nil s0 [start end]) --> sq
 | 
						|
(sequences-fold kons nil s0 s1 ...) --> sq
 | 
						|
 | 
						|
Synopsis:  Let  y o x             := (kons x      y)  resp.
 | 
						|
                y o (x0, x1, ...) := (kons x0 ... y),
 | 
						|
 | 
						|
and let o be left-associative (so that we can spare us the brackets).
 | 
						|
Compute
 | 
						|
        sq = nil o s[start]          o ... o s[end-1],       resp.
 | 
						|
        sq = nil o (s0[0],s1[0],...) o ... o (s0[n-1],s1[n-1],...)
 | 
						|
with
 | 
						|
        n := min.k sequence-length sk.
 | 
						|
 | 
						|
                               *
 | 
						|
 | 
						|
(vector-fold-right kons nil s [start end]) --> sq
 | 
						|
(vectors-fold-right kons nil s0 s1 ...) --> sq
 | 
						|
(sequence-fold-right kons nil s [start end]) --> sq
 | 
						|
(sequences-fold-right kons nil s0 s1 ...) --> sq
 | 
						|
 | 
						|
Synopsis:  Let  x o y := (kons x      y)       resp.
 | 
						|
      (x0,x1,...) o y := (kons x0 ... y),
 | 
						|
 | 
						|
and let o be right-associative (so that we can spare us the brackets).
 | 
						|
Compute
 | 
						|
        sq = s[start]    o ... o s[end-1]      o nil,  resp.
 | 
						|
        sq = (s0[0] ...) o ... o (s0[n-1] ...) o nil
 | 
						|
with
 | 
						|
        n := min.k sequence-length sk.
 | 
						|
 | 
						|
                                 *
 | 
						|
 | 
						|
Examples:
 | 
						|
; Demo implementation of partial sequences
 | 
						|
; ,open sequence-lib srfi-9 krims
 | 
						|
 | 
						|
(define-record-type :shaseq
 | 
						|
  (make-shaseq-record sequence start end)
 | 
						|
  shaseq?
 | 
						|
  (sequence shaseq:sequence)
 | 
						|
  (start shaseq:start)
 | 
						|
  (end shaseq:end))
 | 
						|
 | 
						|
 | 
						|
(define (share-sequence s start end)
 | 
						|
  (assert (<= 0 start end (sequence-length s)))
 | 
						|
  (make-shaseq-record s start end))
 | 
						|
 | 
						|
 | 
						|
(define (displace-index shas k)
 | 
						|
  (let ((start (shaseq:start shas)))
 | 
						|
    (+ start k)))
 | 
						|
 | 
						|
 | 
						|
;; maker -- dummyish
 | 
						|
(define (make-shaseq len . maybe-fill)
 | 
						|
  (make-shaseq-record (apply make-vector len maybe-fill)
 | 
						|
                      0 len))
 | 
						|
;; getter
 | 
						|
(define (shaseq-ref shas k)
 | 
						|
  (sequence-ref (shaseq:sequence shas)
 | 
						|
                (displace-index shas k)))
 | 
						|
;; setter
 | 
						|
(define (shaseq-set! shas k x)
 | 
						|
  (sequence-set! (shaseq:sequence shas)
 | 
						|
                 (displace-index shas k)
 | 
						|
                 x))
 | 
						|
;; meter
 | 
						|
(define (shaseq-length shas)
 | 
						|
  (- (shaseq:end shas)
 | 
						|
     (shaseq:start shas)))
 | 
						|
 | 
						|
 | 
						|
(define shaseq-behavior
 | 
						|
  (make-sequence-behavior make-shaseq shaseq?
 | 
						|
                          shaseq-ref shaseq-set!
 | 
						|
                          shaseq-length))
 | 
						|
 | 
						|
(define a-string (string-copy "brachman foo gratz bladotzky"))
 | 
						|
(define an-abs (make-absequence-record shaseq-behavior
 | 
						|
                                       (share-sequence a-string 3 11)))
 | 
						|
 | 
						|
;; prints ``(c h m a n   f o)''
 | 
						|
(display (sequence-fold-right cons '() an-abs))
 | 
						|
 | 
						|
;; prints ``>>> chman fo <<<''
 | 
						|
(display (sequence-append ">>> " an-abs '#(#\ #\< #\< #\<)))
 | 
						|
 | 
						|
(sequence-fill! an-abs #\X 4)
 | 
						|
;; prints ``brachmaXXXXo gratz bladotzky''
 | 
						|
(display a-string)
 | 
						|
 | 
						|
; EOF
 | 
						|
                                 *
 | 
						|
 | 
						|
Sela (for now).
 | 
						|
 | 
						|
                                oOo
 |