## Rationale

This is a variant of Mario's callable-datastructures. But contrary to that egg, I don't consider hash-tables, but only ordered sequences. So it makes sense, to define slices. Moreover, I'll consider nested sequences as well.

Central to this module is a generic procedure, sequence-constructors, which stores a local database initially supporting lists, pseudolists, vectors and strings. But this database can be enhanced, by adding generic constructors, make-sas-callable or make-ras-callable for sequential or random access sequences respectively, the former following the list pattern, the latter the vector pattern.

Based on this, the most important procedure is make-callable, which transforms an ordinary into a callable-sequence, i.e. a procedure of zero, one or two arguments. With no argument, this returns i.a. the encapsulated sequence, with one, an index, the value of that sequence at the index and with two a slice between its two index arguments, in either direction, the first included, the second excluded. For convenience, the argument #f is allowed in slices, representing the length.

So, for example, if vec is (make-callable #(0 1 2 3 4 5)), then (vec 1 4) or (vec 4 1) are callable-sequences encapsulating #(1 2 3) or #(4 3 2) respectively, and (vec 3 #f) or (vec #f 3) encapsulate #(3 4 5) or #(5 4) respectively.

### API

#### make-sas-callable

make-sas-callable seq seq-cons seq-car seq-cdr seq-null?procedure

sequential access constructor with arguments similar to lists

#### callable-sas?

callable-sas? xprprocedure

evaluates xpr to a sequential access callable-sequence?

#### make-ras-callable

make-ras-callable seq make-seq seq-ref seq-set! seq-lengthprocedure

random access constructor with arguments similar to vectors

#### callable-ras?

callable-ras? xprprocedure

evaluates xpr to a random access callable-sequence?

#### sequence?

sequence? xprprocedure

evaluates xpr to a sequence type, initially a list, pseudolist, vector or string. To be updated, if new sequence types are added.

#### sequence-constructors

sequence-constructorsprocedure
sequence-constructors seqprocedure
sequence-constructors symprocedure

the first resets the internal database and the sequence? predicate, the second selects and returns the constructor corresponding to the sequence argument, and the third adds a new sequential-access or random-access constructor, according to the symbol 'sas or 'ras. sequence? is updated as well.

#### make-callable

make-callable seqprocedure

makes the sequence seq callable

#### callable?

callable? xprprocedure

evaluates xpr to a callable sequence

#### callable-null?

callable-null? clbprocedure

is the callable-sequence clb empty?

#### callable-flat?

callable-flat? clbprocedure

is the callable sequence clb flat?

#### callable-length

callable-length clbprocedure

returns the length of the callable sequence clb

#### callable-nil

callable-nil clbprocedure

returns an empty callable sequence of the same type as clb

#### callable-data

callable-data clbprocedure

returns the encapsulated sequence of the flat callable-sequence clb

#### callable-indices

callable-indices ok? clbprocedure

returns the list of indices, k, for which (clb k) passes the ok? test

#### callable-copy

callable-copy clbprocedure

returns a callable sequence which is a copy of the initial one

#### callable-map

callable-map fn clbprocedure

maps the callable-sequence, clb, via procedure fn

#### callable-for-each

callable-for-each fn clbprocedure

executes fn for each item of clb

#### callable-filter

callable-filter ok? clbprocedure

returnstwo callable sequences filtering items of clb via ok? or not-ok? respectively

#### callable-reverse

callable-reverse clbprocedure
callable-reverse clb clb1procedure

returns a callable sequence which is the reverse of the first argument appended to the second one which defaults to callable-nil, if not given

#### callable-append

callable-append clb #!rest clbsprocedure

returns the callable sequence appending encapsulated sequences of same type

#### callable-collect

(callable-collect item-xpr (var clb ok-xpr ...))syntax
(callable-collect item-xpr (var clb ok-xpr ...) (var1 clb1 ok-xpr1 ...) ...)syntax

creates a new callable-sequence by binding var to each element of the callable-sequence clb in sequence, and if it passes the checks, ok-xpr ..., inserts the value of xpr into the resulting pseudolist. The qualifieres, (var clb ok-xpr ...), are processed sequentially from left to right, so that filters of a qualifier have access to the variables of qualifiers to its left.

#### callable-data*

callable-data* clbprocedure

nested version of callable-data

#### callable-map*

callable-map* fn clbprocedure

nested version of callable-map, i.e. maps a nested callable-sequence

#### make-callable*

make-callable* seqprocedure

nested version of make-callable, i.e. creates a nested callable-sequence from a nested ordinary sequence

#### callable-sequences

callable-sequencesprocedure
callable-sequences symprocedure

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

### Examples

```(import callable-sequences)

(callable-length pls)
;-> 6

(callable-length lst)
;-> 6

(callable-length str)
;-> 6

(callable-length vec)
;-> 6

(callable-null? str)
;-> #f

(callable-flat? vec)
;-> #t

(lst 0)
;-> 0

(lst 3)
;-> 3

(vec 3)
;-> 3

(str 3)
;-> 3

(lst 5)
;-> 5

(condition-case (lst (callable-length lst)) ((exn) #f))
;-> #f

(condition-case (vec (callable-length vec)) ((exn) #f))
;-> #f

(condition-case (str (callable-length str)) ((exn) #f))
;-> #f

(callable-data (lst 2 4))
;-> (quote (2 3))

(callable-data (lst 0 3))
;-> (quote (0 1 2))

(callable-length (lst 0 3))
;-> 3

(callable-data (pls 0 3))
;-> (quote (0 1 2 . 6))

((pls 0 0))
;-> 6

(callable-data (pls 0 0))
;-> 6

(callable-null? (pls 3 3))
;-> #t

(callable-null? (vec 1 2))
;-> #f

(callable-data (pls 3 0))
;-> (quote (3 2 1 . 6))

(callable-data (vec 0 3))
;-> #(0 1 2)

(callable-data (str 0 3))
;-> 012

(callable-data (lst 3 0))
;-> (quote (3 2 1))

(callable-data (vec 3 0))
;-> #(3 2 1)

(callable-data (str 3 0))
;-> 321

(callable-data (pls 0 #f))
;-> (quote (0 1 2 3 4 5 . 6))

(callable-data (pls 0 (callable-length pls)))
;-> (quote (0 1 2 3 4 5 . 6))

(callable-data (lst 0 6))
;-> (quote (0 1 2 3 4 5))

(callable-data (vec 0 #f))
;-> #(0 1 2 3 4 5)

(callable-data (str 0 #f))
;-> 012345

(condition-case (lst 0 7) ((exn) #f))
;-> #f

(condition-case (vec 0 7) ((exn) #f))
;-> #f

(condition-case (str 0 7) ((exn) #f))
;-> #f

(callable-data (lst 0 #f))
;-> (quote (0 1 2 3 4 5))

(callable-data (vec 0 #f))
;-> #(0 1 2 3 4 5)

(callable-data (str 0 #f))
;-> 012345

(callable-data (lst #f -1))
;-> (quote (5 4 3 2 1 0))

(callable-data (lst (- (callable-length lst) 1) -1))
;-> (quote (5 4 3 2 1 0))

(callable-data (callable-reverse lst))
;-> (quote (5 4 3 2 1 0))

(callable-data (vec #f -1))
;-> #(5 4 3 2 1 0)

(callable-data (vec (- (callable-length vec) 1) -1))
;-> #(5 4 3 2 1 0)

(callable-data (vec #f -1))
;-> #(5 4 3 2 1 0)

(callable-data (str #f -1))
;-> 543210

(callable-data (str (- (callable-length str) 1) -1))
;-> 543210

(callable-data (lst 3 1))
;-> (quote (3 2))

(callable-data (vec 3 1))
;-> #(3 2)

(callable-data (str 3 1))
;-> 32

(callable? str)
;-> #t

(callable-sas? lst)
;-> #t

(callable-ras? lst)
;-> #f

(callable? lst)
;-> #t

(callable? vec)
;-> #t

(callable? (lst 1 4))
;-> #t

(callable? (vec 1 4))
;-> #t

(callable-ras? (str 1 4))
;-> #t

(callable-sas? (str 1 4))
;-> #f

(callable? (str 1 4))
;-> #t

(callable? car)
;-> #f

(callable? '(0 1 2 3))
;-> #f

(callable? #(0 1 2 3))
;-> #f

(sequence? #(0 1 2 3))
;-> #t

(callable? "0123")
;-> #f

(sequence? "0123")
;-> #t

(sequence? #f)
;-> #f

(callable? pls)
;-> #t

(callable? '())
;-> #f

(callable-null? vec)
;-> #f

(callable-null? (callable-nil vec))
;-> #t

(callable-flat? vec)
;-> #t

(callable-data (callable-nil vec))
;-> #()

(callable-nil pls)
;-> 6

(callable-data (callable-reverse lst lst))
;-> (quote (5 4 3 2 1 0 0 1 2 3 4 5))

(callable-data (callable-reverse str str))
;-> 543210012345

(callable-data (callable-reverse str))
;-> 543210

(callable-indices even? vec)
;-> (quote (0 2 4))

(callable-indices odd? pls)
;-> (quote (1 3 5))

(callable-data (callable-copy lst))
;-> (quote (0 1 2 3 4 5))

(callable-data (callable-copy vec))
;-> #(0 1 2 3 4 5)

;-> #(1 2 3 4 5 6)

;-> (quote (1 2 3 4 5 6 . 6))

(callable-for-each print vec)
;-> (if #f #f)

(callable-data (callable-filter odd? vec))
;-> #(1 3 5)

(receive (yes no) (callable-filter odd? vec) (list (yes) (no)))
;-> (quote (#(1 3 5) #(0 2 4)))

(callable-data (callable-append str str str))
;-> 012345012345012345

(callable-data (callable-append str str str str))
;-> 012345012345012345012345

(callable-data* pl*)
;-> (quote (a (b . c)))

(callable-data* lv**)
;-> (quote (a (b #(c d) e) f))

(callable-data* ns**)
;-> (quote (0 (1 #(2) 3) 4))

;-> (quote (1 (2 #(3) 4) 5))

(ls* 0)
;-> (quote a)

((ls* 1) 1)
;-> (quote c)

(callable-data ((ls* 1) 2 #f))
;-> (quote ())

(callable? ((ls* 1) 1 2))
;-> #t

(callable-data ((ls* 1) 1 2))
;-> (quote (c))

(callable? pl*)
;-> #t

(callable-data (pl* 1))
;-> (quote (b . c))

(callable? (pl* 1))
;-> #t

((pl* 1) 0)
;-> (quote b)

(callable? ((pl* 1) 1 #f))
;-> #t

(((pl* 1) 1 #f))
;-> (quote c)

(callable-data ((pl* 1) 1 #f))
;-> (quote c)

((lv* 1) 1)
;-> (quote c)

(callable-data ((lv* 1) 1 2))
;-> #(c)

((vp* 1) 0)
;-> (quote b)

(callable? (vp* 1))
;-> #t

(callable? ((vp* 1) 1 #f))
;-> #t

(((vp* 1) 1 #f))
;-> (quote c)

(callable-data ((vp* 1) 1 #f))
;-> (quote c)

((vs* 1) 0)
;-> b

((vs* 1) 1)
;-> c

(callable-data ((vs* 1) 2 #f))
;->

(lv** 0)
;-> (quote a)

((lv** 1) 0)
;-> (quote b)

(((lv** 1) 1) 0)
;-> (quote c)

(((lv** 1) 1) 1)
;-> (quote d)

(lv** 2)
;-> (quote f)

((lv** 1) 2)
;-> (quote e)

((sequence-constructors 'ras)
array?
(lambda (k)
(apply array
(let loop ((i 0) (result '()))
(if (= i k) result (loop (+ i 1) (cons #f result))))))
(lambda (arr k) (array-at k arr))
(lambda (arr k new) (array-update! k new arr))
array-length)
;-> (if #f #f)

(sequence? (make-array))
;-> #t

(set! arr (make-callable (array 0 1 2 3)))
;-> (if #f #f)

(arr 2)
;-> 2

(array-equal? (callable-data (arr 1 3)) (array 1 2))
;-> #t

(array-equal? (callable-data (arr 3 #f)) (array 3))
;-> #t

(array-equal? (callable-data (arr 3 1)) (array 3 2))
;-> #t

(set! va* (make-callable* (vector 0 (array 1 2 3))))
;-> (if #f #f)

;-> (if #f #f)

(mva* 0)
;-> 1

((mva* 1) 0)
;-> 2

(array-equal? (callable-data (mva* 1)) (array 2 3 4))
;-> #t

(sequence-constructors)
;-> (if #f #f)

(sequence? (make-array))
;-> #f

(newline)

(newline)

((callable-collect (add1 x) (x (make-callable '(0 1 2 3)))))
;-> (quote (1 2 3 4))

((callable-collect (add1 x) (x (make-callable '(0 1 2 3)))))
;-> (quote (1 2 3 4))

((callable-collect x (x (make-callable '(0 1 2 3 4 5)) (odd? x))))
;-> (quote (1 3 5))

((callable-collect x (x (make-callable '(0 1 2 3 4 5)) (odd? x))))
;-> (quote (1 3 5))

((callable-collect
(* 10 n)
(n (make-callable '(0 1 2 3 4 5)) (positive? n) (even? n))))
;-> (quote (20 40))

((callable-collect
(list c k)
(c (make-callable '(A B C)))
(k (make-callable '(1 2 3 4)))))
;-> (quote ((A 1) (A 2) (A 3) (A 4) (B 1) (B 2) (B 3) (B 4) (C 1) (C 2) (C 3) (C 4)))

(collect?)
```

None

Jan 22, 2021

Juergen Lorenz

## Repository

This egg is hosted on the CHICKEN Subversion repository:

https://anonymous@code.call-cc.org/svn/chicken-eggs/release/5/callable-sequences

If you want to check out the source code repository of this egg and you are not familiar with Subversion, see this page.

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.

1.3