2017-09-10

(sph record)

vectors as records

all vector procedures can be used and vectors have a read/write syntax

part of sph-lib

description

a record in this sense differs from an association list, for example, in that the keys are not stored inside the data-structure, but separately: a "layout" stores the field names and indices of field values

requiring to use a layout object might seem unnecessary, but most other record implementations share this trait because it follows from what the word "record" usually means in scheme

because field-names/keys are not stored or otherwise encoded with every record instance, they use less memory than alists

because accessor procedures do not need to make extra searches for the positions of the field-values like comparing the keys of alist pairs, or hashing in hashtables, field access can be faster and the performance is nearly the same as for vectors

the library does support getting/setting field values with symbol names instead of accessor/setter procedures, but this is slower than with hashtables

it is possible to define record-layouts procedurally with using the alternative bindings to "define-record"

upsides

access vector fields using symbolic names

low memory usage per record element

no special data type, records are standard vectors

downsides

in this implementation, the creation of record instances is a bit slower than vector creation

the complexity of having record-layouts, accessors, setters and having to pass the layout to some procedures

theoretical comparison

memory usage: vector = sph-record < hashtable

operations for creation: vector < sph-record < hashtable

operations for typical field access: vector < sph-record < hashtable

operations for integer index access: vector = sph-record

examples

define a record type

(define-record my-record a b c)
(define-record my-other-record (a my-a-accessor-name my-a-setter-name) b (c my-c-accessor-name))

create record instances

(define one-element (record my-record 1 2 3))
(define another-element (record my-record #f "b"))
(define a-third-element (record my-record))

access and modify instances

(my-record-b one-element)
(my-record-c-set! one-element 4)
(my-record-c-set! another-element "custom-value")

bindings

define-record

unquoted-symbol/(field-name [accessor-identifier setter-identifier])

with three fields named "a" "b" and "c"

(define-record my-record a b c)

this implicitly defines the procedures my-record-a, my-record-b, my-record-c to access record values for the corresponding fields for any record instance, and it also defines the procedures my-record-a-set!, my-record-b-set!, my-record-c-set! to set record values

different names for accessors and setters

(define-record my-record (a my-a-accessor-name my-a-setter-name) b (c my-c-accessor-name))

here "c" gets a custom accessor name but the default setter "my-record-c-set!", "a" gets a custom accessor and setter name, and "b" gets the default accessor and setter name

library description

the main goal this library tries to archieve is to offer a dictionary data-structure where field values can be accessed by field name, but where the access happens indexed as for vectors and not using a hash function for example.

records use less memory and have shorter access times.

this library is supposed to be simpler in definition and usage than existing record libraries (rnrs, srfi) and more flexible by being based on the less restricted interoperability with vectors (for records) and hashtables (for layouts).

any vector can be accessed as a record and records can be accessed as vectors.

if type information is desired then it has to be added manually by storing a type name in the first record field for example.

usage:

(define-record my-record a b c)

(define-record my-other-record (a accessor-name setter-name) b (c my-other-c))

(define x (record my-record 1 2))

(my-record-a x) -> 1

(my-record-c x) -> #f

(my-record-c-set! x 3)

syntax

  record-update-b :: record-layout a field-names ...

    create a new vector with field name and value taken from given identifier and variable value.

    example: (record-update layout instance name name-2)

    same as (record-update layout instance (q name) name (q name-2) name ...)

import name

(sph record)

exports

alist->record

procedure

signature

a record-layout ->

alist record-layout -> record

description

extract record data from alist using record-layout and result in one record.

currently, string keys are also recognized

define-record

syntax

define-record-accessors

syntax

signature

record-layout (identifier field-name) ...

define-record-setters

syntax

signature

record-layout (identifier field-name) ...

make-record

procedure

signature

record-layout ->

record-layout -> record

make-record-layout

procedure

signature

field-spec ->

(symbol ...) -> record-layout

description

results in a new record-layout with the given field names

record

procedure

signature

record-layout values ... ->

record-layout (any ...) -> record

description

create a new record by specifying the layout and the values in

the same order as they are specified in layout field-spec. not all values have to be given, unspecified fields are set to <unspecified>

record-accessor

procedure

signature

record-layout field-name ->

record-layout symbol -> procedure {record -> field-value}

description

returns an accessor procedure for the given record-layout and field-name.

record-accessors

procedure

signature

record-layout ->

hashtable:record-layout -> (proc ...)

description

returns all accessors for the given record-layout in a list

record-append

procedure

signature

a b ->

description

concatenate "b" at the end of "a".

#(1 2) #(3 4) -> #(1 2 3 4)

create a new bigger vector and copy all elements of "a" and "b" to it

record-field-names

procedure

signature

record-layout ->

hashtable:record-layout -> vector:#(symbol ...)

description

result in the field-names of record in the same order as they were specified.

record-field-names-unordered

procedure

signature

hashtable ->

record-layout->predicate

procedure

signature

a [type-prefix] ->

record-layout [symbol:type-name] -> procedure:{vector -> boolean}

description

if type-prefix is given, the first field of the record is required to contain the type-prefix

record-layout-extend!

procedure

signature

layout-1 layout-2 ->

record-layout-length

procedure

signature

hashtable ->

record-layout-merge!

procedure

signature

a b ... ->

hashtable hashtable ... -> unspecified

description

copy the values of hash b to hash a. existing key values are overwritten

record-layout?

procedure

signature

obj ->

record-length

procedure

signature

a ->

record-list-filter-value

procedure

signature

record-list value match-accessor retrieve-accessor ->

list procedure:accessor procedure:accessor -> false/(any ...)

description

filter record list entries by values retrieved by match-accessor that match the given value,

and return a list of values retrieved by retrieve-accessor

record-ref

procedure

signature

record record-layout field-name ->

record record-layout symbol -> any

description

get the value for field-name of the given record.

record-ref is considerably slower than using an accessor procedure

record-setter

procedure

signature

record-layout field-name ->

record-layout symbol -> procedure {record value -> unspecified}

description

returns a setter procedure for the given layout and field-name

record-setters

procedure

signature

record-layout ->

record-layout (symbol ...) -> proc ...

description

returns all setters for the given layout in a list

record-take

procedure

signature

record-layout a ->

description

this adjusts the length of the given vector to match the length of the layout.

extra fields in are left out if the layout is smaller

record-update

procedure

signature

record-layout a field-name/value ... ->

vector [integer any] ... -> vector

description

create a copy of the given record with values in fields set to new values.

field name and value are given alternatingly.

example: (record-update myrecord (quote a) #\c (quote b) #\d)

record-update-b

syntax

signature

record-layout a field-name ...

record-update-q

syntax

signature

record-layout a field-name/value ...

record?

procedure

signature

a ->

vector->record

procedure

signature

record-layout a ->

description

this adjusts the length of the given vector to match the length of the layout.

extra fields in are left out if the layout is smaller

other record implementations

these regard records as something more complicated

rnrs records has (rnrs records syntactic) and (rnrs records procedural)

srfi-9


tags: programming guile documentation library scheme sph-lib q1 record highlight sph-record