Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== record-vector [[toc:]] === Description '''Record-vector''' is a module for CHICKEN5|6 Scheme, and R7RS library for #:Guile :Gauche Gambit: Schemes, designed to work with key-value data structures, aka {{records}}. Record-vector does not declare a new record type, it is not a hash-table, nor a tree. Record-vector itself is just a pair of '''alist''' of attribute indexes in the second part of pair - value's '''vector'''. '(((#:KW1 . INDEX1) ... (#:KWN . INDEXN)) . #(VALUE1 ... VALUEN)) KW - name of attribute, also Scheme keyword #:NAME or NAME: depend of Scheme variant. VALUE - any Scheme value. Cons * Access to the record attribute barely dumb sequence of ''number? + car + assq + vector-ref'' * Record-vectors are not tagtyped but duck typed * It's not bit-compact * Nor cache frendly it is user frendly records. Pros * Transparent good old way of the Lisp data representation (sic!) * automatic serialization by ''read/write'' * easy handy creation * automatic data import (in memory of SRFI-9 import-export access proc.s hell) * Access to the attribute value by the #:keyword or by index * Access to the attribute of record-vector inside record-vector, recursive, by path of keywords or indexes. === Example. Basic usage <enscript highlight="scheme"> > (record-vector #:x 0.0 #:speed 0.1) => (((#:x . 0) (#:speed . 1)) . #(0.0 0.1)) ;; make-rv an alias of [procedure]record-vector > (define boat (make-rv #:posn (make-rv #:x 1.0 #:y 2.0) #:id 10001 #:passengers 4)) ;; record-vector-ref/rv-ref is accessor procedure/macro (last one supports inner rv chain access) > (rv-ref boat #:posn #:y) => 2.0 ;; same reference by attribute indexes > (rv-ref boat 0 1) => 2.0 ;; Zero - #:posn, 1 - #:y in position. ;; the record-vector extends in this way > (rv-attr? boat #:model) => #f > (rv-update! boat #:model "Azimut 50") > (rv-attr? boat #:model) => (#:model . 3) ;; get attribute by index > (rv-ref boat 3) => "Azimut 50" </enscript> === Example. Compound record-vector <enscript highlight="scheme"> (define objects (record-vector #:table (make-rv #:posn (make-rv #:x 100 #:y 20) #:height 80 #:items (make-rv #:cup (make-rv #:posn (make-rv #:x 10 #:y 0)) #:pot (make-rv #:posn (make-rv #:x 20 #:y 10)))))) > (cdr (rv-ref objects #:table #:items #:pot #:posn)) => #(20 10) </enscript> === Requirements Non standard predicate ''keyword?'' and utility (R7RS) procedure ''vector-append'' are used (in CHICKEN5 it's used from vector-lib package). Also in CHICKEN SRFI-17 ''setter'' adapter used for ''record-vector-ref''. === API All record-vector-* forms has rv-* shortcomings, some in form of macros with extended abilities. ==== record-vector <procedure>(record-vector [#:NAME-1 VALUE-1 ... #:NAME-N VALUE-N])</procedure> <procedure>(make-rv [#:NAME-1 VALUE-1 ... #:NAME-N VALUE-N])</procedure> Record-vector construction procedures. ''make-rv'' is an alias of ''record-vector'' * '''NAME-1''' - first attribute name - scheme keyword ''#:NAME'' (or ''NAME:'' in CHICKEN) * '''VALUE-1''' - first attribute value ''record-vector'' may be empty. <enscript highlight="scheme"> > (record-vector #:code "defs.scm" #:lang 'Scheme #:loc 117)) => (((#:code . 0) (#:lang . 1) (#:loc . 2)) . #("defs.scm" Scheme 117)) > (define empty-obj (make-rv)) > empty-obj => (() . #()) > (record-vector? empty-obj) => #t </enscript> ==== record-vector? <procedure>(record-vector? VAR)</procedure> Unstrict predicate which test structure of argument '''VAR''' is like Scheme pair of list and vector. ==== record-vector-clone <procedure>(record-vector-clone R-V-SRC [#:NAME-k #:NEW-VALUE-k ...])</procedure> <procedure>(rv-clone R-V-SRC [#:NAME-k #:NEW-VALUE-k ...])</procedure> Create the new record-vector by consing attributes alist of R-V-SRC and copy of R-V-SRC value vector. If every n-th value also ''record-vector?'' than recursive clone it inplace of new n-th value. Also apply new values to existing attributes with name '''#:NAME-k''' or extends new ''record-vector'' with them. <enscript highlight="scheme"> > (define r (record-vector #:x 1.0 #:y 3.0)) > (define r2 (record-vector-clone r #:y 2.0 #:z 3.0)) > r2 => (((#:x . 0) (#:y . 1) (#:z . 2)) . #(1.0 2.0 3.0)) </enscript> ==== record-vector-like? <procedure>(record-vector-like? r1 r2)</procedure> <procedure>(rv-like? r1 r2)</procedure> Procedure ''record-vector-like?'' returns true if all of attribute names in r1.alist also in r2.alist or vice versa. <enscript highlight="scheme"> > (define r1 (make-rv x: 1 y: 2 z: 3)) > (define r2 (make-rv x: 4 y: 2)) > (rv-like? r1 r2) => #t ;; bc all attributes from r2 are present in r1. > (rv-like? r2 r1) => #t ;; still True, record-vector-like? symmetrical </enscript> ==== record-vector-attr? <procedure>(record-vector-attr? R-V #:NAME)</procedure> <procedure>(rv-attr? R-V #:NAME)</procedure> This proc's for check presence of the attribute #:NAME in alist dictionary of '''R-V'''. Returns ''(assq #:NAME r-v.alist)''. ==== record-vector-ref <procedure>(record-vector-ref R-V #:NAME-k #!optional DEFAULT)</procedure> <macro>(rv-ref R-V #:NAME-k [#:SUB-NAME-j ...])</macro> This is accesor of the attribute of the record-vector '''R-V'''. In CHICKEN ''record-vector-ref'' (not the ''rv-ref'') SRFI-17 compatible. Optional '''DEFAULT''' value is used if there is no attribute named '''#:NAME-k'''. The '''rv-ref''' macro works like ''record-vector-ref'', but if the value with '''#:NAME-k''' is a ''record-vector?'', it looks for the value of the '''#:SUB-NAME-j''' attribute in it, recursively. The macro does not have a default return value, unlike ''record-vector-ref''. <enscript highlight="scheme"> > (record-vector-ref (record-vector #:x 124 #:y 0) #:x) => 124 > (record-vector-ref (make-rv #:x 1) #:t 1900) => 1900 > ;; but no default value in rv-ref macro > (rv-ref (make-rv #:x 1) #:t 1990) => Error: (cdr) bad argument type: #f > (rv-ref (make-rv #:person (make-rv #:name "Joe" #:age 50)) #:person #:name ) => "Joe" ;; if attribute is not present it returns False (use rv-attr? predicate before) > (rv-ref (make-rv #:posn (make-rv #:x 0.0 #:y 0.0)) #:posn #:z) => #f .... </enscript> ==== record-vector-set! <procedure>(record-vector-set! R-V #:NAME-k NEW-VALUE)</procedure> <macro>(rv-set! R-V #:NAME-k [#:SUB-R-V-NAME-j ...] NEW-VALUE)</macro> ''record-vector-set!'' is a mutator of the record-vector attribute '''NAME''' ''rv-set!'' - recursive macro which able set value not only '''R-V''' but attributes compatible with ''record-vector'' structure <enscript highlight="scheme"> > (define r (record-vector #:pos 0.0 #:line (make-rv #:color 'red #:a 1.0 #:b 2))) > r => (((#:pos . 0) (#:line . 1)) . #(0.0 (((#:color . 0) (#:a . 1) (#:b . 2)) . #(red 1.0 2)))) > (set! (record-vector-ref r #:pos) 1000.0) ;; SRFI-17 > r => (((#:pos . 0) (#:line . 1)) . #(1000.0 (((#:color . 0) (#:a . 1) (#:b . 2)) . #(red 1.0 2)))) > (rv-set! r #:line #:color 'blue) > r => (((#:pos . 0) (#:line . 1)) . #(1000.0 (((#:color . 0) (#:a . 1) (#:b . 2)) . #(blue 1.0 2)))) </enscript> ==== record-vector-update! <procedure>(record-vector-update! R-V #:NAME VALUE)</procedure> <macro>(rv-update! R-V #:NAME [#:SUB-NAME ...] VALUE)</macro> These procedure and macro (which recursive variant) for update existing attribute values and add new attribute in record-vector '''R-V'''. <enscript highlight="scheme"> > (define p (make-rv posn: (make-rv x: 1 y: 2))) > (rv-update! p posn: x: 10) > p => (((#:posn . 0)) . #((((#:x . 0) (#:y . 1)) . #(10 2)))) > (rv-update! p posn: z: 30) > p => (((#:posn . 0)) . #((((#:x . 0) (#:y . 1) (#:z . 2)) . #(10 2 30)))) ;; rv-update! is stable > (rv-update! p posn: z: 30) > p => (((#:posn . 0)) . #((((#:x . 0) (#:y . 1) (#:z . 2)) . #(10 2 30)))) </enscript> === Example <enscript highlight="scheme"> (import (rename (record-vector) (record-vector rv))) (let ((r (rv x: 1 y: 2)) (nr (rv x: 2 y: 3))) (define (distance p t) (let ((dx (- (rv-ref t #:x) (rv-ref p #:x))) (dy (- (rv-ref t #:y) (rv-ref p #:y)))) (sqrt (+ (* dx dx) (* dy dy))))) (= (distance r nr) (distance nr r))) </enscript> === Source code [[https://codeberg.org/Corbas/record-vector|record-vector at Codeberg]] === Authors [[e-mail-to:corbas.ai@gmail.com|Anton Idukov]] === Licence BSD-2-Clause licence. === Version History * 1.0.1 Fixed/simplified dependencies list in .egg * 1.0.0 Initial release
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 13 from 5?