1. Rationale
    1. API
      1. sequence-db
      2. sequence?
      3. seq-length
      4. seq-ref
      5. seq-tail
      6. seq-maker
      7. seq-nil
      8. seq-pseudo?
      9. sequence->list
      10. seq-reverse
      11. subseq
      12. seq-filter
      13. seq-memp
      14. seq-append
      15. seq-map
      16. seq-for-each
      17. seq-ref*
      18. seq-flat?
      19. seq-length*
      20. seq-map*
      21. simple-sequences
    2. Examples
  2. Requirements
  3. Last update
  4. Author
  5. License
  6. Version history

Rationale

This module allows to acces some sequence types, in particular lists, pairs, vectors and strings with a common interface. The number of sequence types handled can be enhanced. The egg is not as complete and sophisticated as Felix' sequences egg, but quite usable. In particular, it is sufficient for use in Paul Graham's dbind implementation, cf. On Lisp, p. 232, which is the workhorse of my bindings egg.

API

sequence-db

[procedure] (sequence-db)
[procedure] (sequence-db seq)
[procedure] (sequence-db seq? seq-length seq-ref seq-tail seq-maker . pos?)

database processing: the first resets the database to the standard with lists, pairs, vectors and strings, the second returns the vector of handlers as well as the discriminator, the third adds a new database record either at the end or before the pos? discriminator. A record cosists of a discriminator, seq?, and a vector with items seq-lenth, seq-ref, seq-tail and seq-maker patterned after vectors. Note, that the last record can handle atoms, albeit it is not a sequence.

sequence?

[procedure] (sequence? x)

type predicate.

seq-length

[procedure] (seq-length seq)

returns the length of a sequences

seq-ref

[procedure] (seq-ref seq k)

returns the item of seq at position k

seq-tail

[procedure] (seq-tail seq k)

reuturns the subsequence of seq starting at position k. Note that k might be equal to (seq-length seq), returning the sentinel of empty sequence

seq-maker

[procedure] (seq-maker seq)

returns the maker, like list or vector, to create new sequences of the same type as seq.

seq-nil

[procedure] (seq-nil seq)

returns the sentinel of pairs or empty sequences

seq-pseudo?

[procedure] (seq-pseudo? x)

checks, if the sequence is pseudo, i.e. a pair. This is needed to handle pairs like other sequences.

sequence->list

[procedure] (sequence->list seq)

type transformer

seq-reverse

[procedure] (seq-reverse seq)

returns a new sequence with items reversed

subseq

[procedure] (subseq seq i)
[procedure] (subseq seq i j)

creates a new sequence of the same type as seq consisting of seq's items from i included and j excluded

seq-filter

[procedure] (seq-filter ok? seq)

returns two subsequences of the same type as seq of items passed or not passed by the ok? test

seq-memp

[procedure] (seq-memp ok? seq)

returns a new sequence of seq's type of items from seq starting at the first item which passes the ok? test, or #f

seq-append

[procedure] (seq-append seq . seqs)

appends the items of all argument sequences, which must be of the same type as seq and in case of pairs, the same sentinel

seq-map

[procedure] (seq-map fn seq . seqs)

maps the argument sequences up to the shortest length. All sequences must be of the same type, and in case of pairs, must have the same sentinels

seq-for-each

[procedure] (seq-for-each proc seq . seqs)

applies proc to each item of seq and seqs up to the shortest length. The sequences might be of different type

seq-ref*

[procedure] (seq-ref* seq ind)

references the value of a nested sequence at appropriate index list: with index '(0) it returns (seq-ref seq 0), with index '(1 0) it returns (seq-ref (seq-ref seq 1) 0)

seq-flat?

[procedure] (seq-flat? seq)

is the sequence seq flat?

seq-length*

[procedure] (seq-length* seq)

counts the number of items in a nested sequence seq

seq-map*

[procedure] (seq-map* fn seq)

deep map: maps all items of a nested sequence seq with function fn

simple-sequences

[procedure] (simple-sequences)
[procedure] (simple-sequences sym)

with sym: documentation of exported symbol without sym: list of exported symbols

Examples


(import simple-sequences)

(sequence-db '())
;-> (vector length list-ref list-tail list)

(sequence-db #())
;-> (vector vector-length vector-ref subvector vector)

(sequence-db "")
;-> (vector string-length string-ref substring string)

(seq-length '())
;-> 0

(seq-length #())
;-> 0

(seq-length "")
;-> 0

(seq-length '(1 . 2))
;-> 1

(seq-length 1)
;-> 0

(seq-ref '(0 1 2 3) 1)
;-> 1

(seq-ref #(0 1 2 3) 1)
;-> 1

(seq-ref "0123" 1)
;-> 1

(seq-ref '(0 1 2 . 3) 1)
;-> 1

(seq-tail '(0 1 2 3 4) 1)
;-> (quote (1 2 3 4))

(seq-tail #(0 1 2 3 4) 1)
;-> #(1 2 3 4)

(seq-tail "01234" 1)
;-> 1234

(seq-tail '(0 1 2 3 . 4) 1)
;-> (quote (1 2 3 . 4))

(seq-tail '(0 1 2 3 . 4) 4)
;-> 4

(seq-tail 1 0)
;-> 1

(sequence? 1)
;-> #f

(length (sequence-db))
;-> 5

(list-ref
  (sequence-db
    number?
    (lambda (x) 0)
    (lambda (x i) (error))
    (lambda (x i) x)
    (lambda (x) x))
  4)
;-> number?

(car (sequence-db
       integer?
       (lambda (x) 0)
       (lambda (x i) (error))
       (lambda (x i) x)
       (lambda (x) x)
       list?))
;-> integer?

(length (sequence-db))
;-> 5

(condition-case (seq-ref 1 0) ((exn) "out of range"))
;-> out of range

(seq-tail 1 0)
;-> 1

(condition-case (seq-tail 1 1) ((exn) "out of range"))
;-> out of range

(sequence->list '(0 1 2 . 3))
;-> (quote (0 1 2))

(seq-maker str)
;-> string

(subseq str 1)
;-> 123

(subseq str 1 3)
;-> 12

(subseq pls 1 3)
;-> (quote (1 2 . 3))

(seq-nil str)
;-> 

(seq-nil pls)
;-> 3

(seq-pseudo? pls)
;-> #t

(seq-pseudo? lst)
;-> #f

(seq-reverse "abc")
;-> cba

(seq-reverse '(1 2 3 . 0))
;-> (quote (3 2 1 . 0))

(receive (odd even) (seq-filter odd? vec) (list odd even))
;-> (quote (#(1 3) #(0 2)))

(receive (odd even) (seq-filter odd? pls) (list odd even))
;-> (quote ((1 . 3) (0 2 . 3)))

(seq-memp odd? vec)
;-> #(1 2 3)

(seq-memp odd? pls)
;-> (quote (1 2 . 3))

(seq-memp (lambda (s) (char=? s #\2)) str)
;-> 23

(seq-append #(1 2 3) #(10 20 30))
;-> #(1 2 3 10 20 30)

(seq-append '(1 2 3 . 0) '(10 20 30 . 0))
;-> (quote (1 2 3 10 20 30 . 0))

(seq-append "a" "b" "c" "d" "e")
;-> abcde

(seq-map add1 #(0 1 2))
;-> #(1 2 3)

(seq-map add1 '(0 1 2 . 0))
;-> (quote (1 2 3 . 0))

(seq-map + #(1 2 3) #(10 20 30 40))
;-> #(11 22 33)

(seq-map + '(1 2 . 0) '(10 20 . 0))
;-> (quote (11 22 . 0))

(condition-case (seq-map + '(1 2 . 3) '(10 20 . 30)) ((exn) "different nils"))
;-> different nils

(seq-ref* '(1 #(2 3)) '(1 0))
;-> 2

(seq-ref* '(0 #(1 "23")) '(1 1 1))
;-> 3

(seq-ref* '(0 #(1 "23")) '(1 0))
;-> 1

(seq-ref* '(0 #(1 "23")) '(1 1))
;-> 23

(seq-flat? #(1 2 3))
;-> #t

(seq-flat? '(1 #(2 3)))
;-> #f

(seq-length* '((2 (3 #(4) 5) 1) 0))
;-> 6

(seq-length* '(1 #(2 "3")))
;-> 3

(seq-length* '(((((0))))))
;-> 1

(seq-map* add1 '(((2) 1) 0))
;-> (quote (((3) 2) 1))

(seq-map* add1 '(0 #(1 2)))
;-> (quote (1 #(2 3)))

(seq-map* add1 '(0 (1 2 . 3)))
;-> (quote (1 (2 3 . 3)))

(seq-map* add1 '(0 (1 (2 . 3))))
;-> (quote (1 (2 (3 . 3))))

(seq-map* add1 '(0 (1 (2 . 3) . 0)))
;-> (quote (1 (2 (3 . 3) . 0)))

Requirements

None

Last update

Nov 22, 2020

Author

Juergen Lorenz

License

Copyright (c) 2020 , Juergen Lorenz, ju (at) jugilo (dot) de All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Version history

1.0
Initial check in