chickadee » callable-sequences

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)

(callable-data (callable-map add1 vec))
;-> #(1 2 3 4 5 6)

(callable-data (callable-map add1 pls))
;-> (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))

(callable-data* (callable-map* add1 ns**))
;-> (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)

(set! mva* (callable-map* add1 va*))
;-> (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?)

Requirements

None

Last update

Jan 22, 2021

Author

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.

License

Copyright (c) 2020-2021 , 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.3
callable-collect added
1.2
some sequence operations added
1.1
make-callable* added, a recursive version of make-callable
1.0.0
initial version

Contents »